nudge-ui 0.2.0

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 (510) hide show
  1. package/README.md +66 -0
  2. package/bin/nudge-ui.mjs +7 -0
  3. package/dist/LICENSE +21 -0
  4. package/dist/client.mjs +261 -0
  5. package/dist/compiler/ast.d.ts +18 -0
  6. package/dist/compiler/ast.js +75 -0
  7. package/dist/compiler/componentContractTypes.d.ts +19 -0
  8. package/dist/compiler/componentContractTypes.js +1 -0
  9. package/dist/compiler/componentContracts.d.ts +2 -0
  10. package/dist/compiler/componentContracts.js +260 -0
  11. package/dist/compiler/componentInstrumentation.d.ts +32 -0
  12. package/dist/compiler/componentInstrumentation.js +140 -0
  13. package/dist/compiler/componentPolicyResolution.d.ts +71 -0
  14. package/dist/compiler/componentPolicyResolution.js +388 -0
  15. package/dist/compiler/index.d.ts +9 -0
  16. package/dist/compiler/index.js +9 -0
  17. package/dist/compiler/packageComponentContracts.d.ts +32 -0
  18. package/dist/compiler/packageComponentContracts.js +308 -0
  19. package/dist/compiler/reactComponentProtocols.d.ts +145 -0
  20. package/dist/compiler/reactComponentProtocols.js +47 -0
  21. package/dist/compiler/reactIdentity.d.ts +15 -0
  22. package/dist/compiler/reactIdentity.js +339 -0
  23. package/dist/compiler/sourcePaths.d.ts +12 -0
  24. package/dist/compiler/sourcePaths.js +27 -0
  25. package/dist/css/dialects/index.d.ts +62 -0
  26. package/dist/css/dialects/index.js +103 -0
  27. package/dist/css/dialects/tailwind.d.ts +46 -0
  28. package/dist/css/dialects/tailwind.js +119 -0
  29. package/dist/css/dialects/vanillaExtract.d.ts +20 -0
  30. package/dist/css/dialects/vanillaExtract.js +32 -0
  31. package/dist/css/index.d.ts +10 -0
  32. package/dist/css/index.js +10 -0
  33. package/dist/css/model/index.d.ts +190 -0
  34. package/dist/css/model/index.js +10 -0
  35. package/dist/css/token-inventory/index.d.ts +26 -0
  36. package/dist/css/token-inventory/index.js +24 -0
  37. package/dist/css/token-inventory/inventory.d.ts +8 -0
  38. package/dist/css/token-inventory/inventory.js +421 -0
  39. package/dist/css/token-inventory/parseStylesheet.d.ts +16 -0
  40. package/dist/css/token-inventory/parseStylesheet.js +155 -0
  41. package/dist/css/token-inventory/policy.d.ts +47 -0
  42. package/dist/css/token-inventory/policy.js +50 -0
  43. package/dist/css/token-inventory/types.d.ts +97 -0
  44. package/dist/css/token-inventory/types.js +1 -0
  45. package/dist/css/value-semantics/borderSemantics.d.ts +28 -0
  46. package/dist/css/value-semantics/borderSemantics.js +91 -0
  47. package/dist/css/value-semantics/boxSemantics.d.ts +37 -0
  48. package/dist/css/value-semantics/boxSemantics.js +71 -0
  49. package/dist/css/value-semantics/colorSemantics.d.ts +99 -0
  50. package/dist/css/value-semantics/colorSemantics.js +526 -0
  51. package/dist/css/value-semantics/cssSyntax.d.ts +19 -0
  52. package/dist/css/value-semantics/cssSyntax.js +111 -0
  53. package/dist/css/value-semantics/fontSemantics.d.ts +35 -0
  54. package/dist/css/value-semantics/fontSemantics.js +131 -0
  55. package/dist/css/value-semantics/index.d.ts +20 -0
  56. package/dist/css/value-semantics/index.js +15 -0
  57. package/dist/css/value-semantics/propertyPolicy.d.ts +118 -0
  58. package/dist/css/value-semantics/propertyPolicy.js +356 -0
  59. package/dist/css/value-semantics/stringMaps.d.ts +2 -0
  60. package/dist/css/value-semantics/stringMaps.js +1 -0
  61. package/dist/css/value-semantics/structuredValues.d.ts +64 -0
  62. package/dist/css/value-semantics/structuredValues.js +250 -0
  63. package/dist/css/value-semantics/tokenInterpretation.d.ts +90 -0
  64. package/dist/css/value-semantics/tokenInterpretation.js +193 -0
  65. package/dist/css/virtual-design-tokens.d.ts +17 -0
  66. package/dist/hosts/astro/astroRuntimeConfig.d.ts +12 -0
  67. package/dist/hosts/astro/astroRuntimeConfig.js +26 -0
  68. package/dist/hosts/astro/clientAsset.d.ts +12 -0
  69. package/dist/hosts/astro/clientAsset.js +51 -0
  70. package/dist/hosts/astro/clientTransport.d.ts +3 -0
  71. package/dist/hosts/astro/clientTransport.js +57 -0
  72. package/dist/hosts/astro/index.d.ts +3 -0
  73. package/dist/hosts/astro/index.js +2 -0
  74. package/dist/hosts/astro/integration.d.ts +35 -0
  75. package/dist/hosts/astro/integration.js +96 -0
  76. package/dist/hosts/astro/middleware.d.ts +13 -0
  77. package/dist/hosts/astro/middleware.js +22 -0
  78. package/dist/hosts/astro/projectContext.d.ts +11 -0
  79. package/dist/hosts/astro/projectContext.js +34 -0
  80. package/dist/hosts/astro/responseInstrumentation.d.ts +41 -0
  81. package/dist/hosts/astro/responseInstrumentation.js +80 -0
  82. package/dist/hosts/next/index.d.ts +4 -0
  83. package/dist/hosts/next/index.js +7 -0
  84. package/dist/hosts/next/loader.d.ts +66 -0
  85. package/dist/hosts/next/loader.js +346 -0
  86. package/dist/hosts/next/loaders/identity-loader.cjs +228257 -0
  87. package/dist/hosts/next/loaders/loader-plugin.cjs +228257 -0
  88. package/dist/hosts/next/manifest.d.ts +38 -0
  89. package/dist/hosts/next/manifest.js +30 -0
  90. package/dist/hosts/next/mount.d.ts +12 -0
  91. package/dist/hosts/next/mount.js +23 -0
  92. package/dist/hosts/next/repositoryScope.d.ts +20 -0
  93. package/dist/hosts/next/repositoryScope.js +33 -0
  94. package/dist/hosts/next/sidecar.d.ts +27 -0
  95. package/dist/hosts/next/sidecar.js +526 -0
  96. package/dist/hosts/next/wrapper.d.ts +67 -0
  97. package/dist/hosts/next/wrapper.js +310 -0
  98. package/dist/hosts/static/cli.d.ts +12 -0
  99. package/dist/hosts/static/cli.js +77 -0
  100. package/dist/hosts/static/html/bootstrap.d.ts +27 -0
  101. package/dist/hosts/static/html/bootstrap.js +93 -0
  102. package/dist/hosts/static/index.d.ts +4 -0
  103. package/dist/hosts/static/index.js +4 -0
  104. package/dist/hosts/static/manifest.d.ts +18 -0
  105. package/dist/hosts/static/manifest.js +51 -0
  106. package/dist/hosts/static/server.d.ts +72 -0
  107. package/dist/hosts/static/server.js +554 -0
  108. package/dist/hosts/vite/index.d.ts +20 -0
  109. package/dist/hosts/vite/index.js +48 -0
  110. package/dist/hosts/vite/react.d.ts +67 -0
  111. package/dist/hosts/vite/react.js +231 -0
  112. package/dist/hosts/vite/tokens/activeStylesheets.d.ts +28 -0
  113. package/dist/hosts/vite/tokens/activeStylesheets.js +70 -0
  114. package/dist/hosts/vite/tokens/fileMap.d.ts +2 -0
  115. package/dist/hosts/vite/tokens/fileMap.js +1 -0
  116. package/dist/hosts/vite/tokens/viteStylesheetArtifacts.d.ts +46 -0
  117. package/dist/hosts/vite/tokens/viteStylesheetArtifacts.js +104 -0
  118. package/dist/hosts/vite/virtual/design-tokens.d.ts +9 -0
  119. package/dist/hosts/vite/virtual/design-tokens.js +7 -0
  120. package/dist/hosts/vite/virtual-design-tokens.d.ts +1 -0
  121. package/dist/hosts/vite/vite.d.ts +62 -0
  122. package/dist/hosts/vite/vite.js +854 -0
  123. package/dist/html/dom.d.ts +13 -0
  124. package/dist/html/dom.js +46 -0
  125. package/dist/html/identity.d.ts +40 -0
  126. package/dist/html/identity.js +196 -0
  127. package/dist/html/insertions.d.ts +26 -0
  128. package/dist/html/insertions.js +59 -0
  129. package/dist/inspector/agent/McpConnectionDialog.d.ts +26 -0
  130. package/dist/inspector/agent/McpConnectionDialog.js +135 -0
  131. package/dist/inspector/agent/client.d.ts +98 -0
  132. package/dist/inspector/agent/client.js +728 -0
  133. package/dist/inspector/agent/connectionStatus.d.ts +13 -0
  134. package/dist/inspector/agent/connectionStatus.js +35 -0
  135. package/dist/inspector/agent/httpTransport.d.ts +21 -0
  136. package/dist/inspector/agent/httpTransport.js +347 -0
  137. package/dist/inspector/agent/protocol.d.ts +95 -0
  138. package/dist/inspector/agent/protocol.js +9 -0
  139. package/dist/inspector/agent/verification.d.ts +39 -0
  140. package/dist/inspector/agent/verification.js +207 -0
  141. package/dist/inspector/canvas/CanvasCard.d.ts +10 -0
  142. package/dist/inspector/canvas/CanvasCard.js +275 -0
  143. package/dist/inspector/canvas/CanvasElementOverlay.d.ts +2 -0
  144. package/dist/inspector/canvas/CanvasElementOverlay.js +301 -0
  145. package/dist/inspector/canvas/CanvasWorkspace.d.ts +2 -0
  146. package/dist/inspector/canvas/CanvasWorkspace.js +301 -0
  147. package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +6 -0
  148. package/dist/inspector/canvas/LockedWorkspaceNotice.js +17 -0
  149. package/dist/inspector/canvas/StaleChangeIndicator.d.ts +7 -0
  150. package/dist/inspector/canvas/StaleChangeIndicator.js +43 -0
  151. package/dist/inspector/canvas/agentPresentation.d.ts +87 -0
  152. package/dist/inspector/canvas/agentPresentation.js +421 -0
  153. package/dist/inspector/canvas/canvasGestures.d.ts +12 -0
  154. package/dist/inspector/canvas/canvasGestures.js +21 -0
  155. package/dist/inspector/canvas/canvasStore.d.ts +108 -0
  156. package/dist/inspector/canvas/canvasStore.js +448 -0
  157. package/dist/inspector/canvas/frameProtocol.d.ts +231 -0
  158. package/dist/inspector/canvas/frameProtocol.js +165 -0
  159. package/dist/inspector/canvas/linkEligibility.d.ts +8 -0
  160. package/dist/inspector/canvas/linkEligibility.js +68 -0
  161. package/dist/inspector/canvas/measurementProjection.d.ts +8 -0
  162. package/dist/inspector/canvas/measurementProjection.js +16 -0
  163. package/dist/inspector/canvas/normalizeUrl.d.ts +7 -0
  164. package/dist/inspector/canvas/normalizeUrl.js +27 -0
  165. package/dist/inspector/canvas/projection.d.ts +41 -0
  166. package/dist/inspector/canvas/projection.js +232 -0
  167. package/dist/inspector/canvas/rendererBootstrap.d.ts +4 -0
  168. package/dist/inspector/canvas/rendererBootstrap.js +410 -0
  169. package/dist/inspector/canvas/rendererCidIndex.d.ts +11 -0
  170. package/dist/inspector/canvas/rendererCidIndex.js +21 -0
  171. package/dist/inspector/canvas/rendererElementSelector.d.ts +2 -0
  172. package/dist/inspector/canvas/rendererElementSelector.js +378 -0
  173. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +2 -0
  174. package/dist/inspector/canvas/rendererSelectionProxy.js +61 -0
  175. package/dist/inspector/canvas/rendererStylesheet.d.ts +16 -0
  176. package/dist/inspector/canvas/rendererStylesheet.js +221 -0
  177. package/dist/inspector/canvas/resizeHandleScale.d.ts +13 -0
  178. package/dist/inspector/canvas/resizeHandleScale.js +20 -0
  179. package/dist/inspector/canvas/roleDetection.d.ts +5 -0
  180. package/dist/inspector/canvas/roleDetection.js +21 -0
  181. package/dist/inspector/canvas/sessionStore.d.ts +71 -0
  182. package/dist/inspector/canvas/sessionStore.js +453 -0
  183. package/dist/inspector/canvas/staleChangeDetector.d.ts +11 -0
  184. package/dist/inspector/canvas/staleChangeDetector.js +217 -0
  185. package/dist/inspector/canvas/toolbarScale.d.ts +7 -0
  186. package/dist/inspector/canvas/toolbarScale.js +11 -0
  187. package/dist/inspector/canvas/workspaceLease.d.ts +26 -0
  188. package/dist/inspector/canvas/workspaceLease.js +214 -0
  189. package/dist/inspector/changes/changesLog.d.ts +46 -0
  190. package/dist/inspector/changes/changesLog.js +209 -0
  191. package/dist/inspector/changes/codecs.d.ts +98 -0
  192. package/dist/inspector/changes/codecs.js +389 -0
  193. package/dist/inspector/changes/editModel.d.ts +74 -0
  194. package/dist/inspector/changes/editModel.js +120 -0
  195. package/dist/inspector/changes/managedStyleProjection.d.ts +6 -0
  196. package/dist/inspector/changes/managedStyleProjection.js +109 -0
  197. package/dist/inspector/changes/model.d.ts +13 -0
  198. package/dist/inspector/changes/model.js +163 -0
  199. package/dist/inspector/changes/presentation.d.ts +14 -0
  200. package/dist/inspector/changes/presentation.js +81 -0
  201. package/dist/inspector/changes/previewDiagnostics.d.ts +39 -0
  202. package/dist/inspector/changes/previewDiagnostics.js +172 -0
  203. package/dist/inspector/changes/structuralTypes.d.ts +35 -0
  204. package/dist/inspector/changes/structuralTypes.js +1 -0
  205. package/dist/inspector/changes/types.d.ts +76 -0
  206. package/dist/inspector/changes/types.js +16 -0
  207. package/dist/inspector/changes/workspaceChanges.d.ts +43 -0
  208. package/dist/inspector/changes/workspaceChanges.js +239 -0
  209. package/dist/inspector/clientManifest.d.ts +24 -0
  210. package/dist/inspector/clientManifest.js +69 -0
  211. package/dist/inspector/componentSemantics/ComponentPropsSection.d.ts +5 -0
  212. package/dist/inspector/componentSemantics/ComponentPropsSection.js +44 -0
  213. package/dist/inspector/componentSemantics/adapterRegistry.d.ts +11 -0
  214. package/dist/inspector/componentSemantics/adapterRegistry.js +75 -0
  215. package/dist/inspector/componentSemantics/boundaries.d.ts +2 -0
  216. package/dist/inspector/componentSemantics/boundaries.js +10 -0
  217. package/dist/inspector/componentSemantics/changeAction.d.ts +3 -0
  218. package/dist/inspector/componentSemantics/changeAction.js +6 -0
  219. package/dist/inspector/componentSemantics/changeModel.d.ts +8 -0
  220. package/dist/inspector/componentSemantics/changeModel.js +60 -0
  221. package/dist/inspector/componentSemantics/index.d.ts +4 -0
  222. package/dist/inspector/componentSemantics/index.js +2 -0
  223. package/dist/inspector/componentSemantics/reactRuntime.d.ts +10 -0
  224. package/dist/inspector/componentSemantics/reactRuntime.js +186 -0
  225. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +25 -0
  226. package/dist/inspector/componentSemantics/runtimeBridge.js +161 -0
  227. package/dist/inspector/componentSemantics/runtimeTypes.d.ts +2 -0
  228. package/dist/inspector/componentSemantics/runtimeTypes.js +1 -0
  229. package/dist/inspector/componentSemantics/textBinding.d.ts +69 -0
  230. package/dist/inspector/componentSemantics/textBinding.js +514 -0
  231. package/dist/inspector/componentSemantics/types.d.ts +96 -0
  232. package/dist/inspector/componentSemantics/types.js +5 -0
  233. package/dist/inspector/conformance/borderCases.d.ts +7 -0
  234. package/dist/inspector/conformance/borderCases.js +428 -0
  235. package/dist/inspector/conformance/colorCases.d.ts +8 -0
  236. package/dist/inspector/conformance/colorCases.js +470 -0
  237. package/dist/inspector/conformance/fixture.d.ts +68 -0
  238. package/dist/inspector/conformance/fixture.js +153 -0
  239. package/dist/inspector/conformance/projection.d.ts +2 -0
  240. package/dist/inspector/conformance/projection.js +3 -0
  241. package/dist/inspector/conformance/spacingCases.d.ts +6 -0
  242. package/dist/inspector/conformance/spacingCases.js +417 -0
  243. package/dist/inspector/conformance/typographyCases.d.ts +7 -0
  244. package/dist/inspector/conformance/typographyCases.js +174 -0
  245. package/dist/inspector/editScope.d.ts +4 -0
  246. package/dist/inspector/editScope.js +5 -0
  247. package/dist/inspector/index.d.ts +20 -0
  248. package/dist/inspector/index.js +236 -0
  249. package/dist/inspector/inline-text/inlineTextEditor.d.ts +74 -0
  250. package/dist/inspector/inline-text/inlineTextEditor.js +1207 -0
  251. package/dist/inspector/inline-text/inlineTextLifecycle.d.ts +2 -0
  252. package/dist/inspector/inline-text/inlineTextLifecycle.js +17 -0
  253. package/dist/inspector/inline-text/textChangeBoundary.d.ts +6 -0
  254. package/dist/inspector/inline-text/textChangeBoundary.js +1 -0
  255. package/dist/inspector/inspection/bridge.d.ts +72 -0
  256. package/dist/inspector/inspection/bridge.js +134 -0
  257. package/dist/inspector/inspection/browserCssInspection.d.ts +74 -0
  258. package/dist/inspector/inspection/browserCssInspection.js +317 -0
  259. package/dist/inspector/inspection/browserCssInspectionRegistry.d.ts +12 -0
  260. package/dist/inspector/inspection/browserCssInspectionRegistry.js +66 -0
  261. package/dist/inspector/inspection/selectionProperty.d.ts +32 -0
  262. package/dist/inspector/inspection/selectionProperty.js +33 -0
  263. package/dist/inspector/inspection/useBrowserCssInspection.d.ts +20 -0
  264. package/dist/inspector/inspection/useBrowserCssInspection.js +159 -0
  265. package/dist/inspector/overlay/DropGuideOverlay.d.ts +17 -0
  266. package/dist/inspector/overlay/DropGuideOverlay.js +17 -0
  267. package/dist/inspector/overlay/InspectorOverlay.d.ts +5 -0
  268. package/dist/inspector/overlay/InspectorOverlay.js +328 -0
  269. package/dist/inspector/overlay/MeasurementGuideOverlay.d.ts +19 -0
  270. package/dist/inspector/overlay/MeasurementGuideOverlay.js +40 -0
  271. package/dist/inspector/overlay/clickPolicy.d.ts +7 -0
  272. package/dist/inspector/overlay/clickPolicy.js +13 -0
  273. package/dist/inspector/overlay/dropGuide.d.ts +22 -0
  274. package/dist/inspector/overlay/dropGuide.js +48 -0
  275. package/dist/inspector/overlay/elementSelector.d.ts +1 -0
  276. package/dist/inspector/overlay/elementSelector.js +100 -0
  277. package/dist/inspector/overlay/frameThrottle.d.ts +10 -0
  278. package/dist/inspector/overlay/frameThrottle.js +38 -0
  279. package/dist/inspector/overlay/interactionStyles.d.ts +3 -0
  280. package/dist/inspector/overlay/interactionStyles.js +70 -0
  281. package/dist/inspector/overlay/measurementGeometry.d.ts +25 -0
  282. package/dist/inspector/overlay/measurementGeometry.js +104 -0
  283. package/dist/inspector/overlay/overlayGeometry.d.ts +40 -0
  284. package/dist/inspector/overlay/overlayGeometry.js +59 -0
  285. package/dist/inspector/overlay/selectedGeometry.d.ts +7 -0
  286. package/dist/inspector/overlay/selectedGeometry.js +51 -0
  287. package/dist/inspector/overlay/structuralGestures.d.ts +28 -0
  288. package/dist/inspector/overlay/structuralGestures.js +180 -0
  289. package/dist/inspector/projection/cssEscapes.d.ts +3 -0
  290. package/dist/inspector/projection/cssEscapes.js +20 -0
  291. package/dist/inspector/projection/managedStylesheet.d.ts +33 -0
  292. package/dist/inspector/projection/managedStylesheet.js +240 -0
  293. package/dist/inspector/projection/renderedInstance.d.ts +56 -0
  294. package/dist/inspector/projection/renderedInstance.js +306 -0
  295. package/dist/inspector/projection/structuralProjection.d.ts +93 -0
  296. package/dist/inspector/projection/structuralProjection.js +560 -0
  297. package/dist/inspector/projection/structuralProjectionBoundary.d.ts +5 -0
  298. package/dist/inspector/projection/structuralProjectionBoundary.js +65 -0
  299. package/dist/inspector/projection/textProjection.d.ts +53 -0
  300. package/dist/inspector/projection/textProjection.js +705 -0
  301. package/dist/inspector/projection/workspaceProjection.d.ts +43 -0
  302. package/dist/inspector/projection/workspaceProjection.js +58 -0
  303. package/dist/inspector/prompt/PromptSettingsDialog.d.ts +15 -0
  304. package/dist/inspector/prompt/PromptSettingsDialog.js +17 -0
  305. package/dist/inspector/prompt/clipboardHandoff.d.ts +34 -0
  306. package/dist/inspector/prompt/clipboardHandoff.js +212 -0
  307. package/dist/inspector/prompt/copyToClipboard.d.ts +1 -0
  308. package/dist/inspector/prompt/copyToClipboard.js +34 -0
  309. package/dist/inspector/prompt/detectFramework.d.ts +6 -0
  310. package/dist/inspector/prompt/detectFramework.js +4 -0
  311. package/dist/inspector/prompt/generatePrompt.d.ts +7 -0
  312. package/dist/inspector/prompt/generatePrompt.js +391 -0
  313. package/dist/inspector/prompt/promptSettings.d.ts +8 -0
  314. package/dist/inspector/prompt/promptSettings.js +28 -0
  315. package/dist/inspector/runtime/devFlag.d.ts +28 -0
  316. package/dist/inspector/runtime/devFlag.js +50 -0
  317. package/dist/inspector/runtime/documentStylesheetOrder.d.ts +19 -0
  318. package/dist/inspector/runtime/documentStylesheetOrder.js +89 -0
  319. package/dist/inspector/runtime/domRealm.d.ts +4 -0
  320. package/dist/inspector/runtime/domRealm.js +11 -0
  321. package/dist/inspector/runtime/runtimeConfig.d.ts +119 -0
  322. package/dist/inspector/runtime/runtimeConfig.js +276 -0
  323. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +32 -0
  324. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +149 -0
  325. package/dist/inspector/runtime/useRuntimeConfig.d.ts +10 -0
  326. package/dist/inspector/runtime/useRuntimeConfig.js +13 -0
  327. package/dist/inspector/selection/editScope.d.ts +32 -0
  328. package/dist/inspector/selection/editScope.js +140 -0
  329. package/dist/inspector/selection/editTarget.d.ts +8 -0
  330. package/dist/inspector/selection/editTarget.js +11 -0
  331. package/dist/inspector/selection/hierarchy.d.ts +7 -0
  332. package/dist/inspector/selection/hierarchy.js +42 -0
  333. package/dist/inspector/selection/resolveSelection.d.ts +10 -0
  334. package/dist/inspector/selection/resolveSelection.js +60 -0
  335. package/dist/inspector/selection/selectionStore.d.ts +41 -0
  336. package/dist/inspector/selection/selectionStore.js +262 -0
  337. package/dist/inspector/selection/selectionTarget.d.ts +5 -0
  338. package/dist/inspector/selection/selectionTarget.js +50 -0
  339. package/dist/inspector/selection/sourceSite.d.ts +2 -0
  340. package/dist/inspector/selection/sourceSite.js +12 -0
  341. package/dist/inspector/selection/styleSelection.d.ts +22 -0
  342. package/dist/inspector/selection/styleSelection.js +104 -0
  343. package/dist/inspector/session/index.d.ts +3 -0
  344. package/dist/inspector/session/index.js +2 -0
  345. package/dist/inspector/session/lifecycle.d.ts +22 -0
  346. package/dist/inspector/session/lifecycle.js +63 -0
  347. package/dist/inspector/session/sessionContext.d.ts +21 -0
  348. package/dist/inspector/session/sessionContext.js +28 -0
  349. package/dist/inspector/session/sessionFactory.d.ts +29 -0
  350. package/dist/inspector/session/sessionFactory.js +73 -0
  351. package/dist/inspector/settings/SettingsDialog.d.ts +12 -0
  352. package/dist/inspector/settings/SettingsDialog.js +46 -0
  353. package/dist/inspector/shell/AppShell.d.ts +2 -0
  354. package/dist/inspector/shell/AppShell.js +9 -0
  355. package/dist/inspector/shell/ChangesLog.d.ts +6 -0
  356. package/dist/inspector/shell/ChangesLog.js +92 -0
  357. package/dist/inspector/shell/CopyPromptButton.d.ts +9 -0
  358. package/dist/inspector/shell/CopyPromptButton.js +159 -0
  359. package/dist/inspector/shell/DomNavigation.d.ts +8 -0
  360. package/dist/inspector/shell/DomNavigation.js +30 -0
  361. package/dist/inspector/shell/EmptyState.d.ts +2 -0
  362. package/dist/inspector/shell/EmptyState.js +15 -0
  363. package/dist/inspector/shell/InspectorShell.d.ts +11 -0
  364. package/dist/inspector/shell/InspectorShell.js +268 -0
  365. package/dist/inspector/shell/openStore.d.ts +6 -0
  366. package/dist/inspector/shell/openStore.js +29 -0
  367. package/dist/inspector/shell/panelLayout.d.ts +2 -0
  368. package/dist/inspector/shell/panelLayout.js +29 -0
  369. package/dist/inspector/shell/shortcuts.d.ts +3 -0
  370. package/dist/inspector/shell/shortcuts.js +25 -0
  371. package/dist/inspector/shell/stateValue.d.ts +3 -0
  372. package/dist/inspector/shell/stateValue.js +34 -0
  373. package/dist/inspector/shell/styleState.d.ts +7 -0
  374. package/dist/inspector/shell/styleState.js +13 -0
  375. package/dist/inspector/spacing/projection.d.ts +43 -0
  376. package/dist/inspector/spacing/projection.js +136 -0
  377. package/dist/inspector/styleEditors/AppearanceSection.d.ts +13 -0
  378. package/dist/inspector/styleEditors/AppearanceSection.js +6 -0
  379. package/dist/inspector/styleEditors/AspectRatioField.d.ts +17 -0
  380. package/dist/inspector/styleEditors/AspectRatioField.js +10 -0
  381. package/dist/inspector/styleEditors/BorderEditor.d.ts +13 -0
  382. package/dist/inspector/styleEditors/BorderEditor.js +295 -0
  383. package/dist/inspector/styleEditors/BorderRadiusEditor.d.ts +14 -0
  384. package/dist/inspector/styleEditors/BorderRadiusEditor.js +108 -0
  385. package/dist/inspector/styleEditors/BoxShadowEditor.d.ts +13 -0
  386. package/dist/inspector/styleEditors/BoxShadowEditor.js +13 -0
  387. package/dist/inspector/styleEditors/ColorPicker.d.ts +15 -0
  388. package/dist/inspector/styleEditors/ColorPicker.js +73 -0
  389. package/dist/inspector/styleEditors/GapField.d.ts +17 -0
  390. package/dist/inspector/styleEditors/GapField.js +12 -0
  391. package/dist/inspector/styleEditors/GridChildSection.d.ts +14 -0
  392. package/dist/inspector/styleEditors/GridChildSection.js +91 -0
  393. package/dist/inspector/styleEditors/GridPicker.d.ts +13 -0
  394. package/dist/inspector/styleEditors/GridPicker.js +179 -0
  395. package/dist/inspector/styleEditors/GridSection.d.ts +17 -0
  396. package/dist/inspector/styleEditors/GridSection.js +27 -0
  397. package/dist/inspector/styleEditors/GridValueField.d.ts +17 -0
  398. package/dist/inspector/styleEditors/GridValueField.js +70 -0
  399. package/dist/inspector/styleEditors/InsetSection.d.ts +15 -0
  400. package/dist/inspector/styleEditors/InsetSection.js +15 -0
  401. package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +6 -0
  402. package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +6 -0
  403. package/dist/inspector/styleEditors/LayoutComboField.d.ts +18 -0
  404. package/dist/inspector/styleEditors/LayoutComboField.js +138 -0
  405. package/dist/inspector/styleEditors/LayoutDropdown.d.ts +14 -0
  406. package/dist/inspector/styleEditors/LayoutDropdown.js +34 -0
  407. package/dist/inspector/styleEditors/LayoutSection.d.ts +13 -0
  408. package/dist/inspector/styleEditors/LayoutSection.js +342 -0
  409. package/dist/inspector/styleEditors/OpacityEditor.d.ts +13 -0
  410. package/dist/inspector/styleEditors/OpacityEditor.js +34 -0
  411. package/dist/inspector/styleEditors/PositionInsets.d.ts +15 -0
  412. package/dist/inspector/styleEditors/PositionInsets.js +12 -0
  413. package/dist/inspector/styleEditors/SpacingBox.d.ts +29 -0
  414. package/dist/inspector/styleEditors/SpacingBox.js +189 -0
  415. package/dist/inspector/styleEditors/Typography.d.ts +13 -0
  416. package/dist/inspector/styleEditors/Typography.js +137 -0
  417. package/dist/inspector/styleEditors/completeCssValue.d.ts +8 -0
  418. package/dist/inspector/styleEditors/completeCssValue.js +34 -0
  419. package/dist/inspector/styleEditors/gridChildModel.d.ts +74 -0
  420. package/dist/inspector/styleEditors/gridChildModel.js +138 -0
  421. package/dist/inspector/styleEditors/layoutValue.d.ts +24 -0
  422. package/dist/inspector/styleEditors/layoutValue.js +103 -0
  423. package/dist/inspector/styleEditors/nudgeValue.d.ts +8 -0
  424. package/dist/inspector/styleEditors/nudgeValue.js +71 -0
  425. package/dist/inspector/styleEditors/rowLookup.d.ts +11 -0
  426. package/dist/inspector/styleEditors/rowLookup.js +13 -0
  427. package/dist/inspector/styleEditors/stringRecord.d.ts +4 -0
  428. package/dist/inspector/styleEditors/stringRecord.js +1 -0
  429. package/dist/inspector/styleEditors/valuePolicy.d.ts +20 -0
  430. package/dist/inspector/styleEditors/valuePolicy.js +82 -0
  431. package/dist/inspector/testing.d.ts +10 -0
  432. package/dist/inspector/testing.js +9 -0
  433. package/dist/inspector/tokens/TokenChip.d.ts +24 -0
  434. package/dist/inspector/tokens/TokenChip.js +23 -0
  435. package/dist/inspector/tokens/TokenDropdown.d.ts +13 -0
  436. package/dist/inspector/tokens/TokenDropdown.js +59 -0
  437. package/dist/inspector/tokens/TokenField.d.ts +68 -0
  438. package/dist/inspector/tokens/TokenField.js +485 -0
  439. package/dist/inspector/tokens/TokenLabel.d.ts +7 -0
  440. package/dist/inspector/tokens/TokenLabel.js +23 -0
  441. package/dist/inspector/tokens/TokensPanel.d.ts +5 -0
  442. package/dist/inspector/tokens/TokensPanel.js +47 -0
  443. package/dist/inspector/tokens/catalog.d.ts +51 -0
  444. package/dist/inspector/tokens/catalog.js +184 -0
  445. package/dist/inspector/tokens/editActions.d.ts +35 -0
  446. package/dist/inspector/tokens/editActions.js +164 -0
  447. package/dist/inspector/tokens/resolution/cascade.d.ts +14 -0
  448. package/dist/inspector/tokens/resolution/cascade.js +31 -0
  449. package/dist/inspector/tokens/resolution/cssomCollector.d.ts +43 -0
  450. package/dist/inspector/tokens/resolution/cssomCollector.js +528 -0
  451. package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +12 -0
  452. package/dist/inspector/tokens/resolution/selectorSemantics.js +106 -0
  453. package/dist/inspector/tokens/resolution.d.ts +56 -0
  454. package/dist/inspector/tokens/resolution.js +1401 -0
  455. package/dist/inspector/tokens/tokenEdits.d.ts +3 -0
  456. package/dist/inspector/tokens/tokenEdits.js +22 -0
  457. package/dist/inspector/tokens/valueSemanticsAdapter.d.ts +6 -0
  458. package/dist/inspector/tokens/valueSemanticsAdapter.js +68 -0
  459. package/dist/inspector/ui/AtRuleContext.d.ts +18 -0
  460. package/dist/inspector/ui/AtRuleContext.js +54 -0
  461. package/dist/inspector/ui/Button.d.ts +9 -0
  462. package/dist/inspector/ui/Button.js +4 -0
  463. package/dist/inspector/ui/ColorSwatch.d.ts +7 -0
  464. package/dist/inspector/ui/ColorSwatch.js +6 -0
  465. package/dist/inspector/ui/ControlSurface.d.ts +14 -0
  466. package/dist/inspector/ui/ControlSurface.js +10 -0
  467. package/dist/inspector/ui/FieldRow.d.ts +14 -0
  468. package/dist/inspector/ui/FieldRow.js +15 -0
  469. package/dist/inspector/ui/IconButton.d.ts +14 -0
  470. package/dist/inspector/ui/IconButton.js +5 -0
  471. package/dist/inspector/ui/InspectorPopover.d.ts +17 -0
  472. package/dist/inspector/ui/InspectorPopover.js +13 -0
  473. package/dist/inspector/ui/PopoverListbox.d.ts +37 -0
  474. package/dist/inspector/ui/PopoverListbox.js +21 -0
  475. package/dist/inspector/ui/SegmentedControl.d.ts +24 -0
  476. package/dist/inspector/ui/SegmentedControl.js +16 -0
  477. package/dist/inspector/ui/Select.d.ts +25 -0
  478. package/dist/inspector/ui/Select.js +56 -0
  479. package/dist/inspector/ui/SideValuesField.d.ts +44 -0
  480. package/dist/inspector/ui/SideValuesField.js +76 -0
  481. package/dist/inspector/ui/StatusCallout.d.ts +9 -0
  482. package/dist/inspector/ui/StatusCallout.js +4 -0
  483. package/dist/inspector/ui/TextInput.d.ts +12 -0
  484. package/dist/inspector/ui/TextInput.js +5 -0
  485. package/dist/inspector/ui/ToggleButton.d.ts +11 -0
  486. package/dist/inspector/ui/ToggleButton.js +6 -0
  487. package/dist/inspector/ui/assets/grid.svg +14 -0
  488. package/dist/inspector/ui/css.d.ts +9 -0
  489. package/dist/inspector/ui/labels.d.ts +1 -0
  490. package/dist/inspector/ui/labels.js +7 -0
  491. package/dist/inspector/ui/styles.d.ts +1 -0
  492. package/dist/inspector/ui/styles.js +68 -0
  493. package/dist/inspector/virtual-modules.d.ts +7 -0
  494. package/dist/inspector/vite-env.d.ts +10 -0
  495. package/dist/internal/agent-protocol.d.ts +232 -0
  496. package/dist/internal/agent-protocol.js +237 -0
  497. package/dist/nudge-ui.mjs +15722 -0
  498. package/dist/project/files.d.ts +19 -0
  499. package/dist/project/files.js +226 -0
  500. package/dist/project/identity.d.ts +6 -0
  501. package/dist/project/identity.js +19 -0
  502. package/dist/project/pathPolicy.d.ts +8 -0
  503. package/dist/project/pathPolicy.js +12 -0
  504. package/dist/project/tokens.d.ts +36 -0
  505. package/dist/project/tokens.js +223 -0
  506. package/dist/transport/index.d.ts +8 -0
  507. package/dist/transport/index.js +8 -0
  508. package/dist/transport/routes.d.ts +13 -0
  509. package/dist/transport/routes.js +16 -0
  510. package/package.json +137 -0
