nudge-ui 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/bin/nudge-ui.mjs +3 -1
  2. package/dist/cli/agentCommand.d.ts +8 -0
  3. package/dist/cli/agentCommand.js +59 -0
  4. package/dist/client.mjs +872 -12
  5. package/dist/hosts/astro/astroRuntimeConfig.js +1 -1
  6. package/dist/hosts/astro/clientTransport.js +60 -11
  7. package/dist/hosts/next/sidecar.d.ts +4 -0
  8. package/dist/hosts/next/sidecar.js +49 -6
  9. package/dist/hosts/next/wrapper.js +30 -2
  10. package/dist/hosts/projectBridge.d.ts +20 -0
  11. package/dist/hosts/projectBridge.js +97 -0
  12. package/dist/hosts/static/cli.d.ts +1 -1
  13. package/dist/hosts/static/cli.js +6 -1
  14. package/dist/hosts/static/manifest.d.ts +1 -1
  15. package/dist/hosts/static/manifest.js +1 -1
  16. package/dist/hosts/static/server.js +44 -3
  17. package/dist/hosts/vite/vite.d.ts +5 -1
  18. package/dist/hosts/vite/vite.js +78 -14
  19. package/dist/inspector/agent/McpConnectionDialog.d.ts +2 -2
  20. package/dist/inspector/agent/McpConnectionDialog.js +11 -35
  21. package/dist/inspector/agent/client.d.ts +10 -3
  22. package/dist/inspector/agent/client.js +80 -9
  23. package/dist/inspector/agent/connectionStatus.js +3 -3
  24. package/dist/inspector/agent/httpTransport.d.ts +2 -0
  25. package/dist/inspector/agent/httpTransport.js +37 -17
  26. package/dist/inspector/agent/protocol.d.ts +8 -3
  27. package/dist/inspector/agent/protocol.js +1 -1
  28. package/dist/inspector/agent/verification.d.ts +1 -1
  29. package/dist/inspector/agent/verification.js +69 -12
  30. package/dist/inspector/canvas/CanvasCard.d.ts +5 -3
  31. package/dist/inspector/canvas/CanvasCard.js +181 -91
  32. package/dist/inspector/canvas/CanvasElementOverlay.js +246 -52
  33. package/dist/inspector/canvas/CanvasToolbar.d.ts +12 -0
  34. package/dist/inspector/canvas/CanvasToolbar.js +24 -0
  35. package/dist/inspector/canvas/CanvasWorkspace.d.ts +4 -1
  36. package/dist/inspector/canvas/CanvasWorkspace.js +392 -73
  37. package/dist/inspector/canvas/activeCanvasDocument.d.ts +5 -0
  38. package/dist/inspector/canvas/activeCanvasDocument.js +23 -0
  39. package/dist/inspector/canvas/canvasResize.d.ts +30 -0
  40. package/dist/inspector/canvas/canvasResize.js +52 -0
  41. package/dist/inspector/canvas/canvasStore.d.ts +30 -6
  42. package/dist/inspector/canvas/canvasStore.js +128 -61
  43. package/dist/inspector/canvas/frameProtocol.d.ts +69 -5
  44. package/dist/inspector/canvas/frameProtocol.js +56 -2
  45. package/dist/inspector/canvas/keyboardShortcuts.d.ts +3 -0
  46. package/dist/inspector/canvas/keyboardShortcuts.js +14 -0
  47. package/dist/inspector/canvas/projection.d.ts +7 -0
  48. package/dist/inspector/canvas/projection.js +118 -25
  49. package/dist/inspector/canvas/rendererBootstrap.js +29 -29
  50. package/dist/inspector/canvas/rendererElementSelector.js +341 -30
  51. package/dist/inspector/canvas/rendererMessageRouter.d.ts +11 -0
  52. package/dist/inspector/canvas/rendererMessageRouter.js +43 -0
  53. package/dist/inspector/canvas/rendererSelectionProxy.js +6 -2
  54. package/dist/inspector/canvas/sessionStore.d.ts +1 -0
  55. package/dist/inspector/canvas/sessionStore.js +12 -4
  56. package/dist/inspector/canvas/staleChangeDetector.js +16 -14
  57. package/dist/inspector/changes/changesLog.js +31 -1
  58. package/dist/inspector/changes/managedStyleProjection.d.ts +1 -1
  59. package/dist/inspector/changes/managedStyleProjection.js +3 -3
  60. package/dist/inspector/changes/structuralTypes.d.ts +4 -0
  61. package/dist/inspector/clientManifest.d.ts +5 -0
  62. package/dist/inspector/clientManifest.js +11 -0
  63. package/dist/inspector/componentSemantics/adapterRegistry.js +4 -3
  64. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +2 -2
  65. package/dist/inspector/componentSemantics/runtimeBridge.js +16 -3
  66. package/dist/inspector/index.d.ts +2 -0
  67. package/dist/inspector/index.js +74 -24
  68. package/dist/inspector/inline-text/inlineTextDiagnostics.d.ts +10 -0
  69. package/dist/inspector/inline-text/inlineTextDiagnostics.js +65 -0
  70. package/dist/inspector/inline-text/inlineTextEditor.d.ts +3 -5
  71. package/dist/inspector/inline-text/inlineTextEditor.js +74 -206
  72. package/dist/inspector/inline-text/inlineTextFeedback.d.ts +5 -0
  73. package/dist/inspector/inline-text/inlineTextFeedback.js +27 -0
  74. package/dist/inspector/inline-text/inlineTextLifecycle.js +2 -0
  75. package/dist/inspector/inline-text/textEditChange.d.ts +14 -0
  76. package/dist/inspector/inline-text/textEditChange.js +165 -0
  77. package/dist/inspector/inspection/selectionProperty.d.ts +1 -0
  78. package/dist/inspector/inspection/selectionProperty.js +1 -0
  79. package/dist/inspector/overlay/selectedGeometry.js +21 -2
  80. package/dist/inspector/overlay/spacingGestures.d.ts +45 -0
  81. package/dist/inspector/overlay/spacingGestures.js +353 -0
  82. package/dist/inspector/overlay/structuralGestures.d.ts +2 -2
  83. package/dist/inspector/overlay/structuralGestures.js +12 -10
  84. package/dist/inspector/projection/managedStylesheet.js +4 -1
  85. package/dist/inspector/projection/renderedInstance.d.ts +2 -0
  86. package/dist/inspector/projection/renderedInstance.js +5 -1
  87. package/dist/inspector/projection/structuralProjection.d.ts +2 -0
  88. package/dist/inspector/projection/structuralProjection.js +85 -1
  89. package/dist/inspector/projection/structuralProjectionBoundary.js +17 -1
  90. package/dist/inspector/projection/textProjection.d.ts +2 -0
  91. package/dist/inspector/projection/textProjection.js +10 -4
  92. package/dist/inspector/prompt/clipboardHandoff.d.ts +1 -1
  93. package/dist/inspector/prompt/clipboardHandoff.js +3 -3
  94. package/dist/inspector/prompt/generatePrompt.d.ts +2 -1
  95. package/dist/inspector/prompt/generatePrompt.js +19 -2
  96. package/dist/inspector/runtime/editorShell.d.ts +2 -0
  97. package/dist/inspector/runtime/editorShell.js +4 -0
  98. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  99. package/dist/inspector/runtime/runtimeConfig.js +4 -0
  100. package/dist/inspector/selection/selectionStore.js +2 -0
  101. package/dist/inspector/settings/SettingsDialog.js +10 -0
  102. package/dist/inspector/shell/AppShell.js +5 -1
  103. package/dist/inspector/shell/ChangesLog.js +8 -4
  104. package/dist/inspector/shell/CopyPromptButton.js +95 -19
  105. package/dist/inspector/shell/EmptyState.js +1 -1
  106. package/dist/inspector/shell/InspectorShell.d.ts +0 -1
  107. package/dist/inspector/shell/InspectorShell.js +37 -38
  108. package/dist/inspector/shell/PeekOriginalButton.d.ts +7 -0
  109. package/dist/inspector/shell/PeekOriginalButton.js +57 -0
  110. package/dist/inspector/shell/PeekOriginalIcon.d.ts +7 -0
  111. package/dist/inspector/shell/PeekOriginalIcon.js +9 -0
  112. package/dist/inspector/shell/originalPreview.d.ts +9 -0
  113. package/dist/inspector/shell/originalPreview.js +61 -0
  114. package/dist/inspector/shell/shortcuts.d.ts +3 -0
  115. package/dist/inspector/shell/shortcuts.js +15 -0
  116. package/dist/inspector/sketch/SketchChanges.d.ts +2 -0
  117. package/dist/inspector/sketch/SketchChanges.js +72 -0
  118. package/dist/inspector/sketch/SketchEditor.d.ts +21 -0
  119. package/dist/inspector/sketch/SketchEditor.js +402 -0
  120. package/dist/inspector/sketch/SketchEntryButton.d.ts +4 -0
  121. package/dist/inspector/sketch/SketchEntryButton.js +11 -0
  122. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +11 -0
  123. package/dist/inspector/sketch/SketchFrameOverlay.js +119 -0
  124. package/dist/inspector/sketch/SketchLayersPanel.d.ts +2 -0
  125. package/dist/inspector/sketch/SketchLayersPanel.js +63 -0
  126. package/dist/inspector/sketch/SketchOverlay.d.ts +19 -0
  127. package/dist/inspector/sketch/SketchOverlay.js +420 -0
  128. package/dist/inspector/sketch/SketchPromptPanel.d.ts +15 -0
  129. package/dist/inspector/sketch/SketchPromptPanel.js +18 -0
  130. package/dist/inspector/sketch/SketchWorkspace.d.ts +13 -0
  131. package/dist/inspector/sketch/SketchWorkspace.js +152 -0
  132. package/dist/inspector/sketch/capture.d.ts +55 -0
  133. package/dist/inspector/sketch/capture.js +350 -0
  134. package/dist/inspector/sketch/freehand.d.ts +13 -0
  135. package/dist/inspector/sketch/freehand.js +64 -0
  136. package/dist/inspector/sketch/geometry.d.ts +17 -0
  137. package/dist/inspector/sketch/geometry.js +98 -0
  138. package/dist/inspector/sketch/handoff.d.ts +21 -0
  139. package/dist/inspector/sketch/handoff.js +72 -0
  140. package/dist/inspector/sketch/interaction.d.ts +21 -0
  141. package/dist/inspector/sketch/interaction.js +98 -0
  142. package/dist/inspector/sketch/model.d.ts +104 -0
  143. package/dist/inspector/sketch/model.js +282 -0
  144. package/dist/inspector/sketch/persistence.d.ts +21 -0
  145. package/dist/inspector/sketch/persistence.js +205 -0
  146. package/dist/inspector/sketch/raster.d.ts +22 -0
  147. package/dist/inspector/sketch/raster.js +203 -0
  148. package/dist/inspector/sketch/sketchNote.d.ts +10 -0
  149. package/dist/inspector/sketch/sketchNote.js +30 -0
  150. package/dist/inspector/sketch/store.d.ts +47 -0
  151. package/dist/inspector/sketch/store.js +409 -0
  152. package/dist/inspector/styleEditors/BorderEditor.js +15 -19
  153. package/dist/inspector/styleEditors/BorderRadiusEditor.js +6 -6
  154. package/dist/inspector/styleEditors/BoxShadowEditor.js +12 -1
  155. package/dist/inspector/styleEditors/ColorPicker.js +11 -36
  156. package/dist/inspector/styleEditors/GapField.d.ts +3 -2
  157. package/dist/inspector/styleEditors/GapField.js +2 -2
  158. package/dist/inspector/styleEditors/GridSection.js +1 -1
  159. package/dist/inspector/styleEditors/LayoutSection.js +11 -8
  160. package/dist/inspector/styleEditors/SpacingBox.js +23 -30
  161. package/dist/inspector/styleEditors/layoutPreviewState.d.ts +5 -0
  162. package/dist/inspector/styleEditors/layoutPreviewState.js +19 -0
  163. package/dist/inspector/styleEditors/layoutValue.js +3 -0
  164. package/dist/inspector/styleEditors/nudgeValue.d.ts +11 -0
  165. package/dist/inspector/styleEditors/nudgeValue.js +91 -5
  166. package/dist/inspector/styleEditors/stylePresence.d.ts +7 -0
  167. package/dist/inspector/styleEditors/stylePresence.js +22 -0
  168. package/dist/inspector/styleEditors/textRelevance.d.ts +3 -0
  169. package/dist/inspector/styleEditors/textRelevance.js +35 -0
  170. package/dist/inspector/styleEditors/useFieldVisibility.d.ts +6 -0
  171. package/dist/inspector/styleEditors/useFieldVisibility.js +26 -0
  172. package/dist/inspector/tokens/TokenField.js +111 -7
  173. package/dist/inspector/tokens/editActions.d.ts +2 -0
  174. package/dist/inspector/tokens/editActions.js +2 -2
  175. package/dist/inspector/tokens/resolution/cssomCollector.d.ts +1 -1
  176. package/dist/inspector/tokens/resolution/cssomCollector.js +9 -5
  177. package/dist/inspector/tokens/resolution/ruleMatching.d.ts +40 -0
  178. package/dist/inspector/tokens/resolution/ruleMatching.js +423 -0
  179. package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +19 -3
  180. package/dist/inspector/tokens/resolution/selectorSemantics.js +378 -4
  181. package/dist/inspector/tokens/resolution.d.ts +3 -26
  182. package/dist/inspector/tokens/resolution.js +44 -735
  183. package/dist/inspector/tokens/tokenAvailability.d.ts +18 -0
  184. package/dist/inspector/tokens/tokenAvailability.js +204 -0
  185. package/dist/inspector/ui/Button.d.ts +1 -1
  186. package/dist/inspector/ui/SideValuesField.js +2 -2
  187. package/dist/inspector/ui/StatusCallout.d.ts +4 -1
  188. package/dist/inspector/ui/StatusCallout.js +2 -2
  189. package/dist/inspector/ui/styles.js +13 -11
  190. package/dist/internal/agent-protocol.d.ts +65 -1
  191. package/dist/internal/agent-protocol.js +183 -3
  192. package/dist/nudge-ui.mjs +261 -57
  193. package/dist/transport/editor.d.ts +28 -0
  194. package/dist/transport/editor.js +132 -0
  195. package/dist/transport/index.d.ts +1 -0
  196. package/dist/transport/index.js +1 -0
  197. package/dist/transport/routes.d.ts +7 -0
  198. package/dist/transport/routes.js +7 -0
  199. package/package.json +3 -1
  200. package/dist/inspector/shell/panelLayout.d.ts +0 -2
  201. package/dist/inspector/shell/panelLayout.js +0 -29
