@designfever/web-review-kit 0.8.1 → 0.8.3
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 +4 -6
- package/dist/{chunk-4ZP7B7R6.js → chunk-FWN7RQCW.js} +190 -92
- package/dist/chunk-FWN7RQCW.js.map +1 -0
- package/dist/{chunk-UNDQZ4Y2.js → chunk-XP2IACXL.js} +80 -46
- package/dist/chunk-XP2IACXL.js.map +1 -0
- package/dist/index.cjs +268 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -7
- package/dist/index.js.map +1 -1
- package/dist/react-shell.cjs +2627 -1736
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.d.cts +2 -1
- package/dist/react-shell.d.ts +2 -1
- package/dist/react-shell.js +2247 -1447
- package/dist/react-shell.js.map +1 -1
- package/dist/{types-BM8E7BFV.d.cts → types-DKDtZjTH.d.cts} +8 -0
- package/dist/{types-BM8E7BFV.d.ts → types-DKDtZjTH.d.ts} +8 -0
- package/dist/vite.cjs +13 -5
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +2 -0
- package/dist/vite.d.ts +2 -0
- package/dist/vite.js +14 -6
- package/dist/vite.js.map +1 -1
- package/docs/README.md +4 -2
- package/docs/architecture.md +33 -7
- package/docs/figma-overlay.md +24 -0
- package/docs/installation.md +3 -5
- package/docs/release-notes-0.8.2.md +50 -0
- package/docs/release-notes-0.8.3.md +48 -0
- package/docs/testing.md +12 -4
- package/package.json +1 -1
- package/dist/chunk-4ZP7B7R6.js.map +0 -1
- package/dist/chunk-UNDQZ4Y2.js.map +0 -1
package/README.md
CHANGED
|
@@ -27,10 +27,10 @@ This package does not own internal operator tools, private admin keys, or produc
|
|
|
27
27
|
- [Testing](docs/testing.md): Vitest adapter contract tests and local verification commands.
|
|
28
28
|
- [Custom adapter sample](docs/adaptor.sample.ts): starting point for host-owned remote adapters.
|
|
29
29
|
- [DB setup](docs/db-setup.md): optional Supabase `review_items` setup, RLS, presence notes, and validation.
|
|
30
|
-
- [Architecture and runtime logic](docs/architecture.md): core runtime, React shell, coordinate, anchor, and
|
|
31
|
-
- [Figma overlay](docs/figma-overlay.md):
|
|
30
|
+
- [Architecture and runtime logic](docs/architecture.md): core runtime, React shell, coordinate, anchor, sitemap, and feature ownership boundaries.
|
|
31
|
+
- [Figma overlay](docs/figma-overlay.md): host helper behavior and package-managed image overlay state.
|
|
32
32
|
- [Grid overlay](docs/grid-overlay.md): how the shell toggles a host grid/helper overlay.
|
|
33
|
-
- [Release notes 0.8.
|
|
33
|
+
- [Release notes 0.8.3](docs/release-notes-0.8.3.md): code-review bug fixes, sitemap state persistence and status filtering.
|
|
34
34
|
|
|
35
35
|
## Quick Start
|
|
36
36
|
|
|
@@ -146,12 +146,10 @@ import {
|
|
|
146
146
|
export default defineConfig({
|
|
147
147
|
plugins: [
|
|
148
148
|
reviewSourceLocator({
|
|
149
|
-
enabled: true,
|
|
150
149
|
include: ['src'],
|
|
151
150
|
filePath: 'absolute',
|
|
152
151
|
}),
|
|
153
152
|
reviewDataLocator({
|
|
154
|
-
enabled: true,
|
|
155
153
|
include: ['src/data'],
|
|
156
154
|
filePath: 'absolute',
|
|
157
155
|
}),
|
|
@@ -159,7 +157,7 @@ export default defineConfig({
|
|
|
159
157
|
});
|
|
160
158
|
```
|
|
161
159
|
|
|
162
|
-
When source hints are available, hold `Option` over the review target to inspect source
|
|
160
|
+
The locator plugins run automatically on the Vite dev server and stay disabled in production builds. Source Tree and the `Option` shortcut stay available without `sourceRoot` or an `enabled` option; `sourceRoot` is only needed to open relative source paths. When source hints are available, hold `Option` over the review target to inspect its source outline, then click the target to open the closest component in Source Tree. The source locator also reads TSX/JSX with the TypeScript parser when available and writes `data-wrk-source-component` for intrinsic JSX nodes, which helps the inspector prefer real component candidates over repeated wrapper primitives. For function component render paths, it also records the parent JSX call site so Source Tree can show where a component was used. The side rail can open a Source Tree panel with section/source/data links, parent usage links, live box metrics, text/font/media metadata, and class tags. DOM QA cards show a source action when the saved item has source hints. Source Tree filter/options, QA panel mode, and QA status filter are stored in browser localStorage.
|
|
163
161
|
|
|
164
162
|
In Vite/ESM hosts, source opening reads `VITE_REVIEW_SOURCE_ROOT`, `VITE_REVIEW_SOURCE_EDITOR`, and `VITE_REVIEW_SOURCE_URL_TEMPLATE` from the host env. Env values override matching `sourceRoot`, `sourceInspector.editor`, and `sourceInspector.urlTemplate` init values; init values still work as a fallback for existing projects and CommonJS consumers. Use `VITE_REVIEW_SOURCE_URL_TEMPLATE` only with `VITE_REVIEW_SOURCE_EDITOR=custom`; the template supports `{path}`, `{encodedPath}`, `{line}`, and `{column}`.
|
|
165
163
|
|
|
@@ -931,6 +931,15 @@ function isMeaningfulClass(value) {
|
|
|
931
931
|
) && !normalized.startsWith("mq-");
|
|
932
932
|
}
|
|
933
933
|
|
|
934
|
+
// src/core/error.ts
|
|
935
|
+
function getErrorMessage(error, fallback) {
|
|
936
|
+
if (error instanceof Error) return error.message;
|
|
937
|
+
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
938
|
+
return error.message;
|
|
939
|
+
}
|
|
940
|
+
return fallback;
|
|
941
|
+
}
|
|
942
|
+
|
|
934
943
|
// src/core/id.ts
|
|
935
944
|
function createId() {
|
|
936
945
|
if ("randomUUID" in crypto) return crypto.randomUUID();
|
|
@@ -966,6 +975,13 @@ var HOTKEY_KEY_ALIASES = {
|
|
|
966
975
|
n: ["\u315C"],
|
|
967
976
|
m: ["\u3161"]
|
|
968
977
|
};
|
|
978
|
+
function isEditableEventTarget(event) {
|
|
979
|
+
const path = event.composedPath?.() ?? [];
|
|
980
|
+
const element = path[0] ?? event.target;
|
|
981
|
+
if (!element || typeof element.tagName !== "string") return false;
|
|
982
|
+
const tag = element.tagName;
|
|
983
|
+
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || element.isContentEditable === true;
|
|
984
|
+
}
|
|
969
985
|
function isHotkey(event, hotkey) {
|
|
970
986
|
const parts = hotkey.split("+").map((part) => part.trim().toLowerCase()).filter(Boolean);
|
|
971
987
|
const key = parts.find(
|
|
@@ -1321,6 +1337,7 @@ var DraftPreviewController = class {
|
|
|
1321
1337
|
};
|
|
1322
1338
|
element.style.visibility = "hidden";
|
|
1323
1339
|
}
|
|
1340
|
+
syncDraftPreviewCloneRect(this.snapshot.clone, element);
|
|
1324
1341
|
const metrics = this.config.getMetrics(draft);
|
|
1325
1342
|
const translate = `translate(${toCssNumber(metrics.cssX)}px, ${toCssNumber(
|
|
1326
1343
|
metrics.cssY
|
|
@@ -1345,16 +1362,11 @@ var DraftPreviewController = class {
|
|
|
1345
1362
|
}
|
|
1346
1363
|
};
|
|
1347
1364
|
function positionDraftPreviewClone(clone, element, computedStyle) {
|
|
1348
|
-
const rect = element.getBoundingClientRect();
|
|
1349
1365
|
clone.setAttribute("data-dfwr-adjust-preview", "true");
|
|
1350
1366
|
clone.setAttribute("aria-hidden", "true");
|
|
1351
1367
|
clone.style.position = "fixed";
|
|
1352
|
-
clone.style.left = `${toCssNumber(rect.left)}px`;
|
|
1353
|
-
clone.style.top = `${toCssNumber(rect.top)}px`;
|
|
1354
1368
|
clone.style.right = "auto";
|
|
1355
1369
|
clone.style.bottom = "auto";
|
|
1356
|
-
clone.style.width = `${toCssNumber(rect.width)}px`;
|
|
1357
|
-
clone.style.height = `${toCssNumber(rect.height)}px`;
|
|
1358
1370
|
clone.style.maxWidth = "none";
|
|
1359
1371
|
clone.style.maxHeight = "none";
|
|
1360
1372
|
clone.style.margin = "0";
|
|
@@ -1366,6 +1378,14 @@ function positionDraftPreviewClone(clone, element, computedStyle) {
|
|
|
1366
1378
|
clone.style.willChange = "transform";
|
|
1367
1379
|
clone.style.transformOrigin = "top left";
|
|
1368
1380
|
clone.style.transform = "none";
|
|
1381
|
+
syncDraftPreviewCloneRect(clone, element);
|
|
1382
|
+
}
|
|
1383
|
+
function syncDraftPreviewCloneRect(clone, element) {
|
|
1384
|
+
const rect = element.getBoundingClientRect();
|
|
1385
|
+
clone.style.left = `${toCssNumber(rect.left)}px`;
|
|
1386
|
+
clone.style.top = `${toCssNumber(rect.top)}px`;
|
|
1387
|
+
clone.style.width = `${toCssNumber(rect.width)}px`;
|
|
1388
|
+
clone.style.height = `${toCssNumber(rect.height)}px`;
|
|
1369
1389
|
}
|
|
1370
1390
|
function getDraftPreviewDisplay(display) {
|
|
1371
1391
|
if (display === "inline" || display === "contents") return "inline-block";
|
|
@@ -1441,11 +1461,11 @@ function createStyleElement() {
|
|
|
1441
1461
|
--df-review-color-text: #f7f7f2;
|
|
1442
1462
|
--df-review-color-text-muted: rgba(247, 247, 242, 0.62);
|
|
1443
1463
|
--df-review-color-text-subtle: rgba(247, 247, 242, 0.46);
|
|
1444
|
-
--df-review-color-accent: #
|
|
1464
|
+
--df-review-color-accent: #7cc7ff;
|
|
1445
1465
|
--df-review-color-accent-contrast: #171b1e;
|
|
1446
|
-
--df-review-color-accent-soft: rgba(
|
|
1447
|
-
--df-review-color-accent-ring: rgba(
|
|
1448
|
-
--df-review-color-area: #
|
|
1466
|
+
--df-review-color-accent-soft: rgba(124, 199, 255, 0.16);
|
|
1467
|
+
--df-review-color-accent-ring: rgba(124, 199, 255, 0.6);
|
|
1468
|
+
--df-review-color-area: #7cc7ff;
|
|
1449
1469
|
--df-review-color-error: #ffb7a7;
|
|
1450
1470
|
--df-review-shadow-panel: 0 18px 48px rgba(0, 0, 0, 0.34);
|
|
1451
1471
|
--df-review-shadow-popover: 0 16px 38px rgba(0, 0, 0, 0.32);
|
|
@@ -1631,9 +1651,9 @@ function createStyleElement() {
|
|
|
1631
1651
|
.dfwr-selection-highlight {
|
|
1632
1652
|
position: fixed;
|
|
1633
1653
|
z-index: 1;
|
|
1634
|
-
border: 2px solid #
|
|
1654
|
+
border: 2px solid #7cc7ff;
|
|
1635
1655
|
border-radius: var(--df-review-radius-xs);
|
|
1636
|
-
background: rgba(
|
|
1656
|
+
background: rgba(124, 199, 255, 0.08);
|
|
1637
1657
|
box-shadow:
|
|
1638
1658
|
0 0 0 1px rgba(31, 36, 40, 0.72),
|
|
1639
1659
|
0 0 0 9999px rgba(0, 0, 0, 0.12),
|
|
@@ -1642,8 +1662,8 @@ function createStyleElement() {
|
|
|
1642
1662
|
}
|
|
1643
1663
|
|
|
1644
1664
|
.dfwr-selection-highlight.is-draft {
|
|
1645
|
-
border-color: #
|
|
1646
|
-
background: rgba(
|
|
1665
|
+
border-color: #7cc7ff;
|
|
1666
|
+
background: rgba(124, 199, 255, 0.1);
|
|
1647
1667
|
box-shadow:
|
|
1648
1668
|
0 0 0 1px rgba(31, 36, 40, 0.72),
|
|
1649
1669
|
0 0 0 9999px rgba(0, 0, 0, 0.08),
|
|
@@ -1654,9 +1674,9 @@ function createStyleElement() {
|
|
|
1654
1674
|
.dfwr-dom-hover {
|
|
1655
1675
|
position: fixed;
|
|
1656
1676
|
z-index: 2;
|
|
1657
|
-
border: 1px solid #
|
|
1677
|
+
border: 1px solid #7cc7ff;
|
|
1658
1678
|
border-radius: var(--df-review-radius-xs);
|
|
1659
|
-
background: rgba(
|
|
1679
|
+
background: rgba(124, 199, 255, 0.1);
|
|
1660
1680
|
box-shadow:
|
|
1661
1681
|
0 0 0 1px rgba(31, 36, 40, 0.72),
|
|
1662
1682
|
0 0 0 9999px rgba(0, 0, 0, 0.08);
|
|
@@ -1837,12 +1857,12 @@ function createStyleElement() {
|
|
|
1837
1857
|
}
|
|
1838
1858
|
|
|
1839
1859
|
.dfwr-area-preview-layer .dfwr-bound-marker {
|
|
1840
|
-
border-color: #
|
|
1860
|
+
border-color: #7cc7ff;
|
|
1841
1861
|
background: var(--df-review-color-panel);
|
|
1842
1862
|
box-shadow:
|
|
1843
|
-
0 0 0 5px rgba(
|
|
1863
|
+
0 0 0 5px rgba(124, 199, 255, 0.2),
|
|
1844
1864
|
0 12px 26px rgba(0, 0, 0, 0.3);
|
|
1845
|
-
color: #
|
|
1865
|
+
color: #7cc7ff;
|
|
1846
1866
|
}
|
|
1847
1867
|
|
|
1848
1868
|
.dfwr-bound-marker-icon {
|
|
@@ -1925,7 +1945,7 @@ function createStyleElement() {
|
|
|
1925
1945
|
border-radius: var(--df-review-radius-pill);
|
|
1926
1946
|
background: var(--df-review-color-accent);
|
|
1927
1947
|
box-shadow:
|
|
1928
|
-
0 0 0 4px rgba(
|
|
1948
|
+
0 0 0 4px rgba(124, 199, 255, 0.22),
|
|
1929
1949
|
0 8px 18px rgba(0, 0, 0, 0.28);
|
|
1930
1950
|
cursor: grab;
|
|
1931
1951
|
pointer-events: auto;
|
|
@@ -1943,7 +1963,7 @@ function createStyleElement() {
|
|
|
1943
1963
|
pointer-events: auto;
|
|
1944
1964
|
color: var(--df-review-color-text);
|
|
1945
1965
|
background: var(--df-review-color-panel);
|
|
1946
|
-
border: 1px solid rgba(
|
|
1966
|
+
border: 1px solid rgba(124, 199, 255, 0.56);
|
|
1947
1967
|
border-radius: var(--df-review-radius-md);
|
|
1948
1968
|
box-shadow: var(--df-review-shadow-popover);
|
|
1949
1969
|
}
|
|
@@ -1952,7 +1972,7 @@ function createStyleElement() {
|
|
|
1952
1972
|
.dfwr-area-draft.is-composer {
|
|
1953
1973
|
max-height: min(360px, calc(100vh - 32px));
|
|
1954
1974
|
overflow: auto;
|
|
1955
|
-
border-color: rgba(
|
|
1975
|
+
border-color: rgba(124, 199, 255, 0.56);
|
|
1956
1976
|
}
|
|
1957
1977
|
|
|
1958
1978
|
.dfwr-shell.is-docked-composer .dfwr-dom-popover.is-docked-composer,
|
|
@@ -1989,7 +2009,7 @@ function createStyleElement() {
|
|
|
1989
2009
|
|
|
1990
2010
|
.dfwr-draft-drag-handle:hover,
|
|
1991
2011
|
.dfwr-draft-drag-handle:focus-visible {
|
|
1992
|
-
background: rgba(
|
|
2012
|
+
background: rgba(124, 199, 255, 0.62);
|
|
1993
2013
|
}
|
|
1994
2014
|
|
|
1995
2015
|
.dfwr-draft-drag-handle:active {
|
|
@@ -2008,7 +2028,7 @@ function createStyleElement() {
|
|
|
2008
2028
|
pointer-events: auto;
|
|
2009
2029
|
color: var(--df-review-color-text);
|
|
2010
2030
|
background: var(--df-review-color-panel);
|
|
2011
|
-
border: 1px solid rgba(
|
|
2031
|
+
border: 1px solid rgba(124, 199, 255, 0.56);
|
|
2012
2032
|
border-radius: var(--df-review-radius-md);
|
|
2013
2033
|
box-shadow: var(--df-review-shadow-popover);
|
|
2014
2034
|
}
|
|
@@ -2227,7 +2247,7 @@ function createStyleElement() {
|
|
|
2227
2247
|
}
|
|
2228
2248
|
|
|
2229
2249
|
.dfwr-adjust-panel.is-active {
|
|
2230
|
-
border-color: rgba(
|
|
2250
|
+
border-color: rgba(124, 199, 255, 0.5);
|
|
2231
2251
|
background: var(--df-review-color-accent-soft);
|
|
2232
2252
|
}
|
|
2233
2253
|
|
|
@@ -2266,7 +2286,7 @@ function createStyleElement() {
|
|
|
2266
2286
|
.dfwr-adjust-toggle:hover,
|
|
2267
2287
|
.dfwr-adjust-toggle:focus-visible,
|
|
2268
2288
|
.dfwr-adjust-toggle.is-active {
|
|
2269
|
-
border-color: rgba(
|
|
2289
|
+
border-color: rgba(124, 199, 255, 0.68);
|
|
2270
2290
|
background: var(--df-review-color-accent-soft);
|
|
2271
2291
|
outline: none;
|
|
2272
2292
|
}
|
|
@@ -2329,7 +2349,7 @@ function createStyleElement() {
|
|
|
2329
2349
|
}
|
|
2330
2350
|
|
|
2331
2351
|
.dfwr-item:focus-visible {
|
|
2332
|
-
outline: 2px solid rgba(
|
|
2352
|
+
outline: 2px solid rgba(124, 199, 255, 0.72);
|
|
2333
2353
|
outline-offset: 4px;
|
|
2334
2354
|
}
|
|
2335
2355
|
|
|
@@ -2439,8 +2459,8 @@ function createStyleElement() {
|
|
|
2439
2459
|
z-index: 2;
|
|
2440
2460
|
width: 0;
|
|
2441
2461
|
height: 0;
|
|
2442
|
-
border: 1px solid #
|
|
2443
|
-
background: rgba(
|
|
2462
|
+
border: 1px solid #7cc7ff;
|
|
2463
|
+
background: rgba(124, 199, 255, 0.16);
|
|
2444
2464
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);
|
|
2445
2465
|
}
|
|
2446
2466
|
|
|
@@ -3517,6 +3537,12 @@ function createDomDraftLayer(context, draft, options = {}) {
|
|
|
3517
3537
|
pin.setAttribute("aria-label", "Move DOM point");
|
|
3518
3538
|
pin.style.left = `${hostPoint.x}px`;
|
|
3519
3539
|
pin.style.top = `${hostPoint.y}px`;
|
|
3540
|
+
if (draft.isSelectionOnly) {
|
|
3541
|
+
pin.classList.add("is-selection-only");
|
|
3542
|
+
pin.tabIndex = -1;
|
|
3543
|
+
group.append(pin);
|
|
3544
|
+
return { layer: group, composer: void 0 };
|
|
3545
|
+
}
|
|
3520
3546
|
const popover = document.createElement("div");
|
|
3521
3547
|
const position = getPopoverPosition(hostPoint, environment);
|
|
3522
3548
|
popover.className = [
|
|
@@ -3639,7 +3665,7 @@ function createDomDraftLayer(context, draft, options = {}) {
|
|
|
3639
3665
|
attachments: currentDraft.attachments
|
|
3640
3666
|
});
|
|
3641
3667
|
};
|
|
3642
|
-
const adjustmentControls = isElementDraft ? createAdjustmentControls(context, {
|
|
3668
|
+
const adjustmentControls = isElementDraft && !options.dockComposer ? createAdjustmentControls(context, {
|
|
3643
3669
|
draft,
|
|
3644
3670
|
pin,
|
|
3645
3671
|
popover,
|
|
@@ -4285,7 +4311,7 @@ var WebReviewKitView = class {
|
|
|
4285
4311
|
this.draftPreview = new DraftPreviewController({
|
|
4286
4312
|
getEnvironment: () => this.config.getEnvironment(),
|
|
4287
4313
|
getMetrics: (draft) => getDraftAdjustmentMetrics(draft, presets()),
|
|
4288
|
-
hasAdjustment: (draft) => hasDraftAdjustment(draft, presets())
|
|
4314
|
+
hasAdjustment: (draft) => draft.adjustment?.preview !== false && hasDraftAdjustment(draft, presets())
|
|
4289
4315
|
});
|
|
4290
4316
|
this.draftContext = {
|
|
4291
4317
|
config: this.config,
|
|
@@ -4306,8 +4332,11 @@ var WebReviewKitView = class {
|
|
|
4306
4332
|
shadow.replaceChildren();
|
|
4307
4333
|
shadow.append(createStyleElement());
|
|
4308
4334
|
shadow.append(hiddenItemsStyle);
|
|
4309
|
-
const
|
|
4310
|
-
const
|
|
4335
|
+
const hasSelectionOnlyDraft = state.domDraft?.isSelectionOnly === true;
|
|
4336
|
+
const hasDismissableDraft = Boolean(
|
|
4337
|
+
state.domDraft && !hasSelectionOnlyDraft || state.areaDraft
|
|
4338
|
+
);
|
|
4339
|
+
const shouldDockComposer = this.config.options.ui?.panel === false && hasDismissableDraft && !hasSelectionOnlyDraft && Boolean(this.getShellComposerHost());
|
|
4311
4340
|
let dockedComposer;
|
|
4312
4341
|
const shell = document.createElement("div");
|
|
4313
4342
|
shell.className = [
|
|
@@ -4429,13 +4458,7 @@ var WebReviewKitView = class {
|
|
|
4429
4458
|
|
|
4430
4459
|
// src/core/web.review.kit.app.ts
|
|
4431
4460
|
var ROOT_ID = "df-web-review-kit-root";
|
|
4432
|
-
|
|
4433
|
-
const path = event.composedPath?.() ?? [];
|
|
4434
|
-
const element = path[0] ?? event.target;
|
|
4435
|
-
if (!element || typeof element.tagName !== "string") return false;
|
|
4436
|
-
const tag = element.tagName;
|
|
4437
|
-
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || element.isContentEditable === true;
|
|
4438
|
-
}
|
|
4461
|
+
var VIEWPORT_SCROLL_OPTIONS = { capture: true, passive: true };
|
|
4439
4462
|
function createWebReviewKit(options) {
|
|
4440
4463
|
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
4441
4464
|
return createNoopController();
|
|
@@ -4448,6 +4471,8 @@ function createWebReviewKit(options) {
|
|
|
4448
4471
|
toggle: () => app.toggle(),
|
|
4449
4472
|
setMode: (mode) => app.setMode(mode),
|
|
4450
4473
|
startElementReview: (element, comment) => app.startElementReview(element, comment),
|
|
4474
|
+
selectElement: (element) => app.selectElement(element),
|
|
4475
|
+
adjustElementSelection: (delta, adjustmentOptions) => app.adjustElementSelection(delta, adjustmentOptions),
|
|
4451
4476
|
getMode: () => app.getMode(),
|
|
4452
4477
|
highlightItem: (itemId) => app.highlightItem(itemId),
|
|
4453
4478
|
setHiddenItemIds: (itemIds) => app.setHiddenItemIds(itemIds),
|
|
@@ -4468,6 +4493,12 @@ var WebReviewKitApp = class {
|
|
|
4468
4493
|
this.isSelectingArea = false;
|
|
4469
4494
|
this.handleKeyDown = (event) => {
|
|
4470
4495
|
if (event.key === "Escape" && this.cancelMode()) {
|
|
4496
|
+
const activeElement = document.activeElement;
|
|
4497
|
+
if (activeElement instanceof HTMLButtonElement && activeElement.matches(
|
|
4498
|
+
".df-review-mode-button, .df-review-section-outline-link.is-dom-select"
|
|
4499
|
+
)) {
|
|
4500
|
+
activeElement.blur();
|
|
4501
|
+
}
|
|
4471
4502
|
event.preventDefault();
|
|
4472
4503
|
event.stopPropagation();
|
|
4473
4504
|
return;
|
|
@@ -4482,6 +4513,7 @@ var WebReviewKitApp = class {
|
|
|
4482
4513
|
this.renderFrame = window.requestAnimationFrame(() => {
|
|
4483
4514
|
this.renderFrame = void 0;
|
|
4484
4515
|
if (this.isDraftComposerFocused()) return;
|
|
4516
|
+
this.syncDomDraftViewportGeometry();
|
|
4485
4517
|
this.render();
|
|
4486
4518
|
});
|
|
4487
4519
|
};
|
|
@@ -4539,16 +4571,48 @@ var WebReviewKitApp = class {
|
|
|
4539
4571
|
this.shadow = this.root.attachShadow({ mode: "open" });
|
|
4540
4572
|
document.body.appendChild(this.root);
|
|
4541
4573
|
document.addEventListener("keydown", this.handleKeyDown, true);
|
|
4542
|
-
window.addEventListener(
|
|
4574
|
+
window.addEventListener(
|
|
4575
|
+
"scroll",
|
|
4576
|
+
this.handleViewportChange,
|
|
4577
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
4578
|
+
);
|
|
4543
4579
|
window.addEventListener("resize", this.handleViewportChange);
|
|
4580
|
+
this.targetViewportWindow = this.getEnvironment()?.window;
|
|
4581
|
+
if (this.targetViewportWindow && this.targetViewportWindow !== window) {
|
|
4582
|
+
this.targetViewportWindow.addEventListener(
|
|
4583
|
+
"scroll",
|
|
4584
|
+
this.handleViewportChange,
|
|
4585
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
4586
|
+
);
|
|
4587
|
+
this.targetViewportWindow.addEventListener(
|
|
4588
|
+
"resize",
|
|
4589
|
+
this.handleViewportChange
|
|
4590
|
+
);
|
|
4591
|
+
}
|
|
4544
4592
|
this.render();
|
|
4545
4593
|
}
|
|
4546
4594
|
destroy() {
|
|
4547
4595
|
this.view.clearDraftPreview();
|
|
4548
4596
|
this.clearDrafts();
|
|
4549
4597
|
document.removeEventListener("keydown", this.handleKeyDown, true);
|
|
4550
|
-
window.removeEventListener(
|
|
4598
|
+
window.removeEventListener(
|
|
4599
|
+
"scroll",
|
|
4600
|
+
this.handleViewportChange,
|
|
4601
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
4602
|
+
);
|
|
4551
4603
|
window.removeEventListener("resize", this.handleViewportChange);
|
|
4604
|
+
if (this.targetViewportWindow && this.targetViewportWindow !== window) {
|
|
4605
|
+
this.targetViewportWindow.removeEventListener(
|
|
4606
|
+
"scroll",
|
|
4607
|
+
this.handleViewportChange,
|
|
4608
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
4609
|
+
);
|
|
4610
|
+
this.targetViewportWindow.removeEventListener(
|
|
4611
|
+
"resize",
|
|
4612
|
+
this.handleViewportChange
|
|
4613
|
+
);
|
|
4614
|
+
}
|
|
4615
|
+
this.targetViewportWindow = void 0;
|
|
4552
4616
|
if (this.renderFrame) {
|
|
4553
4617
|
window.cancelAnimationFrame(this.renderFrame);
|
|
4554
4618
|
this.renderFrame = void 0;
|
|
@@ -4593,6 +4657,33 @@ var WebReviewKitApp = class {
|
|
|
4593
4657
|
this.isSelectingArea = false;
|
|
4594
4658
|
await this.bindElementDraftToElement(element, { comment });
|
|
4595
4659
|
}
|
|
4660
|
+
async selectElement(element) {
|
|
4661
|
+
if (!this.isOpen) {
|
|
4662
|
+
this.isOpen = true;
|
|
4663
|
+
}
|
|
4664
|
+
this.setModeState("element");
|
|
4665
|
+
this.clearDrafts();
|
|
4666
|
+
this.isSelectingArea = false;
|
|
4667
|
+
await this.bindElementDraftToElement(element, {
|
|
4668
|
+
isSelectionOnly: true
|
|
4669
|
+
});
|
|
4670
|
+
}
|
|
4671
|
+
adjustElementSelection(delta, options) {
|
|
4672
|
+
if (!this.domDraft?.selection) return false;
|
|
4673
|
+
const current = this.domDraft.adjustment;
|
|
4674
|
+
this.domDraft = {
|
|
4675
|
+
...this.domDraft,
|
|
4676
|
+
adjustment: {
|
|
4677
|
+
x: (current?.x ?? 0) + (delta.x ?? 0),
|
|
4678
|
+
y: (current?.y ?? 0) + (delta.y ?? 0),
|
|
4679
|
+
scale: (current?.scale ?? 0) + (delta.scale ?? 0),
|
|
4680
|
+
isActive: true,
|
|
4681
|
+
preview: options?.preview ?? current?.preview
|
|
4682
|
+
}
|
|
4683
|
+
};
|
|
4684
|
+
this.render();
|
|
4685
|
+
return true;
|
|
4686
|
+
}
|
|
4596
4687
|
getMode() {
|
|
4597
4688
|
return this.mode;
|
|
4598
4689
|
}
|
|
@@ -4672,6 +4763,33 @@ var WebReviewKitApp = class {
|
|
|
4672
4763
|
this.render();
|
|
4673
4764
|
return true;
|
|
4674
4765
|
}
|
|
4766
|
+
syncDomDraftViewportGeometry() {
|
|
4767
|
+
const draft = this.domDraft;
|
|
4768
|
+
const element = draft?.previewElement;
|
|
4769
|
+
const environment = this.getEnvironment();
|
|
4770
|
+
if (!draft?.selection || !element?.isConnected || !environment || element.ownerDocument !== environment.document) {
|
|
4771
|
+
return;
|
|
4772
|
+
}
|
|
4773
|
+
const rect = element.getBoundingClientRect();
|
|
4774
|
+
if (rect.width <= 0 || rect.height <= 0) return;
|
|
4775
|
+
const selection = {
|
|
4776
|
+
left: rect.left,
|
|
4777
|
+
top: rect.top,
|
|
4778
|
+
width: rect.width,
|
|
4779
|
+
height: rect.height
|
|
4780
|
+
};
|
|
4781
|
+
this.domDraft = {
|
|
4782
|
+
...draft,
|
|
4783
|
+
marker: {
|
|
4784
|
+
...draft.marker,
|
|
4785
|
+
viewport: roundPoint({ x: rect.left, y: rect.top })
|
|
4786
|
+
},
|
|
4787
|
+
selection: {
|
|
4788
|
+
...draft.selection,
|
|
4789
|
+
viewport: toPublicSelection(selection)
|
|
4790
|
+
}
|
|
4791
|
+
};
|
|
4792
|
+
}
|
|
4675
4793
|
isDraftComposerFocused() {
|
|
4676
4794
|
if (!this.domDraft && !this.areaDraft) return false;
|
|
4677
4795
|
const composerHost = this.getEnvironment()?.composerHost;
|
|
@@ -4895,46 +5013,28 @@ var WebReviewKitApp = class {
|
|
|
4895
5013
|
this.root.style.display = previousDisplay;
|
|
4896
5014
|
}
|
|
4897
5015
|
}
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
const environment = this.getEnvironment();
|
|
4901
|
-
const draft = this.domDraft;
|
|
4902
|
-
if (!draft) return;
|
|
4903
|
-
if (!environment?.captureViewport) {
|
|
4904
|
-
this.draftError = "Viewport capture helper is not available.";
|
|
4905
|
-
this.render();
|
|
4906
|
-
return;
|
|
4907
|
-
}
|
|
4908
|
-
const captureInput = this.createViewportCaptureInput(
|
|
4909
|
-
environment,
|
|
5016
|
+
captureDomDraft(input) {
|
|
5017
|
+
return this.captureDraft(
|
|
4910
5018
|
input,
|
|
4911
|
-
|
|
5019
|
+
() => this.domDraft,
|
|
5020
|
+
(draft) => {
|
|
5021
|
+
this.domDraft = draft;
|
|
5022
|
+
}
|
|
4912
5023
|
);
|
|
4913
|
-
this.draftError = "";
|
|
4914
|
-
this.isCapturingViewport = true;
|
|
4915
|
-
this.render();
|
|
4916
|
-
try {
|
|
4917
|
-
const result = await environment.captureViewport(captureInput);
|
|
4918
|
-
const attachment = this.createCaptureDraftAttachment(result, captureInput);
|
|
4919
|
-
const currentDraft = this.domDraft ?? draft;
|
|
4920
|
-
this.domDraft = {
|
|
4921
|
-
...currentDraft,
|
|
4922
|
-
attachments: [...currentDraft.attachments ?? [], attachment]
|
|
4923
|
-
};
|
|
4924
|
-
} catch (error) {
|
|
4925
|
-
this.draftError = this.getErrorMessage(
|
|
4926
|
-
error,
|
|
4927
|
-
"Failed to capture viewport."
|
|
4928
|
-
);
|
|
4929
|
-
} finally {
|
|
4930
|
-
this.isCapturingViewport = false;
|
|
4931
|
-
this.render();
|
|
4932
|
-
}
|
|
4933
5024
|
}
|
|
4934
|
-
|
|
5025
|
+
captureAreaDraft(input) {
|
|
5026
|
+
return this.captureDraft(
|
|
5027
|
+
input,
|
|
5028
|
+
() => this.areaDraft,
|
|
5029
|
+
(draft) => {
|
|
5030
|
+
this.areaDraft = draft;
|
|
5031
|
+
}
|
|
5032
|
+
);
|
|
5033
|
+
}
|
|
5034
|
+
async captureDraft(input, getDraft, setDraft) {
|
|
4935
5035
|
if (this.isCapturingViewport) return;
|
|
4936
5036
|
const environment = this.getEnvironment();
|
|
4937
|
-
const draft =
|
|
5037
|
+
const draft = getDraft();
|
|
4938
5038
|
if (!draft) return;
|
|
4939
5039
|
if (!environment?.captureViewport) {
|
|
4940
5040
|
this.draftError = "Viewport capture helper is not available.";
|
|
@@ -4952,16 +5052,13 @@ var WebReviewKitApp = class {
|
|
|
4952
5052
|
try {
|
|
4953
5053
|
const result = await environment.captureViewport(captureInput);
|
|
4954
5054
|
const attachment = this.createCaptureDraftAttachment(result, captureInput);
|
|
4955
|
-
const currentDraft =
|
|
4956
|
-
|
|
5055
|
+
const currentDraft = getDraft() ?? draft;
|
|
5056
|
+
setDraft({
|
|
4957
5057
|
...currentDraft,
|
|
4958
5058
|
attachments: [...currentDraft.attachments ?? [], attachment]
|
|
4959
|
-
};
|
|
5059
|
+
});
|
|
4960
5060
|
} catch (error) {
|
|
4961
|
-
this.draftError =
|
|
4962
|
-
error,
|
|
4963
|
-
"Failed to capture viewport."
|
|
4964
|
-
);
|
|
5061
|
+
this.draftError = getErrorMessage(error, "Failed to capture viewport.");
|
|
4965
5062
|
} finally {
|
|
4966
5063
|
this.isCapturingViewport = false;
|
|
4967
5064
|
this.render();
|
|
@@ -5100,17 +5197,10 @@ var WebReviewKitApp = class {
|
|
|
5100
5197
|
);
|
|
5101
5198
|
}
|
|
5102
5199
|
getCreateItemErrorMessage(error, wasUploadingAttachments) {
|
|
5103
|
-
const message =
|
|
5200
|
+
const message = getErrorMessage(error, "Failed to save QA.");
|
|
5104
5201
|
const reason = error && typeof error === "object" && "reason" in error && typeof error.reason === "string" ? ` (${error.reason})` : "";
|
|
5105
5202
|
return wasUploadingAttachments && reason ? `Attachment upload failed${reason}: ${message}` : message;
|
|
5106
5203
|
}
|
|
5107
|
-
getErrorMessage(error, fallback) {
|
|
5108
|
-
if (error instanceof Error) return error.message;
|
|
5109
|
-
if (error && typeof error === "object" && "message" in error && typeof error.message === "string") {
|
|
5110
|
-
return error.message;
|
|
5111
|
-
}
|
|
5112
|
-
return fallback;
|
|
5113
|
-
}
|
|
5114
5204
|
async restoreItem(item) {
|
|
5115
5205
|
this.setModeState("idle");
|
|
5116
5206
|
this.clearDrafts();
|
|
@@ -5143,6 +5233,11 @@ function createNoopController() {
|
|
|
5143
5233
|
},
|
|
5144
5234
|
async startElementReview() {
|
|
5145
5235
|
},
|
|
5236
|
+
async selectElement() {
|
|
5237
|
+
},
|
|
5238
|
+
adjustElementSelection() {
|
|
5239
|
+
return false;
|
|
5240
|
+
},
|
|
5146
5241
|
getMode() {
|
|
5147
5242
|
return "idle";
|
|
5148
5243
|
},
|
|
@@ -5169,6 +5264,8 @@ export {
|
|
|
5169
5264
|
isPointInViewport,
|
|
5170
5265
|
toHostPoint,
|
|
5171
5266
|
clamp,
|
|
5267
|
+
getErrorMessage,
|
|
5268
|
+
isEditableEventTarget,
|
|
5172
5269
|
isHotkey,
|
|
5173
5270
|
getHotkeyActionKey,
|
|
5174
5271
|
DEFAULT_REVIEW_VIEWPORTS,
|
|
@@ -5181,7 +5278,8 @@ export {
|
|
|
5181
5278
|
getItemHighlightSelection,
|
|
5182
5279
|
shouldShowMarkerForScope,
|
|
5183
5280
|
runWithAutoScrollBehavior,
|
|
5281
|
+
getDraftViewportScale,
|
|
5184
5282
|
reviewTypographyTokens,
|
|
5185
5283
|
createWebReviewKit
|
|
5186
5284
|
};
|
|
5187
|
-
//# sourceMappingURL=chunk-
|
|
5285
|
+
//# sourceMappingURL=chunk-FWN7RQCW.js.map
|