@@ -0,0 +1,705 @@
1
+ import { sourceSiteSelector } from "../selection/sourceSite.js";
2
+ import { isNudgeUiDev } from "../runtime/devFlag.js";
3
+ import { isTextContentChangeValue, isTextProjectionTargetValue, } from "../inline-text/textChangeBoundary.js";
4
+ import { isInteractionStylesInstalled } from "../overlay/interactionStyles.js";
5
+ /** Strict JSON boundary guard for a text projection target. */
6
+ export const isTextProjectionTarget = isTextProjectionTargetValue;
7
+ function isTextProjectionReportObject(value) {
8
+ return typeof value === "object" && value !== null;
9
+ }
10
+ function hasOnlyKeys(value, allowed) {
11
+ return Object.keys(value).every((key) => allowed.includes(key));
12
+ }
13
+ /** Dedicated document-local marker; never part of canonical session identity. */
14
+ export const TEXT_PROJECTION_ATTR = "data-projection-text";
15
+ /** Inspector-owned hit target for a projected text node whose value is empty. */
16
+ export const EMPTY_TEXT_PROJECTION_ATTR = "data-empty-text";
17
+ /** Inspector-owned exact-node evidence paired with EMPTY_TEXT_PROJECTION_ATTR. */
18
+ export const EMPTY_TEXT_PROJECTION_PATH_ATTR = "data-empty-text-path";
19
+ const UNSAFE_TEXT_TAGS = new Set(["SCRIPT", "STYLE", "TEXTAREA", "OPTION"]);
20
+ const UNSAFE_MIXED_DESCENDANT_TAGS = new Set([
21
+ ...UNSAFE_TEXT_TAGS,
22
+ "INPUT",
23
+ "SELECT",
24
+ "BUTTON",
25
+ "A",
26
+ "B",
27
+ "STRONG",
28
+ "I",
29
+ "EM",
30
+ "U",
31
+ "MARK",
32
+ "CODE",
33
+ "S",
34
+ "DEL",
35
+ "INS",
36
+ ]);
37
+ const TEXT_PROJECTION_MARKER_MAP_PREFIX = "map:";
38
+ function isTextNode(node) {
39
+ return node?.nodeType === 3;
40
+ }
41
+ function markerKey(target) {
42
+ return target.textNodePath ? `path:${target.textNodePath.join(",")}` : "root";
43
+ }
44
+ function isEmptyTextAffordance(node) {
45
+ return node instanceof HTMLElement && node.hasAttribute(EMPTY_TEXT_PROJECTION_ATTR);
46
+ }
47
+ function hasInlineTextEditor(element) {
48
+ return element.querySelector('[data-inline-editor="true"]') !== null;
49
+ }
50
+ function readProjectionMarkers(element) {
51
+ const raw = element.getAttribute(TEXT_PROJECTION_ATTR);
52
+ if (!raw)
53
+ return new Map();
54
+ if (!raw.startsWith(TEXT_PROJECTION_MARKER_MAP_PREFIX)) {
55
+ return new Map([["root", raw]]);
56
+ }
57
+ try {
58
+ const parsed = JSON.parse(raw.slice(TEXT_PROJECTION_MARKER_MAP_PREFIX.length));
59
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
60
+ return new Map();
61
+ return new Map(Object.entries(parsed).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
62
+ }
63
+ catch {
64
+ return new Map();
65
+ }
66
+ }
67
+ function writeProjectionMarkers(element, markers) {
68
+ if (markers.size === 0) {
69
+ element.removeAttribute(TEXT_PROJECTION_ATTR);
70
+ return;
71
+ }
72
+ const singleRootId = markers.size === 1 ? markers.get("root") : undefined;
73
+ if (singleRootId !== undefined && !singleRootId.startsWith(TEXT_PROJECTION_MARKER_MAP_PREFIX)) {
74
+ element.setAttribute(TEXT_PROJECTION_ATTR, singleRootId);
75
+ return;
76
+ }
77
+ const ordered = Object.fromEntries([...markers.entries()].sort(([a], [b]) => a.localeCompare(b)));
78
+ element.setAttribute(TEXT_PROJECTION_ATTR, `${TEXT_PROJECTION_MARKER_MAP_PREFIX}${JSON.stringify(ordered)}`);
79
+ }
80
+ function setProjectionMarker(element, target, id) {
81
+ const markers = readProjectionMarkers(element);
82
+ markers.set(markerKey(target), id);
83
+ writeProjectionMarkers(element, markers);
84
+ }
85
+ function hasProjectionMarker(element, target, id) {
86
+ return readProjectionMarkers(element).get(markerKey(target)) === id;
87
+ }
88
+ function removeProjectionMarker(element, target, id) {
89
+ const markers = readProjectionMarkers(element);
90
+ if (markers.get(markerKey(target)) !== id)
91
+ return;
92
+ markers.delete(markerKey(target));
93
+ writeProjectionMarkers(element, markers);
94
+ }
95
+ let canonicalChanges = new Map();
96
+ let documentStates = new Map();
97
+ let reportsByDocument = new WeakMap();
98
+ let reportsByCanvasCard = new Map();
99
+ const diagnosticListeners = new Set();
100
+ let diagnosticRevision = 0;
101
+ function normalizedText(value) {
102
+ return value.replace(/\s+/g, " ").trim();
103
+ }
104
+ function textMatches(value, expected) {
105
+ return value === expected || normalizedText(value) === normalizedText(expected);
106
+ }
107
+ function textNodePath(root, textNode) {
108
+ if (!root.contains(textNode))
109
+ return null;
110
+ const path = [];
111
+ let current = textNode;
112
+ while (current !== root) {
113
+ const parent = current.parentNode;
114
+ if (!parent)
115
+ return null;
116
+ const index = Array.prototype.indexOf.call(parent.childNodes, current);
117
+ if (index < 0)
118
+ return null;
119
+ path.unshift(index);
120
+ current = parent;
121
+ }
122
+ return path;
123
+ }
124
+ function nodeAtPath(root, path) {
125
+ let current = root;
126
+ for (const index of path) {
127
+ const child = current.childNodes[index];
128
+ if (!child)
129
+ return null;
130
+ current = child;
131
+ }
132
+ return current;
133
+ }
134
+ /** Find the exact text node represented by a target, tolerating a changed
135
+ * child path only when one bounded before/after text node remains unique. */
136
+ export function resolveTextProjectionTextNode(element, target, expectedText = target.beforeText) {
137
+ if (target.textNodePath) {
138
+ const atPath = nodeAtPath(element, target.textNodePath);
139
+ if (isTextNode(atPath)
140
+ && (expectedText === undefined || textMatches(atPath.nodeValue ?? "", expectedText))) {
141
+ return atPath;
142
+ }
143
+ }
144
+ const walker = element.ownerDocument.createTreeWalker(element, 0x4 /* NodeFilter.SHOW_TEXT */);
145
+ const matches = [];
146
+ let node = walker.nextNode();
147
+ while (node) {
148
+ if (node.nodeType === 3
149
+ && expectedText !== undefined
150
+ && textMatches(node.nodeValue ?? "", expectedText)) {
151
+ if (isTextNode(node))
152
+ matches.push(node);
153
+ }
154
+ node = walker.nextNode();
155
+ }
156
+ return matches.length === 1 ? matches[0] : null;
157
+ }
158
+ function hasSafeMixedDescendants(element) {
159
+ // <br> only controls line layout. The projection targets one exact text
160
+ // node, so keeping the break while changing that node is safe; formatting
161
+ // descendants below still reject a flattening text projection.
162
+ for (const descendant of Array.from(element.querySelectorAll("*"))) {
163
+ if (UNSAFE_MIXED_DESCENDANT_TAGS.has(descendant.tagName))
164
+ return false;
165
+ const editingHost = descendant.closest("[contenteditable]");
166
+ if (editingHost
167
+ && editingHost.getAttribute("data-inline-editor") !== "true"
168
+ && editingHost.getAttribute("contenteditable") !== "false")
169
+ return false;
170
+ }
171
+ return true;
172
+ }
173
+ function textHostIsSafe(element, allowEmpty = false, target) {
174
+ if (UNSAFE_TEXT_TAGS.has(element.tagName))
175
+ return false;
176
+ const editingHost = element.closest("[contenteditable]");
177
+ if (editingHost
178
+ && editingHost.getAttribute("data-inline-editor") !== "true"
179
+ && editingHost.getAttribute("contenteditable") !== "false")
180
+ return false;
181
+ if (allowEmpty && element.childNodes.length === 0)
182
+ return true;
183
+ if (target?.textNodePath) {
184
+ const textNode = nodeAtPath(element, target.textNodePath)
185
+ ?? resolveTextProjectionTextNode(element, target);
186
+ return Boolean(textNode
187
+ && textNode.nodeType === 3
188
+ && (allowEmpty || textNode.nodeValue?.length)
189
+ && hasSafeMixedDescendants(element));
190
+ }
191
+ // An empty-text affordance is inspector-owned and deliberately sits beside
192
+ // the retained empty Text node. Ignore it when proving that a direct leaf
193
+ // remains safe; otherwise the affordance would invalidate its own target.
194
+ const applicationChildren = Array.from(element.children)
195
+ .filter((child) => !isEmptyTextAffordance(child)
196
+ && child.getAttribute("data-inline-editor") !== "true");
197
+ if (applicationChildren.length > 0)
198
+ return false;
199
+ const textNodes = Array.from(element.childNodes).filter((node) => node.nodeType === Node.TEXT_NODE);
200
+ if (textNodes.length === 1) {
201
+ return allowEmpty || Boolean(textNodes[0]?.nodeValue?.length);
202
+ }
203
+ // The temporary inline editor wraps the retained direct Text node. Treat
204
+ // that inspector-owned wrapper as transparent while validating the
205
+ // canonical projection; otherwise its insertion would self-report as an
206
+ // application reconciliation and remove the re-entry slot mid-session.
207
+ const editingHosts = Array.from(element.children)
208
+ .filter((child) => child.getAttribute("data-inline-editor") === "true");
209
+ // The browser may split/replace the retained empty Text node while the
210
+ // native editor receives its first input. The wrapper is still inspector
211
+ // owned; its plain-text input guards are responsible for rejecting rich or
212
+ // paragraph edits, so validation must not cancel the session on that
213
+ // transient child shape.
214
+ return editingHosts.length === 1;
215
+ }
216
+ function sourceCandidates(doc, sourceSite) {
217
+ const selector = sourceSiteSelector(sourceSite.cid, sourceSite.src);
218
+ if (!selector)
219
+ return [];
220
+ try {
221
+ return Array.from(doc.querySelectorAll(selector));
222
+ }
223
+ catch {
224
+ return [];
225
+ }
226
+ }
227
+ function evidenceMatches(element, target, expectedText) {
228
+ const textNode = resolveTextProjectionTextNode(element, target, expectedText);
229
+ return textHostIsSafe(element, expectedText.length === 0, target)
230
+ && element.getAttribute("data-cprops") === target.props
231
+ && element.getAttribute("aria-label") === target.ariaLabel
232
+ && (Boolean(textNode)
233
+ || (expectedText.length === 0
234
+ && target.textNodePath === undefined
235
+ && (element.textContent ?? "") === ""));
236
+ }
237
+ /** Capture stable source/evidence identity without retaining a DOM reference. */
238
+ export function captureTextProjectionTarget(element, beforeText = element.textContent ?? "", selectedTextNode) {
239
+ if (!element.isConnected)
240
+ return null;
241
+ const textNode = selectedTextNode
242
+ ?? (element.children.length === 0
243
+ ? Array.from(element.childNodes).find((node) => node.nodeType === 3)
244
+ : null);
245
+ const path = textNode ? textNodePath(element, textNode) : null;
246
+ const pathTarget = path && element.children.length > 0 ? { textNodePath: path } : undefined;
247
+ if (!textHostIsSafe(element, false, pathTarget))
248
+ return null;
249
+ const cid = element.getAttribute("data-cid") ?? "";
250
+ const src = element.getAttribute("data-src") ?? "";
251
+ if (!cid || !src)
252
+ return null;
253
+ const sourceSite = { cid, src };
254
+ const occurrence = sourceCandidates(element.ownerDocument, sourceSite).indexOf(element);
255
+ if (occurrence < 0)
256
+ return null;
257
+ return {
258
+ sourceSite,
259
+ occurrence,
260
+ props: element.getAttribute("data-cprops"),
261
+ ariaLabel: element.getAttribute("aria-label"),
262
+ beforeText,
263
+ ...pathTarget,
264
+ };
265
+ }
266
+ /**
267
+ * Resolve against source identity and bounded evidence. Occurrence is kept as
268
+ * presentation metadata only and is never used to choose among identical
269
+ * repeated outputs.
270
+ */
271
+ export function resolveTextProjectionTarget(doc, target, afterText) {
272
+ const candidates = sourceCandidates(doc, target.sourceSite);
273
+ const evidence = candidates.filter((element) => evidenceMatches(element, target, target.beforeText)
274
+ || (afterText !== undefined && evidenceMatches(element, target, afterText)));
275
+ if (evidence.length === 0)
276
+ return { status: "missing" };
277
+ if (evidence.length !== 1)
278
+ return { status: "ambiguous" };
279
+ return { status: "resolved", element: evidence[0] };
280
+ }
281
+ export function textProjectionSelector(target) {
282
+ return sourceSiteSelector(target.sourceSite.cid, target.sourceSite.src);
283
+ }
284
+ export function collectTextContentChanges(changes) {
285
+ return changes.filter(isTextContentChangeValue).map((change) => ({
286
+ ...change,
287
+ target: {
288
+ sourceSite: { ...change.target.sourceSite },
289
+ occurrence: change.target.occurrence,
290
+ props: change.target.props,
291
+ ariaLabel: change.target.ariaLabel,
292
+ beforeText: change.target.beforeText,
293
+ ...(change.target.textNodePath
294
+ ? { textNodePath: [...change.target.textNodePath] }
295
+ : {}),
296
+ },
297
+ source: { ...change.source },
298
+ }));
299
+ }
300
+ function removeEmptyTextAffordance(state, changeId) {
301
+ const affordance = state.emptyAffordances.get(changeId);
302
+ if (affordance)
303
+ affordance.remove();
304
+ state.emptyAffordances.delete(changeId);
305
+ }
306
+ function emptyTextAffordanceFor(doc, state, change, element) {
307
+ const textNode = resolveTextProjectionTextNode(element, change.target, "");
308
+ if (!textNode || textNode.nodeValue !== "")
309
+ return null;
310
+ const parent = textNode.parentNode;
311
+ if (!(parent instanceof HTMLElement))
312
+ return null;
313
+ const path = markerKey(change.target);
314
+ // During re-entry the temporary editor wraps the empty Text node. The
315
+ // existing slot remains beside that wrapper; search the whole projected
316
+ // root before creating another slot inside the editing host.
317
+ const existing = Array.from(element.querySelectorAll(`[${EMPTY_TEXT_PROJECTION_ATTR}]`))
318
+ .find((child) => child.getAttribute(EMPTY_TEXT_PROJECTION_ATTR) === change.id
319
+ && child.getAttribute(EMPTY_TEXT_PROJECTION_PATH_ATTR) === path);
320
+ if (existing) {
321
+ existing.hidden = !isInteractionStylesInstalled(doc);
322
+ state.emptyAffordances.set(change.id, existing);
323
+ return existing;
324
+ }
325
+ const affordance = doc.createElement("span");
326
+ affordance.setAttribute(EMPTY_TEXT_PROJECTION_ATTR, change.id);
327
+ affordance.setAttribute(EMPTY_TEXT_PROJECTION_PATH_ATTR, path);
328
+ affordance.setAttribute("aria-hidden", "true");
329
+ affordance.setAttribute("role", "presentation");
330
+ affordance.setAttribute("contenteditable", "false");
331
+ affordance.tabIndex = -1;
332
+ // It has no application text and is never a source identity. The
333
+ // interaction stylesheet supplies its visible, borderless hit geometry.
334
+ affordance.hidden = !isInteractionStylesInstalled(doc);
335
+ parent.insertBefore(affordance, textNode.nextSibling);
336
+ state.emptyAffordances.set(change.id, affordance);
337
+ return affordance;
338
+ }
339
+ /**
340
+ * Keep inspector-owned empty-text hit slots aligned with the canonical text
341
+ * projection. Slots are colocated with the exact retained Text node, so they
342
+ * do not replace application structure or alter the durable text path.
343
+ */
344
+ function syncEmptyTextAffordances(doc, state, changes) {
345
+ const emptyChanges = new Map(changes.filter((change) => change.after.length === 0).map((change) => [change.id, change]));
346
+ const seen = new Set();
347
+ for (const marker of Array.from(doc.querySelectorAll(`[${EMPTY_TEXT_PROJECTION_ATTR}]`))) {
348
+ const changeId = marker.getAttribute(EMPTY_TEXT_PROJECTION_ATTR);
349
+ const change = changeId ? emptyChanges.get(changeId) : undefined;
350
+ const applied = changeId ? state.applied.get(changeId) : undefined;
351
+ const identity = changeId
352
+ ? `${changeId}\u0000${marker.getAttribute(EMPTY_TEXT_PROJECTION_PATH_ATTR) ?? ""}`
353
+ : "";
354
+ const valid = Boolean(change
355
+ && applied?.status === "applied"
356
+ && applied.element?.isConnected
357
+ && applied.element.contains(marker)
358
+ && marker.getAttribute(EMPTY_TEXT_PROJECTION_PATH_ATTR) === markerKey(change.target));
359
+ if (!valid || seen.has(identity)) {
360
+ marker.remove();
361
+ if (changeId)
362
+ state.emptyAffordances.delete(changeId);
363
+ }
364
+ else {
365
+ seen.add(identity);
366
+ }
367
+ }
368
+ for (const [changeId, affordance] of state.emptyAffordances) {
369
+ if (!emptyChanges.has(changeId) || !affordance.isConnected) {
370
+ affordance.remove();
371
+ state.emptyAffordances.delete(changeId);
372
+ }
373
+ }
374
+ for (const change of emptyChanges.values()) {
375
+ const applied = state.applied.get(change.id);
376
+ if (applied?.status !== "applied" || !applied.element?.isConnected)
377
+ continue;
378
+ emptyTextAffordanceFor(doc, state, change, applied.element);
379
+ }
380
+ }
381
+ /** Returns the canonical record represented by an inspector empty-text slot. */
382
+ export function getTextContentChangeById(changeId) {
383
+ return canonicalChanges.get(changeId) ?? null;
384
+ }
385
+ function notifyDiagnostics() {
386
+ diagnosticRevision += 1;
387
+ for (const listener of diagnosticListeners)
388
+ listener();
389
+ }
390
+ function sameReports(a, b) {
391
+ return a.length === b.length && a.every((report, index) => report.changeId === b[index]?.changeId && report.status === b[index]?.status);
392
+ }
393
+ function storeReports(doc, reports) {
394
+ const before = reportsByDocument.get(doc) ?? [];
395
+ reportsByDocument.set(doc, reports);
396
+ if (!sameReports(before, reports))
397
+ notifyDiagnostics();
398
+ }
399
+ function reportsForSnapshot(state, changes) {
400
+ return changes.map((change) => ({
401
+ changeId: change.id,
402
+ status: state.applied.get(change.id)?.status ?? "missing",
403
+ }));
404
+ }
405
+ function textProjectionIdentityMatches(element, change) {
406
+ return element.getAttribute("data-cid") === change.target.sourceSite.cid
407
+ && element.getAttribute("data-src") === change.target.sourceSite.src
408
+ && element.getAttribute("data-cprops") === change.target.props
409
+ && element.getAttribute("aria-label") === change.target.ariaLabel;
410
+ }
411
+ function restoreAppliedProjection(applied) {
412
+ const element = applied.element;
413
+ if (!element || !element.isConnected)
414
+ return;
415
+ if (!hasProjectionMarker(element, applied.change.target, applied.change.id))
416
+ return;
417
+ // Never overwrite a newer application/reconciliation state during undo or
418
+ // clear. The marker, identity evidence, and projected value must all still
419
+ // belong to us; text alone is not proof after a source-site identity change.
420
+ if (!textProjectionIdentityMatches(element, applied.change))
421
+ return;
422
+ const textNode = resolveTextProjectionTextNode(element, applied.change.target, applied.change.after);
423
+ if (!textHostIsSafe(element, applied.change.after.length === 0, applied.change.target))
424
+ return;
425
+ if (textNode) {
426
+ textNode.nodeValue = applied.change.before;
427
+ }
428
+ else if (applied.change.target.textNodePath === undefined
429
+ && applied.change.after.length === 0
430
+ && (element.textContent ?? "") === "") {
431
+ element.textContent = applied.change.before;
432
+ }
433
+ }
434
+ function validationStatus(applied) {
435
+ if (applied.status === "overridden")
436
+ return "overridden";
437
+ const element = applied.element;
438
+ if (applied.status === "missing" || applied.status === "ambiguous")
439
+ return applied.status;
440
+ if (!element || !element.isConnected)
441
+ return "overridden";
442
+ if (!hasProjectionMarker(element, applied.change.target, applied.change.id))
443
+ return "overridden";
444
+ const textNode = resolveTextProjectionTextNode(element, applied.change.target, applied.change.after);
445
+ const directEmpty = applied.change.target.textNodePath === undefined
446
+ && applied.change.after.length === 0
447
+ && (element.textContent ?? "") === "";
448
+ // While an empty projection is being reopened, the native editor owns a
449
+ // draft value that intentionally differs from the canonical empty value.
450
+ // Keep the projection applied until the editor restores its Text node and
451
+ // appends the next canonical snapshot; otherwise removing the slot changes
452
+ // the wrapper's ownership and cancels the draft mid-keystroke.
453
+ const inlineDraft = hasInlineTextEditor(element);
454
+ const identityValid = textProjectionIdentityMatches(element, applied.change);
455
+ const safe = textHostIsSafe(element, applied.change.after.length === 0, applied.change.target);
456
+ if (!identityValid || !safe || (!textNode && !directEmpty && !inlineDraft)) {
457
+ return "overridden";
458
+ }
459
+ return "applied";
460
+ }
461
+ /**
462
+ * A controller can hydrate before a lazy route has mounted its tracked roots.
463
+ * Keep a missing/ambiguous record pending and retry only when the document
464
+ * mutates; an overridden projection remains authoritative and is never
465
+ * re-applied.
466
+ */
467
+ function resolvePendingProjection(doc, applied) {
468
+ if (applied.status !== "missing" && applied.status !== "ambiguous") {
469
+ return validationStatus(applied);
470
+ }
471
+ const resolved = resolveTextProjectionTarget(doc, applied.change.target, applied.change.after);
472
+ if (resolved.status !== "resolved")
473
+ return resolved.status;
474
+ const element = resolved.element;
475
+ setProjectionMarker(element, applied.change.target, applied.change.id);
476
+ const textNode = resolveTextProjectionTextNode(element, applied.change.target, applied.change.target.beforeText)
477
+ ?? resolveTextProjectionTextNode(element, applied.change.target, applied.change.after);
478
+ if (!textNode) {
479
+ if (applied.change.target.textNodePath !== undefined)
480
+ return "overridden";
481
+ element.textContent = applied.change.after;
482
+ }
483
+ else {
484
+ textNode.nodeValue = applied.change.after;
485
+ }
486
+ applied.element = element;
487
+ return "applied";
488
+ }
489
+ function validateAppliedProjection(doc, state) {
490
+ let changed = false;
491
+ for (const applied of state.applied.values()) {
492
+ const status = resolvePendingProjection(doc, applied);
493
+ if (status !== applied.status) {
494
+ applied.status = status;
495
+ changed = true;
496
+ }
497
+ }
498
+ syncEmptyTextAffordances(doc, state, [...canonicalChanges.values()]);
499
+ if (changed)
500
+ storeReports(doc, reportsForSnapshot(state, [...canonicalChanges.values()]));
501
+ }
502
+ function scheduleValidation(doc, state) {
503
+ if (state.validationQueued || state.applied.size === 0)
504
+ return;
505
+ state.validationQueued = true;
506
+ queueMicrotask(() => {
507
+ state.validationQueued = false;
508
+ validateAppliedProjection(doc, state);
509
+ });
510
+ }
511
+ function getDocumentState(doc) {
512
+ const existing = documentStates.get(doc);
513
+ if (existing)
514
+ return existing;
515
+ const state = {
516
+ applied: new Map(),
517
+ emptyAffordances: new Map(),
518
+ snapshotKey: null,
519
+ observer: null,
520
+ validationQueued: false,
521
+ };
522
+ const Observer = doc.defaultView?.MutationObserver;
523
+ if (Observer && doc.documentElement) {
524
+ state.observer = new Observer(() => scheduleValidation(doc, state));
525
+ state.observer.observe(doc.documentElement, {
526
+ childList: true,
527
+ subtree: true,
528
+ characterData: true,
529
+ attributes: true,
530
+ attributeFilter: [
531
+ "data-cid",
532
+ "data-src",
533
+ "data-cprops",
534
+ "aria-label",
535
+ TEXT_PROJECTION_ATTR,
536
+ EMPTY_TEXT_PROJECTION_ATTR,
537
+ EMPTY_TEXT_PROJECTION_PATH_ATTR,
538
+ ],
539
+ });
540
+ }
541
+ documentStates.set(doc, state);
542
+ return state;
543
+ }
544
+ /** Apply one controller-owned text snapshot to a document adapter. */
545
+ export function applyTextContentProjection(doc, changes) {
546
+ if (!isNudgeUiDev())
547
+ return [];
548
+ const state = getDocumentState(doc);
549
+ canonicalChanges = new Map(changes.map((change) => [change.id, change]));
550
+ const key = JSON.stringify(changes);
551
+ if (state.snapshotKey === key) {
552
+ // Reconciliation can happen between controller snapshots. Validate before
553
+ // reporting so a pending MutationObserver callback cannot leave a stale
554
+ // "applied" result visible to the Changes Log.
555
+ validateAppliedProjection(doc, state);
556
+ const reports = reportsForSnapshot(state, changes);
557
+ storeReports(doc, reports);
558
+ return reports;
559
+ }
560
+ const previous = state.applied;
561
+ const next = new Map();
562
+ const incomingIds = new Set(changes.map((change) => change.id));
563
+ // Removing a canonical record is an explicit revert/clear. Restore only a
564
+ // marker/value still owned by that record; every surviving record keeps its
565
+ // current application status and must not be replayed merely because an
566
+ // unrelated change altered the shared snapshot.
567
+ for (const [id, applied] of previous) {
568
+ if (incomingIds.has(id))
569
+ continue;
570
+ removeEmptyTextAffordance(state, id);
571
+ restoreAppliedProjection(applied);
572
+ if (applied.element)
573
+ removeProjectionMarker(applied.element, applied.change.target, id);
574
+ }
575
+ state.snapshotKey = key;
576
+ for (const change of changes) {
577
+ const existing = previous.get(change.id);
578
+ if (existing && JSON.stringify(existing.change) === JSON.stringify(change)) {
579
+ existing.status = resolvePendingProjection(doc, existing);
580
+ next.set(change.id, existing);
581
+ continue;
582
+ }
583
+ if (existing) {
584
+ removeEmptyTextAffordance(state, change.id);
585
+ restoreAppliedProjection(existing);
586
+ if (existing.element)
587
+ removeProjectionMarker(existing.element, existing.change.target, change.id);
588
+ }
589
+ const resolved = resolveTextProjectionTarget(doc, change.target, change.after);
590
+ if (resolved.status !== "resolved") {
591
+ next.set(change.id, { change, element: null, status: resolved.status });
592
+ continue;
593
+ }
594
+ const element = resolved.element;
595
+ setProjectionMarker(element, change.target, change.id);
596
+ const textNode = resolveTextProjectionTextNode(element, change.target, change.before)
597
+ ?? resolveTextProjectionTextNode(element, change.target, change.after);
598
+ if (!textNode && (change.target.textNodePath !== undefined || change.after.length > 0)) {
599
+ removeProjectionMarker(element, change.target, change.id);
600
+ next.set(change.id, { change, element: null, status: "missing" });
601
+ continue;
602
+ }
603
+ if (textNode)
604
+ textNode.nodeValue = change.after;
605
+ else
606
+ element.textContent = change.after;
607
+ next.set(change.id, { change, element, status: "applied" });
608
+ }
609
+ state.applied = next;
610
+ syncEmptyTextAffordances(doc, state, changes);
611
+ // Drop markers that do not belong to the current controller snapshot. This
612
+ // also cleans a marker left by a previous runtime instance without touching
613
+ // a surviving overridden projection in `next`.
614
+ for (const marker of Array.from(doc.querySelectorAll(`[${TEXT_PROJECTION_ATTR}]`))) {
615
+ const markers = readProjectionMarkers(marker);
616
+ for (const [key, id] of markers) {
617
+ const applied = next.get(id);
618
+ if (!applied || markerKey(applied.change.target) !== key)
619
+ markers.delete(key);
620
+ }
621
+ writeProjectionMarkers(marker, markers);
622
+ }
623
+ const reports = reportsForSnapshot(state, changes);
624
+ storeReports(doc, reports);
625
+ return reports;
626
+ }
627
+ export function getTextProjectionReports(doc) {
628
+ return reportsByDocument.get(doc) ?? [];
629
+ }
630
+ export function subscribeTextProjectionDiagnostics(listener) {
631
+ diagnosticListeners.add(listener);
632
+ return () => diagnosticListeners.delete(listener);
633
+ }
634
+ export function getTextProjectionDiagnosticRevision() {
635
+ return diagnosticRevision;
636
+ }
637
+ export function recordCanvasTextProjectionReports(cardId, revision, reports) {
638
+ if (!Number.isSafeInteger(revision) || revision < 0 || !reports.every(isTextProjectionReport))
639
+ return;
640
+ const expected = new Set(canonicalChanges.keys());
641
+ if (reports.length !== expected.size
642
+ || new Set(reports.map((report) => report.changeId)).size !== reports.length
643
+ || reports.some((report) => !expected.has(report.changeId)))
644
+ return;
645
+ const existing = reportsByCanvasCard.get(cardId);
646
+ if (existing && revision < existing.revision)
647
+ return;
648
+ const next = reports.map((report) => ({ ...report }));
649
+ if (existing && existing.revision === revision && sameReports(existing.reports, next))
650
+ return;
651
+ reportsByCanvasCard.set(cardId, { revision, reports: next });
652
+ notifyDiagnostics();
653
+ }
654
+ export function clearCanvasTextProjectionReports(cardId) {
655
+ if (!reportsByCanvasCard.delete(cardId))
656
+ return;
657
+ notifyDiagnostics();
658
+ }
659
+ export function getTextContentChangeDiagnostics(changeId) {
660
+ const diagnostics = [];
661
+ const change = canonicalChanges.get(changeId);
662
+ const host = reportsByDocument.get(document)?.find((report) => report.changeId === changeId);
663
+ if (host)
664
+ diagnostics.push({
665
+ ...host,
666
+ document: "Inspect",
667
+ scope: change?.scope,
668
+ evidence: change?.evidence,
669
+ });
670
+ for (const [cardId, entry] of reportsByCanvasCard) {
671
+ const report = entry.reports.find((candidate) => candidate.changeId === changeId);
672
+ if (report)
673
+ diagnostics.push({
674
+ ...report,
675
+ document: `Canvas ${cardId}`,
676
+ scope: change?.scope,
677
+ evidence: change?.evidence,
678
+ });
679
+ }
680
+ return diagnostics;
681
+ }
682
+ export function isTextProjectionReport(value) {
683
+ if (!isTextProjectionReportObject(value)
684
+ || !hasOnlyKeys(value, ["changeId", "status"]))
685
+ return false;
686
+ const { changeId, status } = value;
687
+ return typeof changeId === "string" && changeId.length > 0
688
+ && (status === "applied" || status === "missing"
689
+ || status === "ambiguous" || status === "overridden");
690
+ }
691
+ export function resetTextProjectionState() {
692
+ for (const [doc, state] of documentStates) {
693
+ state.observer?.disconnect();
694
+ for (const affordance of state.emptyAffordances.values())
695
+ affordance.remove();
696
+ for (const affordance of Array.from(doc.querySelectorAll(`[${EMPTY_TEXT_PROJECTION_ATTR}]`))) {
697
+ affordance.remove();
698
+ }
699
+ }
700
+ documentStates = new Map();
701
+ canonicalChanges = new Map();
702
+ reportsByDocument = new WeakMap();
703
+ reportsByCanvasCard.clear();
704
+ diagnosticRevision = 0;
705
+ }