@@ -17,7 +17,7 @@ function extractParenContent(source, openIndex) {
17
17
  }
18
18
  return { content: source.slice(start, index - 1).trim(), end: index };
19
19
  }
20
- function splitSelectorAtTopLevel(selector, separator) {
20
+ export function splitSelectorAtTopLevel(selector, separator) {
21
21
  const parts = [];
22
22
  let depth = 0;
23
23
  let start = 0;
@@ -44,11 +44,11 @@ function splitSelectorAtTopLevel(selector, separator) {
44
44
  const SPECIFICITY_MEMO_LIMIT = 10_000;
45
45
  const specificityMemo = new Map();
46
46
  let specificityComputations = 0;
47
- /** Number of unique selector strings actually computed (for tests). */
47
+ /** Test-only specificity cache size. */
48
48
  export function specificityComputationCount() {
49
49
  return specificityComputations;
50
50
  }
51
- /** Clears the specificity memo (for tests). */
51
+ /** Test-only specificity cache reset. */
52
52
  export function resetSpecificityMemo() {
53
53
  specificityMemo.clear();
54
54
  specificityComputations = 0;
@@ -69,7 +69,7 @@ export function computeSpecificity(selectorText) {
69
69
  specificityMemo.set(selectorText, result);
70
70
  return result;
71
71
  }
72
- /** The unmemoized implementation, exposed for equivalence tests. */
72
+ /** Unmemoized implementation used by equivalence tests. */
73
73
  export function computeSpecificityCore(selectorText) {
74
74
  const selector = selectorText.trim();
75
75
  const commaParts = splitSelectorAtTopLevel(selector, ",");
@@ -104,3 +104,377 @@ export function computeSpecificityCore(selectorText) {
104
104
  }
105
105
  return idCount * 1000000 + classCount * 10000 + elementCount * 100;
106
106
  }
107
+ const SELECTOR_PSEUDO_CLASS_CACHE_MAX = 16_384;
108
+ const selectorPseudoClassMemo = new Map();
109
+ export function selectorPseudoClasses(selector) {
110
+ const cached = selectorPseudoClassMemo.get(selector);
111
+ if (cached)
112
+ return cached;
113
+ const matches = [];
114
+ let attributeDepth = 0;
115
+ let quote = null;
116
+ let escaped = false;
117
+ for (let index = 0; index < selector.length; index++) {
118
+ const character = selector[index];
119
+ if (quote) {
120
+ if (escaped)
121
+ escaped = false;
122
+ else if (character === "\\")
123
+ escaped = true;
124
+ else if (character === quote)
125
+ quote = null;
126
+ continue;
127
+ }
128
+ if (attributeDepth > 0) {
129
+ if (character === '"' || character === "'")
130
+ quote = character;
131
+ else if (character === "[")
132
+ attributeDepth++;
133
+ else if (character === "]")
134
+ attributeDepth--;
135
+ continue;
136
+ }
137
+ if (escaped) {
138
+ escaped = false;
139
+ continue;
140
+ }
141
+ if (character === "\\") {
142
+ escaped = true;
143
+ continue;
144
+ }
145
+ if (character === "[") {
146
+ attributeDepth = 1;
147
+ continue;
148
+ }
149
+ if (character !== ":" || selector[index - 1] === ":" || selector[index + 1] === ":")
150
+ continue;
151
+ const name = /^[A-Za-z-]+/.exec(selector.slice(index + 1))?.[0];
152
+ if (!name)
153
+ continue;
154
+ matches.push({ name: name.toLowerCase(), start: index, end: index + name.length + 1 });
155
+ index += name.length;
156
+ }
157
+ if (selectorPseudoClassMemo.size >= SELECTOR_PSEUDO_CLASS_CACHE_MAX)
158
+ selectorPseudoClassMemo.clear();
159
+ selectorPseudoClassMemo.set(selector, matches);
160
+ return matches;
161
+ }
162
+ export function hasSelectorPseudoClass(selector, names) {
163
+ return selectorPseudoClasses(selector).some(({ name }) => names.has(name));
164
+ }
165
+ const STATIC_SELECTOR_FUNCTIONS = new Set(["is", "where", "not"]);
166
+ const STATIC_PSEUDO_CLASSES = new Set(["host", "root"]);
167
+ const SELECTOR_SENSITIVITY_CACHE_MAX = 16_384;
168
+ const selectorSensitivityMemo = new Map();
169
+ function selectorFunctionEnd(selector, openingIndex) {
170
+ let parentheses = 0;
171
+ let brackets = 0;
172
+ let quote = null;
173
+ let escaped = false;
174
+ for (let index = openingIndex; index < selector.length; index++) {
175
+ const character = selector[index];
176
+ if (quote) {
177
+ if (escaped)
178
+ escaped = false;
179
+ else if (character === "\\")
180
+ escaped = true;
181
+ else if (character === quote)
182
+ quote = null;
183
+ continue;
184
+ }
185
+ if (escaped) {
186
+ escaped = false;
187
+ continue;
188
+ }
189
+ if (character === "\\") {
190
+ escaped = true;
191
+ continue;
192
+ }
193
+ if (character === '"' || character === "'") {
194
+ quote = character;
195
+ continue;
196
+ }
197
+ if (character === "[") {
198
+ brackets++;
199
+ continue;
200
+ }
201
+ if (character === "]") {
202
+ brackets = Math.max(0, brackets - 1);
203
+ continue;
204
+ }
205
+ if (brackets > 0)
206
+ continue;
207
+ if (character === "(") {
208
+ parentheses++;
209
+ }
210
+ else if (character === ")") {
211
+ parentheses--;
212
+ if (parentheses === 0)
213
+ return index;
214
+ }
215
+ }
216
+ return -1;
217
+ }
218
+ export function isElementSensitiveSelector(selector) {
219
+ const cached = selectorSensitivityMemo.get(selector);
220
+ if (cached !== undefined)
221
+ return cached;
222
+ const result = computeElementSensitiveSelector(selector);
223
+ if (selectorSensitivityMemo.size >= SELECTOR_SENSITIVITY_CACHE_MAX)
224
+ selectorSensitivityMemo.clear();
225
+ selectorSensitivityMemo.set(selector, result);
226
+ return result;
227
+ }
228
+ function computeElementSensitiveSelector(selector) {
229
+ let attributeDepth = 0;
230
+ let quote = null;
231
+ let escaped = false;
232
+ for (let index = 0; index < selector.length; index++) {
233
+ const character = selector[index];
234
+ if (quote) {
235
+ if (escaped)
236
+ escaped = false;
237
+ else if (character === "\\")
238
+ escaped = true;
239
+ else if (character === quote)
240
+ quote = null;
241
+ continue;
242
+ }
243
+ if (attributeDepth > 0) {
244
+ if (character === '"' || character === "'")
245
+ quote = character;
246
+ else if (character === "[")
247
+ attributeDepth++;
248
+ else if (character === "]")
249
+ attributeDepth--;
250
+ continue;
251
+ }
252
+ // Tailwind escapes utility variants such as `.sm\\:text-red-500`. The
253
+ // escaped colon is part of the class name, not a pseudo-class boundary.
254
+ if (escaped) {
255
+ escaped = false;
256
+ continue;
257
+ }
258
+ if (character === "\\") {
259
+ escaped = true;
260
+ continue;
261
+ }
262
+ if (character === "[") {
263
+ attributeDepth = 1;
264
+ continue;
265
+ }
266
+ if (character === "+" || character === "~")
267
+ return true;
268
+ if (character !== ":")
269
+ continue;
270
+ const pseudoElement = selector[index + 1] === ":";
271
+ const pseudo = /^[A-Za-z-]+/.exec(selector.slice(index + (pseudoElement ? 2 : 1)))?.[0];
272
+ if (pseudoElement) {
273
+ // Pseudo-elements do not change whether the originating element matches
274
+ // a selector. Continue scanning after the name so a real pseudo-class
275
+ // elsewhere in the selector remains element-sensitive.
276
+ if (!pseudo)
277
+ return true;
278
+ index += pseudo.length + 1;
279
+ let next = index + 1;
280
+ while (next < selector.length && /\s/.test(selector[next]))
281
+ next++;
282
+ if (selector[next] === "(")
283
+ return true;
284
+ continue;
285
+ }
286
+ if (!pseudo)
287
+ continue;
288
+ const pseudoName = pseudo.toLowerCase();
289
+ index += pseudo.length;
290
+ let next = index + 1;
291
+ while (next < selector.length && /\s/.test(selector[next]))
292
+ next++;
293
+ if (STATIC_SELECTOR_FUNCTIONS.has(pseudoName) && selector[next] === "(") {
294
+ const end = selectorFunctionEnd(selector, next);
295
+ if (end < 0 || isElementSensitiveSelector(selector.slice(next + 1, end)))
296
+ return true;
297
+ index = end;
298
+ continue;
299
+ }
300
+ // :root and :host are represented by the complete ancestor/document
301
+ // context. Other pseudo-classes can vary per concrete element without an
302
+ // attribute or sibling mutation (for example :checked, :visited, and
303
+ // :target), so keep them in the element-sensitive bucket.
304
+ if (STATIC_PSEUDO_CLASSES.has(pseudoName))
305
+ continue;
306
+ return true;
307
+ }
308
+ return false;
309
+ }
310
+ function selectorSubject(selector) {
311
+ let start = 0;
312
+ let parentheses = 0;
313
+ let brackets = 0;
314
+ let quote = null;
315
+ let escaped = false;
316
+ for (let index = 0; index < selector.length; index++) {
317
+ const character = selector[index];
318
+ if (quote) {
319
+ if (escaped)
320
+ escaped = false;
321
+ else if (character === "\\")
322
+ escaped = true;
323
+ else if (character === quote)
324
+ quote = null;
325
+ continue;
326
+ }
327
+ if (escaped) {
328
+ escaped = false;
329
+ continue;
330
+ }
331
+ if (character === "\\") {
332
+ escaped = true;
333
+ continue;
334
+ }
335
+ if (character === '"' || character === "'") {
336
+ quote = character;
337
+ continue;
338
+ }
339
+ if (character === "[") {
340
+ brackets++;
341
+ continue;
342
+ }
343
+ if (character === "]") {
344
+ brackets = Math.max(0, brackets - 1);
345
+ continue;
346
+ }
347
+ if (brackets > 0)
348
+ continue;
349
+ if (character === "(") {
350
+ parentheses++;
351
+ continue;
352
+ }
353
+ if (character === ")") {
354
+ parentheses = Math.max(0, parentheses - 1);
355
+ continue;
356
+ }
357
+ if (parentheses > 0)
358
+ continue;
359
+ if (character === ">" || character === "+" || character === "~" || /\s/.test(character)) {
360
+ start = index + 1;
361
+ }
362
+ }
363
+ return selector.slice(start).trim();
364
+ }
365
+ function cssIdentifierEnd(source, start) {
366
+ let index = start;
367
+ while (index < source.length) {
368
+ const character = source[index];
369
+ if (character === "\\") {
370
+ index++;
371
+ if (index >= source.length)
372
+ break;
373
+ if (/[0-9a-fA-F]/.test(source[index])) {
374
+ let digits = 0;
375
+ while (index < source.length && digits < 6 && /[0-9a-fA-F]/.test(source[index])) {
376
+ index++;
377
+ digits++;
378
+ }
379
+ if (/\s/.test(source[index] ?? ""))
380
+ index++;
381
+ }
382
+ else {
383
+ index++;
384
+ }
385
+ continue;
386
+ }
387
+ if (!/[A-Za-z0-9_-]/.test(character) && character.charCodeAt(0) < 0x80)
388
+ break;
389
+ index++;
390
+ }
391
+ return index;
392
+ }
393
+ function unescapeCssIdentifier(value) {
394
+ return value
395
+ .replace(/\\([0-9a-fA-F]{1,6})(?:\s)?/g, (_match, hex) => {
396
+ const codePoint = Number.parseInt(hex, 16);
397
+ return codePoint === 0
398
+ || codePoint > 0x10FFFF
399
+ || (codePoint >= 0xD800 && codePoint <= 0xDFFF)
400
+ ? "\uFFFD"
401
+ : String.fromCodePoint(codePoint);
402
+ })
403
+ .replace(/\\(.)/g, "$1");
404
+ }
405
+ const SELECTOR_CLASS_REQUIREMENTS_CACHE_MAX = 16_384;
406
+ const selectorClassRequirementsMemo = new Map();
407
+ function selectorClassRequirements(selector) {
408
+ const cached = selectorClassRequirementsMemo.get(selector);
409
+ if (cached)
410
+ return cached;
411
+ const subject = selectorSubject(selector);
412
+ const requirements = [];
413
+ let parentheses = 0;
414
+ let brackets = 0;
415
+ let quote = null;
416
+ let escaped = false;
417
+ for (let index = 0; index < subject.length; index++) {
418
+ const character = subject[index];
419
+ if (quote) {
420
+ if (escaped)
421
+ escaped = false;
422
+ else if (character === "\\")
423
+ escaped = true;
424
+ else if (character === quote)
425
+ quote = null;
426
+ continue;
427
+ }
428
+ if (escaped) {
429
+ escaped = false;
430
+ continue;
431
+ }
432
+ if (character === "\\") {
433
+ escaped = true;
434
+ continue;
435
+ }
436
+ if (character === '"' || character === "'") {
437
+ quote = character;
438
+ continue;
439
+ }
440
+ if (character === "[") {
441
+ brackets++;
442
+ continue;
443
+ }
444
+ if (character === "]") {
445
+ brackets = Math.max(0, brackets - 1);
446
+ continue;
447
+ }
448
+ if (brackets > 0)
449
+ continue;
450
+ if (character === "(") {
451
+ parentheses++;
452
+ continue;
453
+ }
454
+ if (character === ")") {
455
+ parentheses = Math.max(0, parentheses - 1);
456
+ continue;
457
+ }
458
+ if (parentheses > 0 || character !== ".")
459
+ continue;
460
+ const end = cssIdentifierEnd(subject, index + 1);
461
+ const className = unescapeCssIdentifier(subject.slice(index + 1, end));
462
+ if (className)
463
+ requirements.push(className);
464
+ index = end - 1;
465
+ }
466
+ if (selectorClassRequirementsMemo.size >= SELECTOR_CLASS_REQUIREMENTS_CACHE_MAX) {
467
+ selectorClassRequirementsMemo.clear();
468
+ }
469
+ selectorClassRequirementsMemo.set(selector, requirements);
470
+ return requirements;
471
+ }
472
+ /**
473
+ * Rejects selectors whose rightmost compound requires a class the element
474
+ * does not have. This is a conservative prefilter: it only returns false for
475
+ * an impossible positive class requirement and leaves all other selectors to
476
+ * the browser's selector engine.
477
+ */
478
+ export function canMatchSelectorSubject(el, selector) {
479
+ return selectorClassRequirements(selector).every((className) => el.classList.contains(className));
480
+ }
@@ -1,7 +1,8 @@
1
- import type { TokenDefinition, TokenEntry } from "../../css/model/index.js";
2
1
  import type { InteractionState } from "../shell/styleState.js";
3
- export { invalidateStyleResolutionCache } from "./resolution/cssomCollector.js";
4
2
  import type { MatchedRule, ResolvedProperty, TokenTable } from "../../css/model/index.js";
3
+ export { getAvailableInteractionStates, resetSourceSiteMatchCache, sourceSiteMatchCacheSize } from "./resolution/ruleMatching.js";
4
+ export { buildTokenTable, getTokenTable, getAvailableTokenEntriesForElement, getAvailableTokenCatalog } from "./tokenAvailability.js";
5
+ export { invalidateStyleResolutionCache } from "./resolution/cssomCollector.js";
5
6
  /**
6
7
  * Builds (or reuses) the document's CSSOM rule snapshot ahead of a resolution
7
8
  * sweep. Idempotent: the walk runs once per stylesheet revision and is a cache
@@ -9,29 +10,6 @@ import type { MatchedRule, ResolvedProperty, TokenTable } from "../../css/model/
9
10
  * subsequent resolution sweep's blocking time small.
10
11
  */
11
12
  export declare function prewarmCssomRuleSnapshot(doc: Document): void;
12
- export declare function buildTokenTable(entries: readonly TokenEntry[]): TokenTable;
13
- export declare function getTokenTable(): TokenTable;
14
- /**
15
- * The build-time catalog is intentionally an inventory of every project token.
16
- * Element edits must instead use only custom properties resolved in that
17
- * element's cascade; a token defined by a lazy stylesheet is not usable until
18
- * that stylesheet is attached to the document. Entries are cached per element
19
- * until the element or stylesheet revision changes; the derived table reuses
20
- * `buildTokenTable`'s input-identity memo.
21
- */
22
- export declare function getAvailableTokenEntriesForElement(el: HTMLElement, definitions?: readonly TokenDefinition[]): TokenEntry[];
23
- /**
24
- * Produces the page catalog used by the global Tokens settings section. It retains the
25
- * build-time inventory separately, while removing declarations from CSS files
26
- * that have not loaded when the document exposes mappable source identities
27
- * (such as Vite's lazy route stylesheets). Opaque compiled URLs do not narrow
28
- * the adapter-supplied catalog.
29
- */
30
- export declare function getAvailableTokenCatalog(root?: HTMLElement, definitions?: readonly TokenDefinition[]): TokenDefinition[];
31
- /** Test hook: clears the per-source-site matched-rule cache. */
32
- export declare function resetSourceSiteMatchCache(): void;
33
- /** Test hook: number of distinct cached source-site match sets. */
34
- export declare function sourceSiteMatchCacheSize(): number;
35
13
  /**
36
14
  * Package-private cascade fixture seam. This exercises selector, layer,
37
15
  * importance, and interaction-state coordination while still crossing the
@@ -47,7 +25,6 @@ export declare function getResolvedProperties(el: HTMLElement, tokenTable: Token
47
25
  * computed value in the field layer.
48
26
  */
49
27
  export declare function getResolvedPropertiesForState(el: HTMLElement, tokenTable: TokenTable, state: InteractionState): ResolvedProperty[];
50
- export declare function getAvailableInteractionStates(el: HTMLElement): InteractionState[];
51
28
  /**
52
29
  * Resolves the cascade with transient interaction selectors removed. Used when
53
30
  * an editor must stay linked to the stable token beneath a live :hover/:focus