@comty.io/core 0.1.8 → 0.1.10
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.
- package/README.md +32 -3
- package/comty-sdk.js +3891 -1655
- package/package.json +4 -2
- package/src/anchors.js +168 -403
- package/src/browser.js +3327 -1212
- package/src/comments.js +6 -6
- package/src/dev.mjs +317 -112
- package/src/inspect-markup.js +1 -1
- package/src/measurements.js +5 -4
- package/src/resilient-anchor.js +333 -0
- package/src/resilient-anchor.ts +551 -0
- package/src/style.js +60 -33
- package/src/vite.mjs +123 -38
package/README.md
CHANGED
|
@@ -10,17 +10,25 @@ Comments use the pathname and hash routes starting with `#/` or `#!/`. Plain fra
|
|
|
10
10
|
|
|
11
11
|
Target matching combines content, attributes and surrounding structure. Small changes inside a container can preserve its comments; ambiguous matches do not place a pin. The sidebar shows **Target missing** when no target is found and **Target uncertain** when placement cannot be determined reliably. Both still open the full thread. Closed or unmounted known overlays do not count as deleted elements, and their comments never attach to matching content outside that overlay.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
New anchors exclude editable content from inputs, textareas, selects and rich-text editors, including when comparing their surrounding containers. Repeated fields use their attributes and question context to distinguish them. React-generated IDs are not treated as permanent identities. Existing comments are resolved again on reload without rewriting their stored anchors.
|
|
14
|
+
|
|
15
|
+
New comments also capture an automatic structural anchor, with no prototype annotations or Angular development APIs. Copy, classes, dimensions and layout wrappers can change without requiring an exact text match. The nearest small composition is compared after meaningful DOM changes, even when the target node is reused. A large structural change (for example an empty illustration/action replaced by a table) hides the pin; returning to that composition resolves it again. Unrelated page changes and list length changes are tolerated. The original anchor is never rewritten. Repeated records require distinguishing context after remount, and ambiguous twins stay in the sidebar rather than borrowing another record's pin.
|
|
16
|
+
|
|
17
|
+
This is a conservative structural heuristic, not a semantic understanding of application data: states with indistinguishable markup cannot be reliably separated, and removing every distinguishing cue from repeated records can leave a comment uncertain. All comments use the same matching engine. Saved formats are normalized at read time without rewriting the original evidence. Older comments offer fewer clues: missing state fingerprints cannot be recovered, and position is not guaranteed when the remaining clues are ambiguous. Text contributes to confidence but is never a mandatory exact match.
|
|
18
|
+
|
|
19
|
+
The dependency-free TypeScript engine lives in `src/resilient-anchor.ts`; `npm run build` generates its browser JavaScript and includes it in the CDN bundle. The same source is mirrored in Hephaistos' `src/modules/commentaires/resilient-anchor.ts`; update both copies together.
|
|
20
|
+
|
|
21
|
+
Run `npm run test:anchors` for route, reload, rewritten copy, state transitions, repeated records, ambiguity and overlay regressions.
|
|
14
22
|
|
|
15
23
|
## Comment screenshots
|
|
16
24
|
|
|
17
|
-
Posting immediately displays a pending comment
|
|
25
|
+
Posting immediately displays a pending comment, captures the viewport, then sends the comment and screenshot in one multipart request. The API stores the screenshot before creating the comment. Capture or save failures restore the draft for retry instead of silently creating a comment without an image. Screenshot annotations reuse the real Comty pin and hover card (avatar, author, date and content). They are measured in an invisible, inert host, then cloned with their computed styles and embedded resources into the screenshot. The temporary host is removed after cloning and never appears on screen.
|
|
18
26
|
|
|
19
27
|
The bundled capture engine is based on `html-to-image` 1.11.13 (MIT), not SnapDOM. It embeds web fonts, responsive images, CSS backgrounds and pseudo-elements, preserves scroll offsets, and yields during DOM traversal. Each font face keeps its source when selecting WOFF2, including consecutive subset and weight rules. Transparent page backgrounds are composited over the browser's light or dark canvas so the image viewer cannot tint the screenshot. Offscreen leaf boxes keep their layout dimensions without their rendering cost. PNG is preferred for text; large images fall back to JPEG. Captures are capped at 2× resolution / 2560 pixels per side and have a 15-second processing deadline.
|
|
20
28
|
|
|
21
29
|
Resources are fetched directly first. Public cross-origin assets blocked by CORS can use `/api/sdk/capture-resource`, authenticated with the SDK token and restricted to the project's allowed domain. The API validates and pins public DNS addresses on every redirect, limits bytes/concurrency/time, and never forwards credentials to resource hosts. Deploy the API alongside the SDK to enable this fallback.
|
|
22
30
|
|
|
23
|
-
The capture never locks or restyles the live page. If the URL, viewport or page scroll changes before cloning finishes,
|
|
31
|
+
The capture never locks or restyles the live page. If the URL, viewport or page scroll changes before cloning finishes, posting fails and restores the draft for retry rather than attaching a mismatched image. Browser restrictions still apply to private resources, closed shadow roots and embedded frames; inaccessible frames retain an empty layout box. The final SVG serialization/rasterization still uses browser APIs on the main thread, so zero processing cost on every possible site cannot be guaranteed.
|
|
24
32
|
|
|
25
33
|
`npm run build` reproducibly bundles the pinned library with small checked hooks for cooperative scheduling, resource fetching, cloning and exact font sizes; its MIT notice is included. No runtime package install is needed by SDK consumers. `npm run test:capture` runs Chrome/Chromium visual and posting tests; install Chromium with `npx playwright install chromium` on machines without Chrome. Comparison PNGs are written to `test-results/`.
|
|
26
34
|
|
|
@@ -141,3 +149,24 @@ In Inspect (**Shift I**), choose **Annotate** (**D**) to draw with a pencil, rec
|
|
|
141
149
|
Choose **Capture area** (**S** while inspecting), then drag a rectangle in either direction to download a PNG. The image includes visible annotations, ruler strips, ruler guides, layout guides and distance measurements, without the toolbar or selection controls. **Escape** cancels. Captures stay local and use the existing DOM snapshot engine; inaccessible embedded pages and protected media may not appear exactly as rendered by the browser.
|
|
142
150
|
|
|
143
151
|
The local Agent refreshes on entry and when returning to the tab. It polls only while tasks are pending or running; those progress checks do not reload shared comments. Inspector tools make no polling requests while idle.
|
|
152
|
+
|
|
153
|
+
## UI style isolation
|
|
154
|
+
|
|
155
|
+
Comty renders its tools, comments and dialogs inside a Shadow DOM. Client selectors
|
|
156
|
+
(including resets and `!important` rules) do not style its internal controls.
|
|
157
|
+
Inherited typography is reset at the UI root. `src/style.js` keeps the SDK's 16px
|
|
158
|
+
rem design scale in source and resolves it to CSS pixels when emitting the private
|
|
159
|
+
stylesheet: a shadow tree alone does **not** isolate `rem` from the client's `html`.
|
|
160
|
+
Do not add root-relative sizes to inline styles or inject UI rules into the page.
|
|
161
|
+
Only inspection cursors are intentionally document-scoped.
|
|
162
|
+
|
|
163
|
+
The overlay uses the browser's top layer to escape transformed/clipped ancestors,
|
|
164
|
+
and compensates ancestor CSS `zoom` without cancelling browser zoom. Native modal
|
|
165
|
+
dialogs remain supported. Internal queries and focus checks use the shadow tree;
|
|
166
|
+
document listeners resolve retargeted UI events through their composed path.
|
|
167
|
+
|
|
168
|
+
Run `npm run test:isolation` for npm/CDN regressions against client resets, changed
|
|
169
|
+
root sizes, RTL text, hostile host selectors, CSS zoom, transforms and modal dialogs.
|
|
170
|
+
This runs in CI alongside interaction and screenshot checks. The Shadow DOM is a
|
|
171
|
+
CSS boundary, not a security sandbox: client JavaScript can still remove the widget
|
|
172
|
+
or block its resources. Top-layer isolation requires a browser with the Popover API.
|