@designfever/web-review-kit 0.8.0 → 0.8.2
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 +3 -4
- package/dist/{chunk-UNDQZ4Y2.js → chunk-XP2IACXL.js} +80 -46
- package/dist/chunk-XP2IACXL.js.map +1 -0
- package/dist/{chunk-4ZP7B7R6.js → chunk-ZWJNUOYV.js} +150 -35
- package/dist/chunk-ZWJNUOYV.js.map +1 -0
- package/dist/index.cjs +229 -81
- 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 +2 -2
- package/dist/react-shell.cjs +2345 -1126
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.d.cts +3 -1
- package/dist/react-shell.d.ts +3 -1
- package/dist/react-shell.js +2179 -1069
- 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 +2 -0
- package/docs/installation.md +26 -5
- package/docs/release-notes-0.8.1.md +23 -0
- package/docs/release-notes-0.8.2.md +50 -0
- package/package.json +1 -1
- package/dist/chunk-4ZP7B7R6.js.map +0 -1
- package/dist/chunk-UNDQZ4Y2.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -625,38 +625,69 @@ async function createClientRenderedFigmaAsset(figmaUrl, token, options, fetchOpt
|
|
|
625
625
|
const requestFetch = fetchOption ?? globalThis.fetch;
|
|
626
626
|
if (!requestFetch) throw new Error("Figma client rendering requires fetch.");
|
|
627
627
|
const renderFormat = options.renderFormat ?? "png";
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
628
|
+
const timeoutMs = options.timeoutMs ?? 1e4;
|
|
629
|
+
const imageUrl = await withStageTimeout(
|
|
630
|
+
async (signal) => {
|
|
631
|
+
const response = await requestFetch(
|
|
632
|
+
createReviewFigmaImageApiUrl({
|
|
633
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
634
|
+
fileKey: ref.fileKey,
|
|
635
|
+
nodeId: ref.nodeId,
|
|
636
|
+
format: renderFormat,
|
|
637
|
+
scale: options.renderScale,
|
|
638
|
+
useAbsoluteBounds: options.useAbsoluteBounds
|
|
639
|
+
}),
|
|
640
|
+
{
|
|
641
|
+
headers: {
|
|
642
|
+
"X-Figma-Token": token
|
|
643
|
+
},
|
|
644
|
+
signal
|
|
645
|
+
}
|
|
646
|
+
);
|
|
647
|
+
const body = await response.json().catch(() => null);
|
|
648
|
+
if (!response.ok) {
|
|
649
|
+
throw new Error(
|
|
650
|
+
body?.err || `Figma image render failed with ${response.status}`
|
|
651
|
+
);
|
|
640
652
|
}
|
|
641
|
-
|
|
653
|
+
const nextImageUrl = body?.images?.[ref.nodeId];
|
|
654
|
+
if (!nextImageUrl) {
|
|
655
|
+
throw new Error(
|
|
656
|
+
`Figma image render returned no URL for ${ref.nodeId}.`
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
return nextImageUrl;
|
|
660
|
+
},
|
|
661
|
+
timeoutMs,
|
|
662
|
+
"Figma API request timed out."
|
|
642
663
|
);
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
664
|
+
const originalBlob = await withStageTimeout(
|
|
665
|
+
async (signal) => {
|
|
666
|
+
const imageResponse = await requestFetch(imageUrl, { signal });
|
|
667
|
+
if (!imageResponse.ok) {
|
|
668
|
+
throw new Error(
|
|
669
|
+
`Figma image download failed with ${imageResponse.status}`
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
return imageResponse.blob();
|
|
673
|
+
},
|
|
674
|
+
timeoutMs,
|
|
675
|
+
"Figma image download timed out."
|
|
676
|
+
);
|
|
677
|
+
return withStageTimeout(
|
|
678
|
+
() => createProcessedFigmaAsset(originalBlob, renderFormat, options),
|
|
679
|
+
timeoutMs,
|
|
680
|
+
"Figma image processing timed out."
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
async function createProcessedFigmaAsset(originalBlob, renderFormat, options) {
|
|
654
684
|
const originalMimeType = normalizeClientImageMimeType(originalBlob.type) ?? getReviewFigmaImageMimeType(renderFormat === "jpg" ? "jpg" : "png");
|
|
655
685
|
const originalFormat = getReviewFigmaImageFormatFromMimeType(originalMimeType) ?? (renderFormat === "jpg" ? "jpg" : "png");
|
|
656
|
-
const
|
|
686
|
+
const image = await loadImageBlob(originalBlob);
|
|
687
|
+
const dimensions = readImageDimensions(image);
|
|
657
688
|
const shouldConvertToWebp = options.convertToWebp ?? true;
|
|
658
|
-
const convertedBlob = shouldConvertToWebp ? await
|
|
659
|
-
|
|
689
|
+
const convertedBlob = shouldConvertToWebp ? await convertImageToWebp(
|
|
690
|
+
image,
|
|
660
691
|
options.webpQuality ?? 0.9,
|
|
661
692
|
dimensions
|
|
662
693
|
).catch(() => null) : null;
|
|
@@ -678,22 +709,17 @@ function createReviewFigmaClientRenderedAsset({
|
|
|
678
709
|
token,
|
|
679
710
|
...options
|
|
680
711
|
}) {
|
|
681
|
-
return
|
|
682
|
-
createClientRenderedFigmaAsset(figmaUrl, token, options, fetchOption),
|
|
683
|
-
options.timeoutMs ?? 1e4
|
|
684
|
-
);
|
|
712
|
+
return createClientRenderedFigmaAsset(figmaUrl, token, options, fetchOption);
|
|
685
713
|
}
|
|
686
|
-
|
|
687
|
-
const image = await loadImageBlob(blob);
|
|
714
|
+
function readImageDimensions(image) {
|
|
688
715
|
return {
|
|
689
716
|
width: image.naturalWidth || image.width,
|
|
690
717
|
height: image.naturalHeight || image.height
|
|
691
718
|
};
|
|
692
719
|
}
|
|
693
|
-
async function
|
|
720
|
+
async function convertImageToWebp(image, quality, dimensions) {
|
|
694
721
|
if (typeof document === "undefined") return null;
|
|
695
722
|
if (!dimensions.width || !dimensions.height) return null;
|
|
696
|
-
const image = await loadImageBlob(blob);
|
|
697
723
|
const canvas = document.createElement("canvas");
|
|
698
724
|
canvas.width = dimensions.width;
|
|
699
725
|
canvas.height = dimensions.height;
|
|
@@ -745,18 +771,26 @@ function normalizeClientImageMimeType(value) {
|
|
|
745
771
|
}
|
|
746
772
|
return null;
|
|
747
773
|
}
|
|
748
|
-
async function
|
|
774
|
+
async function withStageTimeout(run, timeoutMs, message) {
|
|
775
|
+
const controller = new AbortController();
|
|
776
|
+
let didTimeout = false;
|
|
749
777
|
let timeoutId;
|
|
750
778
|
try {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
779
|
+
try {
|
|
780
|
+
return await Promise.race([
|
|
781
|
+
run(controller.signal),
|
|
782
|
+
new Promise((_, reject) => {
|
|
783
|
+
timeoutId = setTimeout(() => {
|
|
784
|
+
didTimeout = true;
|
|
785
|
+
controller.abort();
|
|
786
|
+
reject(new Error(message));
|
|
787
|
+
}, timeoutMs);
|
|
788
|
+
})
|
|
789
|
+
]);
|
|
790
|
+
} catch (error) {
|
|
791
|
+
if (didTimeout) throw new Error(message);
|
|
792
|
+
throw error;
|
|
793
|
+
}
|
|
760
794
|
} finally {
|
|
761
795
|
if (timeoutId) clearTimeout(timeoutId);
|
|
762
796
|
}
|
|
@@ -962,7 +996,7 @@ async function uploadFigmaAsset({
|
|
|
962
996
|
const requestFetch = fetchOption ?? globalThis.fetch;
|
|
963
997
|
if (!requestFetch) throw new Error("Figma asset upload requires fetch.");
|
|
964
998
|
const { blob, mimeType } = decodeAssetDataUrl(asset);
|
|
965
|
-
const response = await
|
|
999
|
+
const response = await withTimeout(
|
|
966
1000
|
requestFetch(
|
|
967
1001
|
createAssetUploadUrl(endpoint, {
|
|
968
1002
|
imageFormat: asset.imageFormat,
|
|
@@ -1091,7 +1125,7 @@ function decodeAssetDataUrl(asset) {
|
|
|
1091
1125
|
mimeType
|
|
1092
1126
|
};
|
|
1093
1127
|
}
|
|
1094
|
-
async function
|
|
1128
|
+
async function withTimeout(promise, timeoutMs, message) {
|
|
1095
1129
|
let timeoutId;
|
|
1096
1130
|
try {
|
|
1097
1131
|
return await Promise.race([
|
|
@@ -2426,6 +2460,7 @@ var DraftPreviewController = class {
|
|
|
2426
2460
|
};
|
|
2427
2461
|
element.style.visibility = "hidden";
|
|
2428
2462
|
}
|
|
2463
|
+
syncDraftPreviewCloneRect(this.snapshot.clone, element);
|
|
2429
2464
|
const metrics = this.config.getMetrics(draft);
|
|
2430
2465
|
const translate = `translate(${toCssNumber(metrics.cssX)}px, ${toCssNumber(
|
|
2431
2466
|
metrics.cssY
|
|
@@ -2450,16 +2485,11 @@ var DraftPreviewController = class {
|
|
|
2450
2485
|
}
|
|
2451
2486
|
};
|
|
2452
2487
|
function positionDraftPreviewClone(clone, element, computedStyle) {
|
|
2453
|
-
const rect = element.getBoundingClientRect();
|
|
2454
2488
|
clone.setAttribute("data-dfwr-adjust-preview", "true");
|
|
2455
2489
|
clone.setAttribute("aria-hidden", "true");
|
|
2456
2490
|
clone.style.position = "fixed";
|
|
2457
|
-
clone.style.left = `${toCssNumber(rect.left)}px`;
|
|
2458
|
-
clone.style.top = `${toCssNumber(rect.top)}px`;
|
|
2459
2491
|
clone.style.right = "auto";
|
|
2460
2492
|
clone.style.bottom = "auto";
|
|
2461
|
-
clone.style.width = `${toCssNumber(rect.width)}px`;
|
|
2462
|
-
clone.style.height = `${toCssNumber(rect.height)}px`;
|
|
2463
2493
|
clone.style.maxWidth = "none";
|
|
2464
2494
|
clone.style.maxHeight = "none";
|
|
2465
2495
|
clone.style.margin = "0";
|
|
@@ -2471,6 +2501,14 @@ function positionDraftPreviewClone(clone, element, computedStyle) {
|
|
|
2471
2501
|
clone.style.willChange = "transform";
|
|
2472
2502
|
clone.style.transformOrigin = "top left";
|
|
2473
2503
|
clone.style.transform = "none";
|
|
2504
|
+
syncDraftPreviewCloneRect(clone, element);
|
|
2505
|
+
}
|
|
2506
|
+
function syncDraftPreviewCloneRect(clone, element) {
|
|
2507
|
+
const rect = element.getBoundingClientRect();
|
|
2508
|
+
clone.style.left = `${toCssNumber(rect.left)}px`;
|
|
2509
|
+
clone.style.top = `${toCssNumber(rect.top)}px`;
|
|
2510
|
+
clone.style.width = `${toCssNumber(rect.width)}px`;
|
|
2511
|
+
clone.style.height = `${toCssNumber(rect.height)}px`;
|
|
2474
2512
|
}
|
|
2475
2513
|
function getDraftPreviewDisplay(display) {
|
|
2476
2514
|
if (display === "inline" || display === "contents") return "inline-block";
|
|
@@ -2546,11 +2584,11 @@ function createStyleElement() {
|
|
|
2546
2584
|
--df-review-color-text: #f7f7f2;
|
|
2547
2585
|
--df-review-color-text-muted: rgba(247, 247, 242, 0.62);
|
|
2548
2586
|
--df-review-color-text-subtle: rgba(247, 247, 242, 0.46);
|
|
2549
|
-
--df-review-color-accent: #
|
|
2587
|
+
--df-review-color-accent: #7cc7ff;
|
|
2550
2588
|
--df-review-color-accent-contrast: #171b1e;
|
|
2551
|
-
--df-review-color-accent-soft: rgba(
|
|
2552
|
-
--df-review-color-accent-ring: rgba(
|
|
2553
|
-
--df-review-color-area: #
|
|
2589
|
+
--df-review-color-accent-soft: rgba(124, 199, 255, 0.16);
|
|
2590
|
+
--df-review-color-accent-ring: rgba(124, 199, 255, 0.6);
|
|
2591
|
+
--df-review-color-area: #7cc7ff;
|
|
2554
2592
|
--df-review-color-error: #ffb7a7;
|
|
2555
2593
|
--df-review-shadow-panel: 0 18px 48px rgba(0, 0, 0, 0.34);
|
|
2556
2594
|
--df-review-shadow-popover: 0 16px 38px rgba(0, 0, 0, 0.32);
|
|
@@ -2736,9 +2774,9 @@ function createStyleElement() {
|
|
|
2736
2774
|
.dfwr-selection-highlight {
|
|
2737
2775
|
position: fixed;
|
|
2738
2776
|
z-index: 1;
|
|
2739
|
-
border: 2px solid #
|
|
2777
|
+
border: 2px solid #7cc7ff;
|
|
2740
2778
|
border-radius: var(--df-review-radius-xs);
|
|
2741
|
-
background: rgba(
|
|
2779
|
+
background: rgba(124, 199, 255, 0.08);
|
|
2742
2780
|
box-shadow:
|
|
2743
2781
|
0 0 0 1px rgba(31, 36, 40, 0.72),
|
|
2744
2782
|
0 0 0 9999px rgba(0, 0, 0, 0.12),
|
|
@@ -2747,8 +2785,8 @@ function createStyleElement() {
|
|
|
2747
2785
|
}
|
|
2748
2786
|
|
|
2749
2787
|
.dfwr-selection-highlight.is-draft {
|
|
2750
|
-
border-color: #
|
|
2751
|
-
background: rgba(
|
|
2788
|
+
border-color: #7cc7ff;
|
|
2789
|
+
background: rgba(124, 199, 255, 0.1);
|
|
2752
2790
|
box-shadow:
|
|
2753
2791
|
0 0 0 1px rgba(31, 36, 40, 0.72),
|
|
2754
2792
|
0 0 0 9999px rgba(0, 0, 0, 0.08),
|
|
@@ -2759,9 +2797,9 @@ function createStyleElement() {
|
|
|
2759
2797
|
.dfwr-dom-hover {
|
|
2760
2798
|
position: fixed;
|
|
2761
2799
|
z-index: 2;
|
|
2762
|
-
border: 1px solid #
|
|
2800
|
+
border: 1px solid #7cc7ff;
|
|
2763
2801
|
border-radius: var(--df-review-radius-xs);
|
|
2764
|
-
background: rgba(
|
|
2802
|
+
background: rgba(124, 199, 255, 0.1);
|
|
2765
2803
|
box-shadow:
|
|
2766
2804
|
0 0 0 1px rgba(31, 36, 40, 0.72),
|
|
2767
2805
|
0 0 0 9999px rgba(0, 0, 0, 0.08);
|
|
@@ -2942,12 +2980,12 @@ function createStyleElement() {
|
|
|
2942
2980
|
}
|
|
2943
2981
|
|
|
2944
2982
|
.dfwr-area-preview-layer .dfwr-bound-marker {
|
|
2945
|
-
border-color: #
|
|
2983
|
+
border-color: #7cc7ff;
|
|
2946
2984
|
background: var(--df-review-color-panel);
|
|
2947
2985
|
box-shadow:
|
|
2948
|
-
0 0 0 5px rgba(
|
|
2986
|
+
0 0 0 5px rgba(124, 199, 255, 0.2),
|
|
2949
2987
|
0 12px 26px rgba(0, 0, 0, 0.3);
|
|
2950
|
-
color: #
|
|
2988
|
+
color: #7cc7ff;
|
|
2951
2989
|
}
|
|
2952
2990
|
|
|
2953
2991
|
.dfwr-bound-marker-icon {
|
|
@@ -3030,7 +3068,7 @@ function createStyleElement() {
|
|
|
3030
3068
|
border-radius: var(--df-review-radius-pill);
|
|
3031
3069
|
background: var(--df-review-color-accent);
|
|
3032
3070
|
box-shadow:
|
|
3033
|
-
0 0 0 4px rgba(
|
|
3071
|
+
0 0 0 4px rgba(124, 199, 255, 0.22),
|
|
3034
3072
|
0 8px 18px rgba(0, 0, 0, 0.28);
|
|
3035
3073
|
cursor: grab;
|
|
3036
3074
|
pointer-events: auto;
|
|
@@ -3048,7 +3086,7 @@ function createStyleElement() {
|
|
|
3048
3086
|
pointer-events: auto;
|
|
3049
3087
|
color: var(--df-review-color-text);
|
|
3050
3088
|
background: var(--df-review-color-panel);
|
|
3051
|
-
border: 1px solid rgba(
|
|
3089
|
+
border: 1px solid rgba(124, 199, 255, 0.56);
|
|
3052
3090
|
border-radius: var(--df-review-radius-md);
|
|
3053
3091
|
box-shadow: var(--df-review-shadow-popover);
|
|
3054
3092
|
}
|
|
@@ -3057,7 +3095,7 @@ function createStyleElement() {
|
|
|
3057
3095
|
.dfwr-area-draft.is-composer {
|
|
3058
3096
|
max-height: min(360px, calc(100vh - 32px));
|
|
3059
3097
|
overflow: auto;
|
|
3060
|
-
border-color: rgba(
|
|
3098
|
+
border-color: rgba(124, 199, 255, 0.56);
|
|
3061
3099
|
}
|
|
3062
3100
|
|
|
3063
3101
|
.dfwr-shell.is-docked-composer .dfwr-dom-popover.is-docked-composer,
|
|
@@ -3094,7 +3132,7 @@ function createStyleElement() {
|
|
|
3094
3132
|
|
|
3095
3133
|
.dfwr-draft-drag-handle:hover,
|
|
3096
3134
|
.dfwr-draft-drag-handle:focus-visible {
|
|
3097
|
-
background: rgba(
|
|
3135
|
+
background: rgba(124, 199, 255, 0.62);
|
|
3098
3136
|
}
|
|
3099
3137
|
|
|
3100
3138
|
.dfwr-draft-drag-handle:active {
|
|
@@ -3113,7 +3151,7 @@ function createStyleElement() {
|
|
|
3113
3151
|
pointer-events: auto;
|
|
3114
3152
|
color: var(--df-review-color-text);
|
|
3115
3153
|
background: var(--df-review-color-panel);
|
|
3116
|
-
border: 1px solid rgba(
|
|
3154
|
+
border: 1px solid rgba(124, 199, 255, 0.56);
|
|
3117
3155
|
border-radius: var(--df-review-radius-md);
|
|
3118
3156
|
box-shadow: var(--df-review-shadow-popover);
|
|
3119
3157
|
}
|
|
@@ -3332,7 +3370,7 @@ function createStyleElement() {
|
|
|
3332
3370
|
}
|
|
3333
3371
|
|
|
3334
3372
|
.dfwr-adjust-panel.is-active {
|
|
3335
|
-
border-color: rgba(
|
|
3373
|
+
border-color: rgba(124, 199, 255, 0.5);
|
|
3336
3374
|
background: var(--df-review-color-accent-soft);
|
|
3337
3375
|
}
|
|
3338
3376
|
|
|
@@ -3371,7 +3409,7 @@ function createStyleElement() {
|
|
|
3371
3409
|
.dfwr-adjust-toggle:hover,
|
|
3372
3410
|
.dfwr-adjust-toggle:focus-visible,
|
|
3373
3411
|
.dfwr-adjust-toggle.is-active {
|
|
3374
|
-
border-color: rgba(
|
|
3412
|
+
border-color: rgba(124, 199, 255, 0.68);
|
|
3375
3413
|
background: var(--df-review-color-accent-soft);
|
|
3376
3414
|
outline: none;
|
|
3377
3415
|
}
|
|
@@ -3434,7 +3472,7 @@ function createStyleElement() {
|
|
|
3434
3472
|
}
|
|
3435
3473
|
|
|
3436
3474
|
.dfwr-item:focus-visible {
|
|
3437
|
-
outline: 2px solid rgba(
|
|
3475
|
+
outline: 2px solid rgba(124, 199, 255, 0.72);
|
|
3438
3476
|
outline-offset: 4px;
|
|
3439
3477
|
}
|
|
3440
3478
|
|
|
@@ -3544,8 +3582,8 @@ function createStyleElement() {
|
|
|
3544
3582
|
z-index: 2;
|
|
3545
3583
|
width: 0;
|
|
3546
3584
|
height: 0;
|
|
3547
|
-
border: 1px solid #
|
|
3548
|
-
background: rgba(
|
|
3585
|
+
border: 1px solid #7cc7ff;
|
|
3586
|
+
background: rgba(124, 199, 255, 0.16);
|
|
3549
3587
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.18);
|
|
3550
3588
|
}
|
|
3551
3589
|
|
|
@@ -4622,6 +4660,12 @@ function createDomDraftLayer(context, draft, options = {}) {
|
|
|
4622
4660
|
pin.setAttribute("aria-label", "Move DOM point");
|
|
4623
4661
|
pin.style.left = `${hostPoint.x}px`;
|
|
4624
4662
|
pin.style.top = `${hostPoint.y}px`;
|
|
4663
|
+
if (draft.isSelectionOnly) {
|
|
4664
|
+
pin.classList.add("is-selection-only");
|
|
4665
|
+
pin.tabIndex = -1;
|
|
4666
|
+
group.append(pin);
|
|
4667
|
+
return { layer: group, composer: void 0 };
|
|
4668
|
+
}
|
|
4625
4669
|
const popover = document.createElement("div");
|
|
4626
4670
|
const position = getPopoverPosition(hostPoint, environment);
|
|
4627
4671
|
popover.className = [
|
|
@@ -4744,7 +4788,7 @@ function createDomDraftLayer(context, draft, options = {}) {
|
|
|
4744
4788
|
attachments: currentDraft.attachments
|
|
4745
4789
|
});
|
|
4746
4790
|
};
|
|
4747
|
-
const adjustmentControls = isElementDraft ? createAdjustmentControls(context, {
|
|
4791
|
+
const adjustmentControls = isElementDraft && !options.dockComposer ? createAdjustmentControls(context, {
|
|
4748
4792
|
draft,
|
|
4749
4793
|
pin,
|
|
4750
4794
|
popover,
|
|
@@ -5390,7 +5434,7 @@ var WebReviewKitView = class {
|
|
|
5390
5434
|
this.draftPreview = new DraftPreviewController({
|
|
5391
5435
|
getEnvironment: () => this.config.getEnvironment(),
|
|
5392
5436
|
getMetrics: (draft) => getDraftAdjustmentMetrics(draft, presets()),
|
|
5393
|
-
hasAdjustment: (draft) => hasDraftAdjustment(draft, presets())
|
|
5437
|
+
hasAdjustment: (draft) => draft.adjustment?.preview !== false && hasDraftAdjustment(draft, presets())
|
|
5394
5438
|
});
|
|
5395
5439
|
this.draftContext = {
|
|
5396
5440
|
config: this.config,
|
|
@@ -5411,8 +5455,11 @@ var WebReviewKitView = class {
|
|
|
5411
5455
|
shadow.replaceChildren();
|
|
5412
5456
|
shadow.append(createStyleElement());
|
|
5413
5457
|
shadow.append(hiddenItemsStyle);
|
|
5414
|
-
const
|
|
5415
|
-
const
|
|
5458
|
+
const hasSelectionOnlyDraft = state.domDraft?.isSelectionOnly === true;
|
|
5459
|
+
const hasDismissableDraft = Boolean(
|
|
5460
|
+
state.domDraft && !hasSelectionOnlyDraft || state.areaDraft
|
|
5461
|
+
);
|
|
5462
|
+
const shouldDockComposer = this.config.options.ui?.panel === false && hasDismissableDraft && !hasSelectionOnlyDraft && Boolean(this.getShellComposerHost());
|
|
5416
5463
|
let dockedComposer;
|
|
5417
5464
|
const shell = document.createElement("div");
|
|
5418
5465
|
shell.className = [
|
|
@@ -5534,6 +5581,7 @@ var WebReviewKitView = class {
|
|
|
5534
5581
|
|
|
5535
5582
|
// src/core/web.review.kit.app.ts
|
|
5536
5583
|
var ROOT_ID = "df-web-review-kit-root";
|
|
5584
|
+
var VIEWPORT_SCROLL_OPTIONS = { capture: true, passive: true };
|
|
5537
5585
|
function isEditableEventTarget(event) {
|
|
5538
5586
|
const path = event.composedPath?.() ?? [];
|
|
5539
5587
|
const element = path[0] ?? event.target;
|
|
@@ -5553,6 +5601,8 @@ function createWebReviewKit(options) {
|
|
|
5553
5601
|
toggle: () => app.toggle(),
|
|
5554
5602
|
setMode: (mode) => app.setMode(mode),
|
|
5555
5603
|
startElementReview: (element, comment) => app.startElementReview(element, comment),
|
|
5604
|
+
selectElement: (element) => app.selectElement(element),
|
|
5605
|
+
adjustElementSelection: (delta, adjustmentOptions) => app.adjustElementSelection(delta, adjustmentOptions),
|
|
5556
5606
|
getMode: () => app.getMode(),
|
|
5557
5607
|
highlightItem: (itemId) => app.highlightItem(itemId),
|
|
5558
5608
|
setHiddenItemIds: (itemIds) => app.setHiddenItemIds(itemIds),
|
|
@@ -5573,6 +5623,12 @@ var WebReviewKitApp = class {
|
|
|
5573
5623
|
this.isSelectingArea = false;
|
|
5574
5624
|
this.handleKeyDown = (event) => {
|
|
5575
5625
|
if (event.key === "Escape" && this.cancelMode()) {
|
|
5626
|
+
const activeElement = document.activeElement;
|
|
5627
|
+
if (activeElement instanceof HTMLButtonElement && activeElement.matches(
|
|
5628
|
+
".df-review-mode-button, .df-review-section-outline-link.is-dom-select"
|
|
5629
|
+
)) {
|
|
5630
|
+
activeElement.blur();
|
|
5631
|
+
}
|
|
5576
5632
|
event.preventDefault();
|
|
5577
5633
|
event.stopPropagation();
|
|
5578
5634
|
return;
|
|
@@ -5587,6 +5643,7 @@ var WebReviewKitApp = class {
|
|
|
5587
5643
|
this.renderFrame = window.requestAnimationFrame(() => {
|
|
5588
5644
|
this.renderFrame = void 0;
|
|
5589
5645
|
if (this.isDraftComposerFocused()) return;
|
|
5646
|
+
this.syncDomDraftViewportGeometry();
|
|
5590
5647
|
this.render();
|
|
5591
5648
|
});
|
|
5592
5649
|
};
|
|
@@ -5644,16 +5701,48 @@ var WebReviewKitApp = class {
|
|
|
5644
5701
|
this.shadow = this.root.attachShadow({ mode: "open" });
|
|
5645
5702
|
document.body.appendChild(this.root);
|
|
5646
5703
|
document.addEventListener("keydown", this.handleKeyDown, true);
|
|
5647
|
-
window.addEventListener(
|
|
5704
|
+
window.addEventListener(
|
|
5705
|
+
"scroll",
|
|
5706
|
+
this.handleViewportChange,
|
|
5707
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
5708
|
+
);
|
|
5648
5709
|
window.addEventListener("resize", this.handleViewportChange);
|
|
5710
|
+
this.targetViewportWindow = this.getEnvironment()?.window;
|
|
5711
|
+
if (this.targetViewportWindow && this.targetViewportWindow !== window) {
|
|
5712
|
+
this.targetViewportWindow.addEventListener(
|
|
5713
|
+
"scroll",
|
|
5714
|
+
this.handleViewportChange,
|
|
5715
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
5716
|
+
);
|
|
5717
|
+
this.targetViewportWindow.addEventListener(
|
|
5718
|
+
"resize",
|
|
5719
|
+
this.handleViewportChange
|
|
5720
|
+
);
|
|
5721
|
+
}
|
|
5649
5722
|
this.render();
|
|
5650
5723
|
}
|
|
5651
5724
|
destroy() {
|
|
5652
5725
|
this.view.clearDraftPreview();
|
|
5653
5726
|
this.clearDrafts();
|
|
5654
5727
|
document.removeEventListener("keydown", this.handleKeyDown, true);
|
|
5655
|
-
window.removeEventListener(
|
|
5728
|
+
window.removeEventListener(
|
|
5729
|
+
"scroll",
|
|
5730
|
+
this.handleViewportChange,
|
|
5731
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
5732
|
+
);
|
|
5656
5733
|
window.removeEventListener("resize", this.handleViewportChange);
|
|
5734
|
+
if (this.targetViewportWindow && this.targetViewportWindow !== window) {
|
|
5735
|
+
this.targetViewportWindow.removeEventListener(
|
|
5736
|
+
"scroll",
|
|
5737
|
+
this.handleViewportChange,
|
|
5738
|
+
VIEWPORT_SCROLL_OPTIONS
|
|
5739
|
+
);
|
|
5740
|
+
this.targetViewportWindow.removeEventListener(
|
|
5741
|
+
"resize",
|
|
5742
|
+
this.handleViewportChange
|
|
5743
|
+
);
|
|
5744
|
+
}
|
|
5745
|
+
this.targetViewportWindow = void 0;
|
|
5657
5746
|
if (this.renderFrame) {
|
|
5658
5747
|
window.cancelAnimationFrame(this.renderFrame);
|
|
5659
5748
|
this.renderFrame = void 0;
|
|
@@ -5698,6 +5787,33 @@ var WebReviewKitApp = class {
|
|
|
5698
5787
|
this.isSelectingArea = false;
|
|
5699
5788
|
await this.bindElementDraftToElement(element, { comment });
|
|
5700
5789
|
}
|
|
5790
|
+
async selectElement(element) {
|
|
5791
|
+
if (!this.isOpen) {
|
|
5792
|
+
this.isOpen = true;
|
|
5793
|
+
}
|
|
5794
|
+
this.setModeState("element");
|
|
5795
|
+
this.clearDrafts();
|
|
5796
|
+
this.isSelectingArea = false;
|
|
5797
|
+
await this.bindElementDraftToElement(element, {
|
|
5798
|
+
isSelectionOnly: true
|
|
5799
|
+
});
|
|
5800
|
+
}
|
|
5801
|
+
adjustElementSelection(delta, options) {
|
|
5802
|
+
if (!this.domDraft?.selection) return false;
|
|
5803
|
+
const current = this.domDraft.adjustment;
|
|
5804
|
+
this.domDraft = {
|
|
5805
|
+
...this.domDraft,
|
|
5806
|
+
adjustment: {
|
|
5807
|
+
x: (current?.x ?? 0) + (delta.x ?? 0),
|
|
5808
|
+
y: (current?.y ?? 0) + (delta.y ?? 0),
|
|
5809
|
+
scale: (current?.scale ?? 0) + (delta.scale ?? 0),
|
|
5810
|
+
isActive: true,
|
|
5811
|
+
preview: options?.preview ?? current?.preview
|
|
5812
|
+
}
|
|
5813
|
+
};
|
|
5814
|
+
this.render();
|
|
5815
|
+
return true;
|
|
5816
|
+
}
|
|
5701
5817
|
getMode() {
|
|
5702
5818
|
return this.mode;
|
|
5703
5819
|
}
|
|
@@ -5777,6 +5893,33 @@ var WebReviewKitApp = class {
|
|
|
5777
5893
|
this.render();
|
|
5778
5894
|
return true;
|
|
5779
5895
|
}
|
|
5896
|
+
syncDomDraftViewportGeometry() {
|
|
5897
|
+
const draft = this.domDraft;
|
|
5898
|
+
const element = draft?.previewElement;
|
|
5899
|
+
const environment = this.getEnvironment();
|
|
5900
|
+
if (!draft?.selection || !element?.isConnected || !environment || element.ownerDocument !== environment.document) {
|
|
5901
|
+
return;
|
|
5902
|
+
}
|
|
5903
|
+
const rect = element.getBoundingClientRect();
|
|
5904
|
+
if (rect.width <= 0 || rect.height <= 0) return;
|
|
5905
|
+
const selection = {
|
|
5906
|
+
left: rect.left,
|
|
5907
|
+
top: rect.top,
|
|
5908
|
+
width: rect.width,
|
|
5909
|
+
height: rect.height
|
|
5910
|
+
};
|
|
5911
|
+
this.domDraft = {
|
|
5912
|
+
...draft,
|
|
5913
|
+
marker: {
|
|
5914
|
+
...draft.marker,
|
|
5915
|
+
viewport: roundPoint({ x: rect.left, y: rect.top })
|
|
5916
|
+
},
|
|
5917
|
+
selection: {
|
|
5918
|
+
...draft.selection,
|
|
5919
|
+
viewport: toPublicSelection(selection)
|
|
5920
|
+
}
|
|
5921
|
+
};
|
|
5922
|
+
}
|
|
5780
5923
|
isDraftComposerFocused() {
|
|
5781
5924
|
if (!this.domDraft && !this.areaDraft) return false;
|
|
5782
5925
|
const composerHost = this.getEnvironment()?.composerHost;
|
|
@@ -6248,6 +6391,11 @@ function createNoopController() {
|
|
|
6248
6391
|
},
|
|
6249
6392
|
async startElementReview() {
|
|
6250
6393
|
},
|
|
6394
|
+
async selectElement() {
|
|
6395
|
+
},
|
|
6396
|
+
adjustElementSelection() {
|
|
6397
|
+
return false;
|
|
6398
|
+
},
|
|
6251
6399
|
getMode() {
|
|
6252
6400
|
return "idle";
|
|
6253
6401
|
},
|