@puckeditor/plugin-ai 0.9.0-canary.d8bdabee → 0.9.0-canary.f2867fd7
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/dist/index.js +623 -411
- package/dist/index.mjs +607 -395
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -995,7 +995,7 @@ function useChat({
|
|
|
995
995
|
// src/components/Chat/index.tsx
|
|
996
996
|
var import_core5 = require("@puckeditor/core");
|
|
997
997
|
var import_ai5 = require("ai");
|
|
998
|
-
var
|
|
998
|
+
var import_react27 = require("react");
|
|
999
999
|
var import_ulid = require("ulid");
|
|
1000
1000
|
|
|
1001
1001
|
// ../utils/lib/get-class-name-factory.ts
|
|
@@ -1814,6 +1814,42 @@ var matchesAccept = (file, accept) => {
|
|
|
1814
1814
|
return file.type === entry;
|
|
1815
1815
|
});
|
|
1816
1816
|
};
|
|
1817
|
+
var documentExtensionByMediaType = {
|
|
1818
|
+
"application/msword": "doc",
|
|
1819
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
1820
|
+
"text/markdown": "md",
|
|
1821
|
+
"application/pdf": "pdf",
|
|
1822
|
+
"text/plain": "txt"
|
|
1823
|
+
};
|
|
1824
|
+
var mediaTypeToExtension = (mediaType) => {
|
|
1825
|
+
const mapped = documentExtensionByMediaType[mediaType];
|
|
1826
|
+
if (mapped) {
|
|
1827
|
+
return mapped;
|
|
1828
|
+
}
|
|
1829
|
+
const subtype = mediaType.split("/")[1] ?? "";
|
|
1830
|
+
return subtype.split("+")[0] || "bin";
|
|
1831
|
+
};
|
|
1832
|
+
var getFilesFromClipboard = (data) => {
|
|
1833
|
+
const files = [];
|
|
1834
|
+
for (const item of data.items ? Array.from(data.items) : []) {
|
|
1835
|
+
if (item.kind === "file") {
|
|
1836
|
+
const file = item.getAsFile();
|
|
1837
|
+
if (file) {
|
|
1838
|
+
files.push(file);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
if (files.length === 0 && data.files) {
|
|
1843
|
+
files.push(...Array.from(data.files));
|
|
1844
|
+
}
|
|
1845
|
+
return files.map(
|
|
1846
|
+
(file, index) => file.name ? file : new File(
|
|
1847
|
+
[file],
|
|
1848
|
+
`pasted-${Date.now()}-${index}.${mediaTypeToExtension(file.type)}`,
|
|
1849
|
+
{ type: file.type }
|
|
1850
|
+
)
|
|
1851
|
+
);
|
|
1852
|
+
};
|
|
1817
1853
|
var getAttachmentIdFromRef = (url) => url.startsWith("attachment://") ? url.slice("attachment://".length) : null;
|
|
1818
1854
|
var resolveAttachmentUrl = (url, attachmentEndpoint) => {
|
|
1819
1855
|
if (!attachmentEndpoint) {
|
|
@@ -1896,6 +1932,16 @@ function PromptForm({
|
|
|
1896
1932
|
},
|
|
1897
1933
|
[canDrop, onFileDrop]
|
|
1898
1934
|
);
|
|
1935
|
+
const handlePaste = (0, import_react19.useCallback)(
|
|
1936
|
+
(e) => {
|
|
1937
|
+
if (!canDrop) return;
|
|
1938
|
+
const files = getFilesFromClipboard(e.clipboardData);
|
|
1939
|
+
if (files.length === 0) return;
|
|
1940
|
+
e.preventDefault();
|
|
1941
|
+
onFileDrop(files);
|
|
1942
|
+
},
|
|
1943
|
+
[canDrop, onFileDrop]
|
|
1944
|
+
);
|
|
1899
1945
|
(0, import_react19.useEffect)(() => {
|
|
1900
1946
|
setPrompt(value);
|
|
1901
1947
|
}, [setPrompt, value]);
|
|
@@ -1997,6 +2043,7 @@ function PromptForm({
|
|
|
1997
2043
|
internalRef.current = node;
|
|
1998
2044
|
},
|
|
1999
2045
|
onChange: (e) => setPrompt(e.target.value),
|
|
2046
|
+
onPaste: onFileDrop ? handlePaste : void 0,
|
|
2000
2047
|
onKeyDown: (e) => {
|
|
2001
2048
|
if (!e.shiftKey && e.key === "Enter") {
|
|
2002
2049
|
e.preventDefault();
|
|
@@ -2490,7 +2537,6 @@ function ExamplePrompt({
|
|
|
2490
2537
|
// src/components/Chat/index.tsx
|
|
2491
2538
|
var import_qler = __toESM(require("qler"));
|
|
2492
2539
|
var import_reducer = __toESM(require_dist());
|
|
2493
|
-
var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
|
|
2494
2540
|
var import_use_debounce = require("use-debounce");
|
|
2495
2541
|
|
|
2496
2542
|
// src/lib/scroll-tracking-events.ts
|
|
@@ -2546,151 +2592,20 @@ var import_core4 = require("@puckeditor/core");
|
|
|
2546
2592
|
// src/lib/design/component.tsx
|
|
2547
2593
|
init_react_import();
|
|
2548
2594
|
var import_core3 = require("@puckeditor/core");
|
|
2549
|
-
var
|
|
2595
|
+
var import_react24 = require("react");
|
|
2550
2596
|
|
|
2551
2597
|
// src/lib/morph-html.ts
|
|
2552
2598
|
init_react_import();
|
|
2553
|
-
var PROTECTED_ATTRS = /* @__PURE__ */ new Set([
|
|
2554
|
-
"contenteditable",
|
|
2555
|
-
"data-puck-overlay-portal"
|
|
2556
|
-
]);
|
|
2557
|
-
var SLOT_OWNED_ATTRS = /* @__PURE__ */ new Set(["style", "class"]);
|
|
2558
|
-
var isEventHandlerAttr = (name) => /^on/i.test(name);
|
|
2559
|
-
var cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
|
|
2560
|
-
var FIELD_ATTR_PREFIX = "data-puck-field-";
|
|
2561
|
-
var hasJsonFieldBinding = (el) => {
|
|
2562
|
-
const attrBoundNames = /* @__PURE__ */ new Set();
|
|
2563
|
-
const jsonFieldNames = [];
|
|
2564
|
-
for (const attr of Array.from(el.attributes)) {
|
|
2565
|
-
if (!attr.name.startsWith(FIELD_ATTR_PREFIX)) continue;
|
|
2566
|
-
if (attr.name.startsWith("data-puck-field-value-")) continue;
|
|
2567
|
-
if (attr.value.trimStart().startsWith("{")) {
|
|
2568
|
-
const fieldName = attr.name.slice(FIELD_ATTR_PREFIX.length);
|
|
2569
|
-
if (fieldName && fieldName !== "name") {
|
|
2570
|
-
jsonFieldNames.push(fieldName);
|
|
2571
|
-
}
|
|
2572
|
-
} else {
|
|
2573
|
-
const fieldName = attr.value.trim();
|
|
2574
|
-
if (fieldName) attrBoundNames.add(fieldName);
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2577
|
-
return jsonFieldNames.some((name) => !attrBoundNames.has(name));
|
|
2578
|
-
};
|
|
2579
|
-
var ownsItsChildren = (el) => el.hasAttribute("data-puck-slot") || el.hasAttribute("data-puck-field-name") || el.hasAttribute("data-puck-array") || hasJsonFieldBinding(el);
|
|
2580
|
-
var syncAttributes = (target, source) => {
|
|
2581
|
-
const isSlot = target.hasAttribute("data-puck-slot");
|
|
2582
|
-
for (const attr of Array.from(target.attributes)) {
|
|
2583
|
-
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
2584
|
-
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
2585
|
-
if (isEventHandlerAttr(attr.name) || !source.hasAttribute(attr.name)) {
|
|
2586
|
-
target.removeAttribute(attr.name);
|
|
2587
|
-
}
|
|
2588
|
-
}
|
|
2589
|
-
for (const attr of Array.from(source.attributes)) {
|
|
2590
|
-
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
2591
|
-
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
2592
|
-
if (isEventHandlerAttr(attr.name)) continue;
|
|
2593
|
-
if (target.getAttribute(attr.name) !== attr.value) {
|
|
2594
|
-
target.setAttribute(attr.name, attr.value);
|
|
2595
|
-
}
|
|
2596
|
-
}
|
|
2597
|
-
};
|
|
2598
|
-
var isSameKind = (a, b) => a.nodeType === b.nodeType && (a.nodeType !== Node.ELEMENT_NODE || a.tagName === b.tagName);
|
|
2599
|
-
var isIncompleteTagArtifact = (node) => node.nodeType === Node.TEXT_NODE && /^<\/?[a-zA-Z]*$/.test(node.nodeValue ?? "");
|
|
2600
|
-
var stripIncompleteTagArtifacts = (root) => {
|
|
2601
|
-
for (const child of Array.from(root.childNodes)) {
|
|
2602
|
-
if (isIncompleteTagArtifact(child)) {
|
|
2603
|
-
root.removeChild(child);
|
|
2604
|
-
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
2605
|
-
stripIncompleteTagArtifacts(child);
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
};
|
|
2609
|
-
var stripEventHandlerAttrs = (root) => {
|
|
2610
|
-
root.querySelectorAll("*").forEach((el) => {
|
|
2611
|
-
for (const attr of Array.from(el.attributes)) {
|
|
2612
|
-
if (isEventHandlerAttr(attr.name)) el.removeAttribute(attr.name);
|
|
2613
|
-
}
|
|
2614
|
-
});
|
|
2615
|
-
};
|
|
2616
|
-
var morphChildren = (target, source, skipChildrenOf = ownsItsChildren) => {
|
|
2617
|
-
const sourceChildren = Array.from(source.childNodes);
|
|
2618
|
-
for (let i = 0; i < sourceChildren.length; i++) {
|
|
2619
|
-
const sourceChild = sourceChildren[i];
|
|
2620
|
-
const targetChild = target.childNodes[i];
|
|
2621
|
-
if (!targetChild) {
|
|
2622
|
-
target.appendChild(sourceChild);
|
|
2623
|
-
continue;
|
|
2624
|
-
}
|
|
2625
|
-
if (!isSameKind(targetChild, sourceChild)) {
|
|
2626
|
-
target.replaceChild(sourceChild, targetChild);
|
|
2627
|
-
continue;
|
|
2628
|
-
}
|
|
2629
|
-
if (sourceChild.nodeType !== Node.ELEMENT_NODE) {
|
|
2630
|
-
if (targetChild.nodeValue !== sourceChild.nodeValue) {
|
|
2631
|
-
targetChild.nodeValue = sourceChild.nodeValue;
|
|
2632
|
-
}
|
|
2633
|
-
continue;
|
|
2634
|
-
}
|
|
2635
|
-
const targetEl = targetChild;
|
|
2636
|
-
syncAttributes(targetEl, sourceChild);
|
|
2637
|
-
if (!skipChildrenOf(targetEl)) {
|
|
2638
|
-
morphChildren(targetEl, sourceChild, skipChildrenOf);
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
while (target.childNodes.length > sourceChildren.length) {
|
|
2642
|
-
target.removeChild(target.lastChild);
|
|
2643
|
-
}
|
|
2644
|
-
};
|
|
2645
|
-
function morphHtml(container, html, attrOverrides = [], skipChildrenOf = ownsItsChildren) {
|
|
2646
|
-
const template = container.ownerDocument.createElement("template");
|
|
2647
|
-
template.innerHTML = html;
|
|
2648
|
-
stripIncompleteTagArtifacts(template.content);
|
|
2649
|
-
stripEventHandlerAttrs(template.content);
|
|
2650
|
-
for (const { name, attr, value } of attrOverrides) {
|
|
2651
|
-
template.content.querySelectorAll(`[data-puck-field-${attr}="${cssEscape(name)}"]`).forEach((el) => {
|
|
2652
|
-
if (el.closest("[data-puck-array]")) return;
|
|
2653
|
-
el.setAttribute(attr, value);
|
|
2654
|
-
});
|
|
2655
|
-
}
|
|
2656
|
-
morphChildren(container, template.content, skipChildrenOf);
|
|
2657
|
-
}
|
|
2658
2599
|
|
|
2659
|
-
// src/lib/design/
|
|
2600
|
+
// src/lib/design/annotations.ts
|
|
2660
2601
|
init_react_import();
|
|
2661
|
-
var wrapScriptWithObserverGuard = (script) => {
|
|
2662
|
-
if (!script.includes("MutationObserver")) return script;
|
|
2663
|
-
return `(function () {
|
|
2664
|
-
var __NativeMutationObserver = window.MutationObserver;
|
|
2665
|
-
function MutationObserver(callback) {
|
|
2666
|
-
var observed = [];
|
|
2667
|
-
var inner = new __NativeMutationObserver(function (records) {
|
|
2668
|
-
inner.disconnect();
|
|
2669
|
-
try {
|
|
2670
|
-
callback(records, inner);
|
|
2671
|
-
} finally {
|
|
2672
|
-
for (var i = 0; i < observed.length; i++) {
|
|
2673
|
-
__nativeObserve.call(inner, observed[i][0], observed[i][1]);
|
|
2674
|
-
}
|
|
2675
|
-
}
|
|
2676
|
-
});
|
|
2677
|
-
var __nativeObserve = inner.observe;
|
|
2678
|
-
inner.observe = function (target, options) {
|
|
2679
|
-
observed.push([target, options]);
|
|
2680
|
-
return __nativeObserve.call(inner, target, options);
|
|
2681
|
-
};
|
|
2682
|
-
return inner;
|
|
2683
|
-
}
|
|
2684
|
-
${script}
|
|
2685
|
-
})();`;
|
|
2686
|
-
};
|
|
2687
2602
|
|
|
2688
2603
|
// src/lib/html-annotations.ts
|
|
2689
2604
|
init_react_import();
|
|
2690
2605
|
var import_htmlparser2 = require("htmlparser2");
|
|
2691
2606
|
var import_domutils = require("domutils");
|
|
2692
2607
|
var import_domhandler = require("domhandler");
|
|
2693
|
-
var
|
|
2608
|
+
var FIELD_ATTR_PREFIX = "data-puck-field-";
|
|
2694
2609
|
var OPTIONS_ATTR_PREFIX = "data-puck-options-";
|
|
2695
2610
|
var BIND_ATTR_PREFIX = "data-puck-bind-";
|
|
2696
2611
|
var BIND_INPUT_ATTR_PREFIX = "data-puck-bind-input-";
|
|
@@ -2700,26 +2615,21 @@ var MAX_ATTR_PREFIX = "data-puck-max-";
|
|
|
2700
2615
|
var STEP_ATTR_PREFIX = "data-puck-step-";
|
|
2701
2616
|
var SLOT_ATTR = "data-puck-slot";
|
|
2702
2617
|
var ARRAY_ATTR = "data-puck-array";
|
|
2703
|
-
var
|
|
2618
|
+
var RECOGNIZED_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
2704
2619
|
"text",
|
|
2705
2620
|
"textarea",
|
|
2706
2621
|
"number",
|
|
2707
2622
|
"richtext",
|
|
2708
2623
|
"radio",
|
|
2709
2624
|
"select",
|
|
2710
|
-
"slot"
|
|
2711
|
-
"array",
|
|
2712
|
-
"object",
|
|
2713
|
-
"external",
|
|
2714
|
-
"custom"
|
|
2625
|
+
"slot"
|
|
2715
2626
|
]);
|
|
2716
|
-
var
|
|
2717
|
-
|
|
2718
|
-
const trimmed = attrValue.trimStart();
|
|
2627
|
+
var tryParseFieldShape = (value) => {
|
|
2628
|
+
const trimmed = value.trimStart();
|
|
2719
2629
|
if (!trimmed.startsWith("{")) return null;
|
|
2720
2630
|
try {
|
|
2721
2631
|
const parsed = JSON.parse(trimmed);
|
|
2722
|
-
if (isRecord(parsed) && typeof parsed.type === "string" && parsed.type) {
|
|
2632
|
+
if (isRecord(parsed) && typeof parsed.type === "string" && RECOGNIZED_FIELD_TYPES.has(parsed.type)) {
|
|
2723
2633
|
return parsed;
|
|
2724
2634
|
}
|
|
2725
2635
|
} catch {
|
|
@@ -2743,6 +2653,19 @@ var textContentWithBreaks = (node) => {
|
|
|
2743
2653
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2744
2654
|
var FIELD_NAME_RE = /^[A-Za-z0-9_]+(?:[-.][A-Za-z0-9_]+)*$/;
|
|
2745
2655
|
var isValidFieldName = (name) => FIELD_NAME_RE.test(name);
|
|
2656
|
+
var isFieldNameClaimed = (name, claimed, includeExact = true) => {
|
|
2657
|
+
for (const entry of claimed) {
|
|
2658
|
+
if (includeExact && entry === name || entry.startsWith(`${name}.`) || name.startsWith(`${entry}.`)) {
|
|
2659
|
+
return true;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
return false;
|
|
2663
|
+
};
|
|
2664
|
+
var attrBoundFieldNames = (attribs) => new Set(
|
|
2665
|
+
Object.entries(attribs).filter(
|
|
2666
|
+
([name, value]) => name.startsWith(FIELD_ATTR_PREFIX) && name !== `${FIELD_ATTR_PREFIX}name` && !name.startsWith(`${FIELD_ATTR_PREFIX}value-`) && !tryParseFieldShape(value)
|
|
2667
|
+
).map(([, value]) => value.trim()).filter(isValidFieldName)
|
|
2668
|
+
);
|
|
2746
2669
|
var getDeepValue = (source, path) => {
|
|
2747
2670
|
if (!path.includes(".")) return source[path];
|
|
2748
2671
|
let current = source;
|
|
@@ -2843,6 +2766,7 @@ var collectElementFields = (element, acc) => {
|
|
|
2843
2766
|
return true;
|
|
2844
2767
|
}
|
|
2845
2768
|
let skipChildren = false;
|
|
2769
|
+
const attrBound = attrBoundFieldNames(attribs);
|
|
2846
2770
|
for (const [attrName, attrValue] of Object.entries(attribs)) {
|
|
2847
2771
|
if (attrName.startsWith(OPTIONS_ATTR_PREFIX)) {
|
|
2848
2772
|
const fieldName = attrName.slice(OPTIONS_ATTR_PREFIX.length);
|
|
@@ -2871,8 +2795,8 @@ var collectElementFields = (element, acc) => {
|
|
|
2871
2795
|
}
|
|
2872
2796
|
continue;
|
|
2873
2797
|
}
|
|
2874
|
-
if (!attrName.startsWith(
|
|
2875
|
-
const target = attrName.slice(
|
|
2798
|
+
if (!attrName.startsWith(FIELD_ATTR_PREFIX)) continue;
|
|
2799
|
+
const target = attrName.slice(FIELD_ATTR_PREFIX.length);
|
|
2876
2800
|
if (!target) continue;
|
|
2877
2801
|
const shape = tryParseFieldShape(attrValue);
|
|
2878
2802
|
if (shape) {
|
|
@@ -2886,17 +2810,11 @@ var collectElementFields = (element, acc) => {
|
|
|
2886
2810
|
if (existing) existing.shape = shape;
|
|
2887
2811
|
continue;
|
|
2888
2812
|
}
|
|
2813
|
+
if (isFieldNameClaimed(name2, attrBound, false) || isFieldNameClaimed(name2, acc.seenFields)) {
|
|
2814
|
+
continue;
|
|
2815
|
+
}
|
|
2889
2816
|
acc.seenFields.add(name2);
|
|
2890
|
-
if (
|
|
2891
|
-
const { type, ...value } = shape;
|
|
2892
|
-
acc.fields.push({
|
|
2893
|
-
name: name2,
|
|
2894
|
-
binding: "text",
|
|
2895
|
-
shape: { type },
|
|
2896
|
-
format: "json"
|
|
2897
|
-
});
|
|
2898
|
-
setExtractedValue(acc.values, name2, value);
|
|
2899
|
-
} else if (shape.type === "richtext") {
|
|
2817
|
+
if (shape.type === "richtext") {
|
|
2900
2818
|
acc.fields.push({ name: name2, binding: "text", shape, format: "json" });
|
|
2901
2819
|
setExtractedValue(acc.values, name2, (0, import_domutils.getInnerHTML)(element).trim());
|
|
2902
2820
|
skipChildren = true;
|
|
@@ -2949,6 +2867,9 @@ var collectElementFields = (element, acc) => {
|
|
|
2949
2867
|
}
|
|
2950
2868
|
continue;
|
|
2951
2869
|
}
|
|
2870
|
+
if (target === "name" && isFieldNameClaimed(name, attrBound) || isFieldNameClaimed(name, acc.seenFields)) {
|
|
2871
|
+
continue;
|
|
2872
|
+
}
|
|
2952
2873
|
acc.seenFields.add(name);
|
|
2953
2874
|
const fieldType = getTypeModifier(attribs, name);
|
|
2954
2875
|
const constraints = fieldType === "number" ? getNumberConstraints(attribs, name) : {};
|
|
@@ -3042,7 +2963,7 @@ var parseHtmlAnnotations = (html) => {
|
|
|
3042
2963
|
if (slotName && isValidFieldName(slotName) && !seenSlots.has(slotName)) {
|
|
3043
2964
|
seenSlots.add(slotName);
|
|
3044
2965
|
const shape = tryParseFieldShape(
|
|
3045
|
-
attribs[
|
|
2966
|
+
attribs[FIELD_ATTR_PREFIX + slotName.toLowerCase()] ?? ""
|
|
3046
2967
|
);
|
|
3047
2968
|
const allow = shape?.type === "slot" ? sanitizeStringArray(shape.allow) : void 0;
|
|
3048
2969
|
const disallow = shape?.type === "slot" ? sanitizeStringArray(shape.disallow) : void 0;
|
|
@@ -3191,21 +3112,16 @@ var patchElement = (element, props) => {
|
|
|
3191
3112
|
}
|
|
3192
3113
|
return { didPatch, skipChildren: true };
|
|
3193
3114
|
}
|
|
3194
|
-
const attrBoundFields =
|
|
3195
|
-
for (const [an, av] of Object.entries(attribs)) {
|
|
3196
|
-
if (an.startsWith(FIELD_ATTR_PREFIX2) && an !== `${FIELD_ATTR_PREFIX2}name` && !tryParseFieldShape(av)) {
|
|
3197
|
-
attrBoundFields.add(av.trim());
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3115
|
+
const attrBoundFields = attrBoundFieldNames(attribs);
|
|
3200
3116
|
for (const [attrName, attrValue] of Object.entries(attribs)) {
|
|
3201
|
-
if (!attrName.startsWith(
|
|
3202
|
-
const target = attrName.slice(
|
|
3117
|
+
if (!attrName.startsWith(FIELD_ATTR_PREFIX)) continue;
|
|
3118
|
+
const target = attrName.slice(FIELD_ATTR_PREFIX.length);
|
|
3203
3119
|
if (!target) continue;
|
|
3204
3120
|
const shape = tryParseFieldShape(attrValue);
|
|
3205
3121
|
if (shape) {
|
|
3206
3122
|
if (shape.type === "slot") continue;
|
|
3207
3123
|
const name2 = target;
|
|
3208
|
-
if (
|
|
3124
|
+
if (isFieldNameClaimed(name2, attrBoundFields)) continue;
|
|
3209
3125
|
const value2 = getDeepValue(props, name2);
|
|
3210
3126
|
if (shape.type === "richtext") {
|
|
3211
3127
|
if (typeof value2 !== "string") continue;
|
|
@@ -3223,6 +3139,9 @@ var patchElement = (element, props) => {
|
|
|
3223
3139
|
}
|
|
3224
3140
|
const name = attrValue.trim();
|
|
3225
3141
|
if (!name) continue;
|
|
3142
|
+
if (target === "name" && isFieldNameClaimed(name, attrBoundFields)) {
|
|
3143
|
+
continue;
|
|
3144
|
+
}
|
|
3226
3145
|
const value = getDeepValue(props, name);
|
|
3227
3146
|
if (target === "name" && getTypeModifier(attribs, name) === "richtext") {
|
|
3228
3147
|
if (typeof value !== "string") continue;
|
|
@@ -3295,7 +3214,6 @@ var renderHtmlArrayItems = (html, arrayName, items) => {
|
|
|
3295
3214
|
};
|
|
3296
3215
|
|
|
3297
3216
|
// src/lib/design/annotations.ts
|
|
3298
|
-
init_react_import();
|
|
3299
3217
|
var cache = /* @__PURE__ */ new Map();
|
|
3300
3218
|
var MAX_CACHE_ENTRIES = 32;
|
|
3301
3219
|
var getAnnotations = (html) => {
|
|
@@ -3311,22 +3229,159 @@ var getAnnotations = (html) => {
|
|
|
3311
3229
|
var getSlotFields = (html) => Object.fromEntries(
|
|
3312
3230
|
getAnnotations(html).slots.map((slot) => [slot.name, toSlotField(slot)])
|
|
3313
3231
|
);
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3232
|
+
|
|
3233
|
+
// src/lib/morph-html.ts
|
|
3234
|
+
var PROTECTED_ATTRS = /* @__PURE__ */ new Set([
|
|
3235
|
+
"contenteditable",
|
|
3236
|
+
"data-puck-overlay-portal"
|
|
3237
|
+
]);
|
|
3238
|
+
var SLOT_OWNED_ATTRS = /* @__PURE__ */ new Set(["style", "class"]);
|
|
3239
|
+
var isEventHandlerAttr = (name) => /^on/i.test(name);
|
|
3240
|
+
var FIELD_ATTR_PREFIX2 = "data-puck-field-";
|
|
3241
|
+
var LEGACY_TEXT_ATTR = `${FIELD_ATTR_PREFIX2}name`;
|
|
3242
|
+
var VALUE_ATTR_PREFIX = `${FIELD_ATTR_PREFIX2}value-`;
|
|
3243
|
+
var hasTextBinding = (el, parsedTextFields) => {
|
|
3244
|
+
for (const attr of Array.from(el.attributes)) {
|
|
3245
|
+
if (!attr.name.startsWith(FIELD_ATTR_PREFIX2)) continue;
|
|
3246
|
+
if (attr.name.startsWith(VALUE_ATTR_PREFIX)) continue;
|
|
3247
|
+
const isShape = attr.value.trimStart().startsWith("{");
|
|
3248
|
+
const fieldName = isShape ? attr.name.slice(FIELD_ATTR_PREFIX2.length) : attr.value.trim();
|
|
3249
|
+
if (isValidFieldName(fieldName) && (attr.name === LEGACY_TEXT_ATTR || isShape) && (!parsedTextFields || parsedTextFields.has(fieldName))) {
|
|
3250
|
+
return true;
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
return false;
|
|
3320
3254
|
};
|
|
3321
|
-
var
|
|
3322
|
-
|
|
3323
|
-
const
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3255
|
+
var ownsItsChildren = (el, parsedTextFields) => el.hasAttribute("data-puck-slot") || el.hasAttribute("data-puck-array") || hasTextBinding(el, parsedTextFields);
|
|
3256
|
+
var syncAttributes = (target, source) => {
|
|
3257
|
+
const isSlot = target.hasAttribute("data-puck-slot");
|
|
3258
|
+
for (const attr of Array.from(target.attributes)) {
|
|
3259
|
+
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
3260
|
+
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
3261
|
+
if (isEventHandlerAttr(attr.name) || !source.hasAttribute(attr.name)) {
|
|
3262
|
+
target.removeAttribute(attr.name);
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
for (const attr of Array.from(source.attributes)) {
|
|
3266
|
+
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
3267
|
+
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
3268
|
+
if (isEventHandlerAttr(attr.name)) continue;
|
|
3269
|
+
if (target.getAttribute(attr.name) !== attr.value) {
|
|
3270
|
+
target.setAttribute(attr.name, attr.value);
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
};
|
|
3274
|
+
var isSameKind = (a, b) => a.nodeType === b.nodeType && (a.nodeType !== Node.ELEMENT_NODE || a.tagName === b.tagName);
|
|
3275
|
+
var isIncompleteTagArtifact = (node) => node.nodeType === Node.TEXT_NODE && /^<\/?[a-zA-Z]*$/.test(node.nodeValue ?? "");
|
|
3276
|
+
var stripIncompleteTagArtifacts = (root) => {
|
|
3277
|
+
for (const child of Array.from(root.childNodes)) {
|
|
3278
|
+
if (isIncompleteTagArtifact(child)) {
|
|
3279
|
+
root.removeChild(child);
|
|
3280
|
+
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
3281
|
+
stripIncompleteTagArtifacts(child);
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
};
|
|
3285
|
+
var stripEventHandlerAttrs = (root) => {
|
|
3286
|
+
root.querySelectorAll("*").forEach((el) => {
|
|
3287
|
+
for (const attr of Array.from(el.attributes)) {
|
|
3288
|
+
if (isEventHandlerAttr(attr.name)) el.removeAttribute(attr.name);
|
|
3289
|
+
}
|
|
3290
|
+
});
|
|
3291
|
+
};
|
|
3292
|
+
var morphChildren = (target, source, skipChildrenOf = ownsItsChildren) => {
|
|
3293
|
+
const sourceChildren = Array.from(source.childNodes);
|
|
3294
|
+
for (let i = 0; i < sourceChildren.length; i++) {
|
|
3295
|
+
const sourceChild = sourceChildren[i];
|
|
3296
|
+
const targetChild = target.childNodes[i];
|
|
3297
|
+
if (!targetChild) {
|
|
3298
|
+
target.appendChild(sourceChild);
|
|
3299
|
+
continue;
|
|
3300
|
+
}
|
|
3301
|
+
if (!isSameKind(targetChild, sourceChild)) {
|
|
3302
|
+
target.replaceChild(sourceChild, targetChild);
|
|
3303
|
+
continue;
|
|
3304
|
+
}
|
|
3305
|
+
if (sourceChild.nodeType !== Node.ELEMENT_NODE) {
|
|
3306
|
+
if (targetChild.nodeValue !== sourceChild.nodeValue) {
|
|
3307
|
+
targetChild.nodeValue = sourceChild.nodeValue;
|
|
3308
|
+
}
|
|
3309
|
+
continue;
|
|
3310
|
+
}
|
|
3311
|
+
const targetEl = targetChild;
|
|
3312
|
+
syncAttributes(targetEl, sourceChild);
|
|
3313
|
+
if (!skipChildrenOf(targetEl)) {
|
|
3314
|
+
morphChildren(targetEl, sourceChild, skipChildrenOf);
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
while (target.childNodes.length > sourceChildren.length) {
|
|
3318
|
+
target.removeChild(target.lastChild);
|
|
3319
|
+
}
|
|
3320
|
+
};
|
|
3321
|
+
function morphHtml(container, html, attrOverrides = [], skipChildrenOf) {
|
|
3322
|
+
const template = container.ownerDocument.createElement("template");
|
|
3323
|
+
template.innerHTML = html;
|
|
3324
|
+
stripIncompleteTagArtifacts(template.content);
|
|
3325
|
+
stripEventHandlerAttrs(template.content);
|
|
3326
|
+
if (attrOverrides.length > 0) {
|
|
3327
|
+
const overridesByAttr = /* @__PURE__ */ new Map();
|
|
3328
|
+
for (const override of attrOverrides) {
|
|
3329
|
+
if (isEventHandlerAttr(override.attr)) continue;
|
|
3330
|
+
const bindingAttr = `${FIELD_ATTR_PREFIX2}${override.attr}`;
|
|
3331
|
+
const fields = overridesByAttr.get(bindingAttr) ?? /* @__PURE__ */ new Map();
|
|
3332
|
+
fields.set(override.name, override);
|
|
3333
|
+
overridesByAttr.set(bindingAttr, fields);
|
|
3334
|
+
}
|
|
3335
|
+
template.content.querySelectorAll("*").forEach((el) => {
|
|
3336
|
+
for (const attr of Array.from(el.attributes)) {
|
|
3337
|
+
const override = overridesByAttr.get(attr.name)?.get(attr.value.trim());
|
|
3338
|
+
if (!override) continue;
|
|
3339
|
+
if (el.closest("[data-puck-array]")) return;
|
|
3340
|
+
el.setAttribute(override.attr, override.value);
|
|
3341
|
+
}
|
|
3342
|
+
});
|
|
3343
|
+
}
|
|
3344
|
+
if (skipChildrenOf) {
|
|
3345
|
+
morphChildren(container, template.content, skipChildrenOf);
|
|
3346
|
+
return;
|
|
3347
|
+
}
|
|
3348
|
+
const parsedTextFields = new Set(
|
|
3349
|
+
getAnnotations(html).fields.filter((field) => field.binding === "text").map((field) => field.name)
|
|
3350
|
+
);
|
|
3351
|
+
morphChildren(
|
|
3352
|
+
container,
|
|
3353
|
+
template.content,
|
|
3354
|
+
(el) => ownsItsChildren(el, parsedTextFields)
|
|
3329
3355
|
);
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
// src/lib/design/observer-guard.ts
|
|
3359
|
+
init_react_import();
|
|
3360
|
+
var wrapScriptWithObserverGuard = (script) => {
|
|
3361
|
+
if (!script.includes("MutationObserver")) return script;
|
|
3362
|
+
return `(function () {
|
|
3363
|
+
var __NativeMutationObserver = window.MutationObserver;
|
|
3364
|
+
function MutationObserver(callback) {
|
|
3365
|
+
var observed = [];
|
|
3366
|
+
var inner = new __NativeMutationObserver(function (records) {
|
|
3367
|
+
inner.disconnect();
|
|
3368
|
+
try {
|
|
3369
|
+
callback(records, inner);
|
|
3370
|
+
} finally {
|
|
3371
|
+
for (var i = 0; i < observed.length; i++) {
|
|
3372
|
+
__nativeObserve.call(inner, observed[i][0], observed[i][1]);
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
});
|
|
3376
|
+
var __nativeObserve = inner.observe;
|
|
3377
|
+
inner.observe = function (target, options) {
|
|
3378
|
+
observed.push([target, options]);
|
|
3379
|
+
return __nativeObserve.call(inner, target, options);
|
|
3380
|
+
};
|
|
3381
|
+
return inner;
|
|
3382
|
+
}
|
|
3383
|
+
${script}
|
|
3384
|
+
})();`;
|
|
3330
3385
|
};
|
|
3331
3386
|
|
|
3332
3387
|
// src/lib/design/registration-store.ts
|
|
@@ -3402,7 +3457,7 @@ init_react_import();
|
|
|
3402
3457
|
var import_core2 = require("@puckeditor/core");
|
|
3403
3458
|
var CONTENT_EDITABLE_ATTR = "data-puck-content-editable";
|
|
3404
3459
|
var isInlineEditingDisabled = (el) => el.closest(`[${CONTENT_EDITABLE_ATTR}="false"]`) !== null;
|
|
3405
|
-
var
|
|
3460
|
+
var cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
|
|
3406
3461
|
var queryScopedFields = (entry, selector) => Array.from(entry.querySelectorAll(selector)).filter((el) => {
|
|
3407
3462
|
if (el.closest("[data-puck-array]")) return false;
|
|
3408
3463
|
const closestSlot = el.closest("[data-puck-slot]");
|
|
@@ -3410,7 +3465,7 @@ var queryScopedFields = (entry, selector) => Array.from(entry.querySelectorAll(s
|
|
|
3410
3465
|
return true;
|
|
3411
3466
|
});
|
|
3412
3467
|
var findOwnArrayContainer = (entry, arrayName) => {
|
|
3413
|
-
const selector = `[data-puck-array="${
|
|
3468
|
+
const selector = `[data-puck-array="${cssEscape(arrayName)}"]`;
|
|
3414
3469
|
for (const el of entry.querySelectorAll(selector)) {
|
|
3415
3470
|
const closestSlot = el.closest("[data-puck-slot]");
|
|
3416
3471
|
if (!closestSlot || !entry.contains(closestSlot)) return el;
|
|
@@ -3425,7 +3480,7 @@ var inlineEditModeFor = (field) => {
|
|
|
3425
3480
|
const type = field.shape?.type ?? field.fieldType;
|
|
3426
3481
|
return type === "richtext" ? "richtext" : type === "number" ? "number" : "text";
|
|
3427
3482
|
};
|
|
3428
|
-
var textFieldSelector = (field) => field.format === "json" ? `[${
|
|
3483
|
+
var textFieldSelector = (field) => field.format === "json" ? `[${cssEscape(`data-puck-field-${field.name}`)}]` : `[data-puck-field-name="${cssEscape(field.name)}"]`;
|
|
3429
3484
|
var isHTMLElement = (el) => {
|
|
3430
3485
|
const HTMLElementCtor = el.ownerDocument.defaultView?.HTMLElement;
|
|
3431
3486
|
return !!HTMLElementCtor && el instanceof HTMLElementCtor;
|
|
@@ -3451,6 +3506,29 @@ var syncFieldValues = (entry, fields, props) => {
|
|
|
3451
3506
|
});
|
|
3452
3507
|
}
|
|
3453
3508
|
};
|
|
3509
|
+
var claimedHostStyles = /* @__PURE__ */ new WeakMap();
|
|
3510
|
+
var claimHostStyles = (el, applyWhiteSpace) => {
|
|
3511
|
+
if (!claimedHostStyles.has(el)) {
|
|
3512
|
+
claimedHostStyles.set(el, {
|
|
3513
|
+
cursor: el.style.cursor,
|
|
3514
|
+
whiteSpace: applyWhiteSpace ? el.style.whiteSpace : null
|
|
3515
|
+
});
|
|
3516
|
+
}
|
|
3517
|
+
applyHostStyles(el);
|
|
3518
|
+
};
|
|
3519
|
+
var applyHostStyles = (el) => {
|
|
3520
|
+
const claimed = claimedHostStyles.get(el);
|
|
3521
|
+
if (!claimed) return;
|
|
3522
|
+
el.style.cursor = "text";
|
|
3523
|
+
if (claimed.whiteSpace !== null) el.style.whiteSpace = "pre-wrap";
|
|
3524
|
+
};
|
|
3525
|
+
var releaseHostStyles = (el) => {
|
|
3526
|
+
const claimed = claimedHostStyles.get(el);
|
|
3527
|
+
if (!claimed) return;
|
|
3528
|
+
el.style.cursor = claimed.cursor;
|
|
3529
|
+
if (claimed.whiteSpace !== null) el.style.whiteSpace = claimed.whiteSpace;
|
|
3530
|
+
claimedHostStyles.delete(el);
|
|
3531
|
+
};
|
|
3454
3532
|
var attachInlineEditing = (el, {
|
|
3455
3533
|
componentId,
|
|
3456
3534
|
propPath,
|
|
@@ -3463,8 +3541,7 @@ var attachInlineEditing = (el, {
|
|
|
3463
3541
|
const syncEditable = () => {
|
|
3464
3542
|
el.contentEditable = hovering || focused ? mode === "richtext" ? "true" : "plaintext-only" : "false";
|
|
3465
3543
|
};
|
|
3466
|
-
|
|
3467
|
-
el.style.cursor = "text";
|
|
3544
|
+
claimHostStyles(el, mode !== "richtext");
|
|
3468
3545
|
syncEditable();
|
|
3469
3546
|
let lastValidNumberText = el.innerText.replaceAll(/\n/gm, "");
|
|
3470
3547
|
const handleInput = () => {
|
|
@@ -3542,7 +3619,7 @@ var attachInlineEditing = (el, {
|
|
|
3542
3619
|
el.removeEventListener("mouseout", handleMouseOut, true);
|
|
3543
3620
|
el.removeEventListener("focus", handleFocus);
|
|
3544
3621
|
el.removeEventListener("blur", handleBlur);
|
|
3545
|
-
el
|
|
3622
|
+
releaseHostStyles(el);
|
|
3546
3623
|
el.removeAttribute("contenteditable");
|
|
3547
3624
|
cleanupPortal?.();
|
|
3548
3625
|
};
|
|
@@ -3608,7 +3685,7 @@ var wireArrayItemEditing = ({
|
|
|
3608
3685
|
const mode = inlineEditModeFor(field);
|
|
3609
3686
|
const registration = wiring.get(target);
|
|
3610
3687
|
if (registration?.propPath === propPath && registration.mode === mode) {
|
|
3611
|
-
target
|
|
3688
|
+
applyHostStyles(target);
|
|
3612
3689
|
continue;
|
|
3613
3690
|
}
|
|
3614
3691
|
registration?.cleanup();
|
|
@@ -3674,15 +3751,7 @@ var parseStyleString = (cssText) => {
|
|
|
3674
3751
|
return style;
|
|
3675
3752
|
};
|
|
3676
3753
|
var isEventHandlerAttr2 = (name) => /^on/i.test(name);
|
|
3677
|
-
var
|
|
3678
|
-
var fieldContentFor = (attribs, fields) => {
|
|
3679
|
-
for (const name of Object.keys(fields)) {
|
|
3680
|
-
if (attribs[`${FIELD_ATTR_PREFIX3}${name}`] !== void 0) return name;
|
|
3681
|
-
if (attribs["data-puck-field-name"] === name) return name;
|
|
3682
|
-
}
|
|
3683
|
-
return void 0;
|
|
3684
|
-
};
|
|
3685
|
-
var nodeToReact = (node, slots, fields, key) => {
|
|
3754
|
+
var nodeToReact = (node, slots, key) => {
|
|
3686
3755
|
if (node.type === "text") {
|
|
3687
3756
|
return node.data;
|
|
3688
3757
|
}
|
|
@@ -3713,17 +3782,13 @@ var nodeToReact = (node, slots, fields, key) => {
|
|
|
3713
3782
|
if (VOID_ELEMENTS.has(tag)) {
|
|
3714
3783
|
return (0, import_react22.createElement)(tag, props);
|
|
3715
3784
|
}
|
|
3716
|
-
const
|
|
3717
|
-
if (fieldName !== void 0) {
|
|
3718
|
-
return (0, import_react22.createElement)(tag, props, fields[fieldName]);
|
|
3719
|
-
}
|
|
3720
|
-
const children = el.children.map((child, i) => nodeToReact(child, slots, fields, i)).filter((c) => c !== null);
|
|
3785
|
+
const children = el.children.map((child, i) => nodeToReact(child, slots, i)).filter((c) => c !== null);
|
|
3721
3786
|
return (0, import_react22.createElement)(tag, props, ...children);
|
|
3722
3787
|
};
|
|
3723
|
-
var htmlToReactTree = (html, slots
|
|
3788
|
+
var htmlToReactTree = (html, slots) => {
|
|
3724
3789
|
if (!html) return null;
|
|
3725
3790
|
const doc = (0, import_htmlparser22.parseDocument)(html);
|
|
3726
|
-
const children = doc.children.map((child, i) => nodeToReact(child, slots,
|
|
3791
|
+
const children = doc.children.map((child, i) => nodeToReact(child, slots, i)).filter((c) => c !== null);
|
|
3727
3792
|
if (children.length === 0) return null;
|
|
3728
3793
|
if (children.length === 1) return children[0];
|
|
3729
3794
|
return (0, import_react22.createElement)(import_react22.Fragment, null, ...children);
|
|
@@ -3762,7 +3827,7 @@ var SlotPortal = ({
|
|
|
3762
3827
|
[slotStyle]
|
|
3763
3828
|
);
|
|
3764
3829
|
(0, import_react23.useEffect)(() => {
|
|
3765
|
-
const el = entry.querySelector(`[data-puck-slot="${
|
|
3830
|
+
const el = entry.querySelector(`[data-puck-slot="${cssEscape(slotName)}"]`);
|
|
3766
3831
|
if (el !== lastTarget.current) {
|
|
3767
3832
|
el?.replaceChildren();
|
|
3768
3833
|
lastTarget.current = el;
|
|
@@ -3780,32 +3845,10 @@ var SlotPortal = ({
|
|
|
3780
3845
|
);
|
|
3781
3846
|
};
|
|
3782
3847
|
|
|
3783
|
-
// src/lib/design/field-portal.tsx
|
|
3784
|
-
init_react_import();
|
|
3785
|
-
var import_react24 = require("react");
|
|
3786
|
-
var import_react_dom2 = require("react-dom");
|
|
3787
|
-
var FieldPortal = ({
|
|
3788
|
-
entry,
|
|
3789
|
-
html,
|
|
3790
|
-
selector,
|
|
3791
|
-
children
|
|
3792
|
-
}) => {
|
|
3793
|
-
const [target, setTarget] = (0, import_react24.useState)(null);
|
|
3794
|
-
const lastTarget = (0, import_react24.useRef)(null);
|
|
3795
|
-
(0, import_react24.useEffect)(() => {
|
|
3796
|
-
const el = queryScopedFields(entry, selector)[0] ?? null;
|
|
3797
|
-
if (el !== lastTarget.current) {
|
|
3798
|
-
el?.replaceChildren();
|
|
3799
|
-
lastTarget.current = el;
|
|
3800
|
-
setTarget(el);
|
|
3801
|
-
}
|
|
3802
|
-
}, [entry, html, selector]);
|
|
3803
|
-
if (!target) return null;
|
|
3804
|
-
return (0, import_react_dom2.createPortal)(children, target);
|
|
3805
|
-
};
|
|
3806
|
-
|
|
3807
3848
|
// src/lib/design/component.tsx
|
|
3808
3849
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3850
|
+
var DESIGN_COMPONENT = Symbol("puck-ai.designComponent");
|
|
3851
|
+
var isDesignComponent = (config) => !!config?.[DESIGN_COMPONENT];
|
|
3809
3852
|
var streamingValues = /* @__PURE__ */ new Map();
|
|
3810
3853
|
var instanceKey = (name, instanceId) => `${name}:${typeof instanceId === "string" ? instanceId : ""}`;
|
|
3811
3854
|
var getRegistrationSlotFields = (reg) => {
|
|
@@ -3830,9 +3873,9 @@ function createDesignComponentConfig(registration) {
|
|
|
3830
3873
|
registrationStore.apply(registration);
|
|
3831
3874
|
}
|
|
3832
3875
|
const slotFields = getRegistrationSlotFields(registration);
|
|
3833
|
-
|
|
3876
|
+
const componentConfig = {
|
|
3834
3877
|
...registration.label ? { label: registration.label } : {},
|
|
3835
|
-
fields: { ...slotFields
|
|
3878
|
+
fields: { ...slotFields },
|
|
3836
3879
|
defaultProps: { ...registration.defaultProps ?? {} },
|
|
3837
3880
|
resolveData: (data, { trigger }) => {
|
|
3838
3881
|
if (trigger !== "replace" && trigger !== "insert" && trigger !== "force") {
|
|
@@ -3891,6 +3934,8 @@ function createDesignComponentConfig(registration) {
|
|
|
3891
3934
|
},
|
|
3892
3935
|
render: (renderProps) => renderProps.puck?.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EditorEntry, { ...renderProps }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Entry, { ...renderProps, getPuck: null })
|
|
3893
3936
|
};
|
|
3937
|
+
componentConfig[DESIGN_COMPONENT] = true;
|
|
3938
|
+
return componentConfig;
|
|
3894
3939
|
function EditorEntry(renderProps) {
|
|
3895
3940
|
const getPuck = (0, import_core3.useGetPuck)();
|
|
3896
3941
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Entry, { ...renderProps, getPuck });
|
|
@@ -3902,11 +3947,11 @@ function createDesignComponentConfig(registration) {
|
|
|
3902
3947
|
style,
|
|
3903
3948
|
...props
|
|
3904
3949
|
}) {
|
|
3905
|
-
const getSnapshot = (0,
|
|
3950
|
+
const getSnapshot = (0, import_react24.useCallback)(
|
|
3906
3951
|
() => registrationStore.get(name) ?? registration,
|
|
3907
3952
|
[]
|
|
3908
3953
|
);
|
|
3909
|
-
const reg = (0,
|
|
3954
|
+
const reg = (0, import_react24.useSyncExternalStore)(
|
|
3910
3955
|
registrationStore.subscribe,
|
|
3911
3956
|
getSnapshot,
|
|
3912
3957
|
getSnapshot
|
|
@@ -3914,10 +3959,10 @@ function createDesignComponentConfig(registration) {
|
|
|
3914
3959
|
const html = reg.html ?? "";
|
|
3915
3960
|
const styles = reg.styles;
|
|
3916
3961
|
const script = reg.script;
|
|
3917
|
-
const [entryEl, setEntryEl] = (0,
|
|
3918
|
-
const scriptRef = (0,
|
|
3919
|
-
const annotations = (0,
|
|
3920
|
-
const { attrFields, arrayFields, attrSig, arraySig } = (0,
|
|
3962
|
+
const [entryEl, setEntryEl] = (0, import_react24.useState)(null);
|
|
3963
|
+
const scriptRef = (0, import_react24.useRef)(null);
|
|
3964
|
+
const annotations = (0, import_react24.useMemo)(() => getAnnotations(html), [html]);
|
|
3965
|
+
const { attrFields, arrayFields, attrSig, arraySig } = (0, import_react24.useMemo)(() => {
|
|
3921
3966
|
const attr = [];
|
|
3922
3967
|
const arrays = [];
|
|
3923
3968
|
for (const field of annotations.fields) {
|
|
@@ -3939,86 +3984,56 @@ function createDesignComponentConfig(registration) {
|
|
|
3939
3984
|
arraySig: JSON.stringify(arrays)
|
|
3940
3985
|
};
|
|
3941
3986
|
}, [props, annotations]);
|
|
3942
|
-
const
|
|
3943
|
-
const out = [];
|
|
3944
|
-
for (const field of annotations.fields) {
|
|
3945
|
-
if (field.binding !== "text") continue;
|
|
3946
|
-
const value = getDeepValue(props, field.name);
|
|
3947
|
-
if (!import_react25.default.isValidElement(value)) continue;
|
|
3948
|
-
out.push({
|
|
3949
|
-
name: field.name,
|
|
3950
|
-
selector: textFieldSelector(field),
|
|
3951
|
-
node: value
|
|
3952
|
-
});
|
|
3953
|
-
}
|
|
3954
|
-
return out;
|
|
3955
|
-
}, [annotations, props]);
|
|
3956
|
-
const storedProps = (0, import_react25.useMemo)(
|
|
3957
|
-
() => getPuck ? getPuck().getItemById(id)?.props : void 0,
|
|
3958
|
-
[getPuck, id, props]
|
|
3959
|
-
);
|
|
3960
|
-
const editableFields = (0, import_react25.useMemo)(() => {
|
|
3961
|
-
const mounted = new Set(nodeFields.map((f) => f.name));
|
|
3962
|
-
return annotations.fields.filter((field) => {
|
|
3963
|
-
if (mounted.has(field.name)) return false;
|
|
3964
|
-
if (field.binding === "array") return true;
|
|
3965
|
-
const type = field.shape?.type;
|
|
3966
|
-
if (type && !isBuiltInFieldType(type)) return false;
|
|
3967
|
-
if (!storedProps) return true;
|
|
3968
|
-
return getDeepValue(props, field.name) === getDeepValue(storedProps, field.name);
|
|
3969
|
-
});
|
|
3970
|
-
}, [annotations, nodeFields, props, storedProps]);
|
|
3971
|
-
const patchedHtml = (0, import_react25.useMemo)(() => {
|
|
3987
|
+
const patchedHtml = (0, import_react24.useMemo)(() => {
|
|
3972
3988
|
if (puck.isEditing) return html;
|
|
3973
3989
|
return patchHtmlAnnotations(html, props);
|
|
3974
3990
|
}, [html, props, puck.isEditing]);
|
|
3975
|
-
const fieldValueAttrs = (0,
|
|
3991
|
+
const fieldValueAttrs = (0, import_react24.useMemo)(() => {
|
|
3976
3992
|
const attrs = {};
|
|
3977
3993
|
attrs["data-puck-design"] = name;
|
|
3978
3994
|
for (const field of annotations.fields) {
|
|
3979
3995
|
const value = getDeepValue(props, field.name);
|
|
3980
3996
|
if (value === void 0 || value === null) continue;
|
|
3981
3997
|
if (!isValidFieldName(field.name)) continue;
|
|
3982
|
-
if (import_react25.default.isValidElement(value)) continue;
|
|
3983
3998
|
attrs[`data-puck-field-value-${field.name}`] = typeof value === "string" || typeof value === "number" ? String(value) : JSON.stringify(value);
|
|
3984
3999
|
}
|
|
3985
4000
|
return attrs;
|
|
3986
4001
|
}, [annotations, props, puck.isEditing]);
|
|
3987
|
-
const editorEntryNode = (0,
|
|
4002
|
+
const editorEntryNode = (0, import_react24.useMemo)(
|
|
3988
4003
|
() => puck.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl }) : null,
|
|
3989
4004
|
[puck.isEditing]
|
|
3990
4005
|
);
|
|
3991
|
-
(0,
|
|
4006
|
+
(0, import_react24.useEffect)(() => {
|
|
3992
4007
|
if (!puck.isEditing || !getPuck) return;
|
|
3993
4008
|
getPuck().resolveDataById(id, "force");
|
|
3994
4009
|
}, [reg, puck.isEditing, getPuck, id]);
|
|
3995
|
-
const fieldWiring = (0,
|
|
3996
|
-
const morphed = (0,
|
|
3997
|
-
(0,
|
|
4010
|
+
const fieldWiring = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
|
|
4011
|
+
const morphed = (0, import_react24.useRef)(null);
|
|
4012
|
+
(0, import_react24.useLayoutEffect)(() => {
|
|
3998
4013
|
if (!puck.isEditing || !entryEl) return;
|
|
3999
4014
|
if (morphed.current?.el !== entryEl || morphed.current?.html !== html || morphed.current?.attrSig !== attrSig) {
|
|
4000
4015
|
morphed.current = { el: entryEl, html, attrSig };
|
|
4001
4016
|
morphHtml(entryEl, html, attrFields);
|
|
4002
4017
|
for (const el of fieldWiring.current.keys()) {
|
|
4003
|
-
if (el.isConnected) el
|
|
4018
|
+
if (el.isConnected) applyHostStyles(el);
|
|
4004
4019
|
}
|
|
4005
4020
|
}
|
|
4006
4021
|
syncFieldValues(entryEl, annotations.fields, props);
|
|
4007
4022
|
if (getPuck) {
|
|
4008
|
-
wireFieldEditing(entryEl,
|
|
4023
|
+
wireFieldEditing(entryEl, annotations.fields, fieldWiring.current, {
|
|
4009
4024
|
componentId: id,
|
|
4010
4025
|
getPuck
|
|
4011
4026
|
});
|
|
4012
4027
|
}
|
|
4013
4028
|
});
|
|
4014
|
-
(0,
|
|
4029
|
+
(0, import_react24.useEffect)(
|
|
4015
4030
|
() => () => {
|
|
4016
4031
|
fieldWiring.current.forEach((cleanup) => cleanup());
|
|
4017
4032
|
fieldWiring.current.clear();
|
|
4018
4033
|
},
|
|
4019
4034
|
[]
|
|
4020
4035
|
);
|
|
4021
|
-
(0,
|
|
4036
|
+
(0, import_react24.useEffect)(() => {
|
|
4022
4037
|
if (!entryEl || !puck.isEditing) return;
|
|
4023
4038
|
for (const attr of Array.from(entryEl.attributes)) {
|
|
4024
4039
|
if ((attr.name === "data-puck-design" || attr.name.startsWith("data-puck-field-value-")) && !(attr.name in fieldValueAttrs)) {
|
|
@@ -4031,10 +4046,10 @@ function createDesignComponentConfig(registration) {
|
|
|
4031
4046
|
}
|
|
4032
4047
|
}
|
|
4033
4048
|
}, [entryEl, fieldValueAttrs]);
|
|
4034
|
-
const appliedArrayHtml = (0,
|
|
4035
|
-
const arrayItemWiring = (0,
|
|
4036
|
-
const appliedArrays = (0,
|
|
4037
|
-
(0,
|
|
4049
|
+
const appliedArrayHtml = (0, import_react24.useRef)(/* @__PURE__ */ new WeakMap());
|
|
4050
|
+
const arrayItemWiring = (0, import_react24.useRef)({});
|
|
4051
|
+
const appliedArrays = (0, import_react24.useRef)(null);
|
|
4052
|
+
(0, import_react24.useEffect)(() => {
|
|
4038
4053
|
if (!puck.isEditing || !entryEl || !getPuck) return;
|
|
4039
4054
|
if (appliedArrays.current?.el === entryEl && appliedArrays.current?.html === html && appliedArrays.current?.sig === arraySig) {
|
|
4040
4055
|
return;
|
|
@@ -4086,7 +4101,7 @@ function createDesignComponentConfig(registration) {
|
|
|
4086
4101
|
id,
|
|
4087
4102
|
getPuck
|
|
4088
4103
|
]);
|
|
4089
|
-
(0,
|
|
4104
|
+
(0, import_react24.useEffect)(
|
|
4090
4105
|
() => () => {
|
|
4091
4106
|
Object.values(arrayItemWiring.current).forEach(
|
|
4092
4107
|
(wiring) => wiring.forEach(({ cleanup }) => cleanup())
|
|
@@ -4094,7 +4109,7 @@ function createDesignComponentConfig(registration) {
|
|
|
4094
4109
|
},
|
|
4095
4110
|
[]
|
|
4096
4111
|
);
|
|
4097
|
-
(0,
|
|
4112
|
+
(0, import_react24.useEffect)(() => {
|
|
4098
4113
|
if (!script || !entryEl) return;
|
|
4099
4114
|
scriptRef.current?.remove();
|
|
4100
4115
|
const doc = entryEl.ownerDocument;
|
|
@@ -4121,30 +4136,16 @@ function createDesignComponentConfig(registration) {
|
|
|
4121
4136
|
);
|
|
4122
4137
|
}
|
|
4123
4138
|
}
|
|
4124
|
-
const fieldContent = {};
|
|
4125
|
-
for (const { name: name2, node } of nodeFields) {
|
|
4126
|
-
fieldContent[name2] = node;
|
|
4127
|
-
}
|
|
4128
4139
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
4129
4140
|
styles && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: styles }),
|
|
4130
4141
|
style && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: style }),
|
|
4131
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl, ...fieldValueAttrs, children: htmlToReactTree(patchedHtml, slotContent
|
|
4142
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl, ...fieldValueAttrs, children: htmlToReactTree(patchedHtml, slotContent) })
|
|
4132
4143
|
] });
|
|
4133
4144
|
}
|
|
4134
4145
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
4135
4146
|
styles && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: styles }),
|
|
4136
4147
|
style && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: style }),
|
|
4137
4148
|
editorEntryNode,
|
|
4138
|
-
entryEl && nodeFields.map(({ name: name2, selector, node }) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4139
|
-
FieldPortal,
|
|
4140
|
-
{
|
|
4141
|
-
entry: entryEl,
|
|
4142
|
-
html,
|
|
4143
|
-
selector,
|
|
4144
|
-
children: node
|
|
4145
|
-
},
|
|
4146
|
-
name2
|
|
4147
|
-
)),
|
|
4148
4149
|
entryEl && annotations.slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4149
4150
|
SlotPortal,
|
|
4150
4151
|
{
|
|
@@ -4163,7 +4164,7 @@ function createDesignComponentConfig(registration) {
|
|
|
4163
4164
|
|
|
4164
4165
|
// src/lib/design/globals.tsx
|
|
4165
4166
|
init_react_import();
|
|
4166
|
-
var
|
|
4167
|
+
var import_react25 = require("react");
|
|
4167
4168
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
4168
4169
|
function getDynamicConfigGlobals(dynamicConfig) {
|
|
4169
4170
|
if (typeof dynamicConfig !== "object" || dynamicConfig === null) return {};
|
|
@@ -4173,13 +4174,15 @@ function getDynamicConfigGlobals(dynamicConfig) {
|
|
|
4173
4174
|
...typeof script === "string" ? { script } : {}
|
|
4174
4175
|
};
|
|
4175
4176
|
}
|
|
4177
|
+
var INLINE_EDIT_RESET = ":where([data-puck-design] [contenteditable]){overflow-wrap:inherit;line-break:inherit;-webkit-nbsp-mode:inherit}";
|
|
4176
4178
|
function DesignGlobals({
|
|
4177
4179
|
styles,
|
|
4178
|
-
script
|
|
4180
|
+
script,
|
|
4181
|
+
isEditing
|
|
4179
4182
|
}) {
|
|
4180
|
-
const scriptRef = (0,
|
|
4181
|
-
const hostRef = (0,
|
|
4182
|
-
(0,
|
|
4183
|
+
const scriptRef = (0, import_react25.useRef)(null);
|
|
4184
|
+
const hostRef = (0, import_react25.useRef)(null);
|
|
4185
|
+
(0, import_react25.useEffect)(() => {
|
|
4183
4186
|
if (!script) return;
|
|
4184
4187
|
scriptRef.current?.remove();
|
|
4185
4188
|
const doc = hostRef.current?.ownerDocument ?? document;
|
|
@@ -4193,6 +4196,7 @@ function DesignGlobals({
|
|
|
4193
4196
|
};
|
|
4194
4197
|
}, [script]);
|
|
4195
4198
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
4199
|
+
isEditing && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("style", { children: INLINE_EDIT_RESET }),
|
|
4196
4200
|
styles && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("style", { children: styles }),
|
|
4197
4201
|
script && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: hostRef, style: { display: "none" } })
|
|
4198
4202
|
] });
|
|
@@ -4205,7 +4209,14 @@ function withDesignGlobals(root) {
|
|
|
4205
4209
|
const render = (props) => {
|
|
4206
4210
|
const { styles, script } = getDynamicConfigGlobals(props._dynamicConfig);
|
|
4207
4211
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
4208
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4212
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4213
|
+
DesignGlobals,
|
|
4214
|
+
{
|
|
4215
|
+
styles,
|
|
4216
|
+
script,
|
|
4217
|
+
isEditing: props.puck?.isEditing
|
|
4218
|
+
}
|
|
4219
|
+
),
|
|
4209
4220
|
userRender ? userRender(props) : props.children
|
|
4210
4221
|
] });
|
|
4211
4222
|
};
|
|
@@ -4319,7 +4330,7 @@ function syncDesignComponents(getPuck) {
|
|
|
4319
4330
|
ensureDynamicConfigField(config);
|
|
4320
4331
|
for (const [name, persistedReg] of Object.entries(persisted)) {
|
|
4321
4332
|
const prev = lastSynced.get(name);
|
|
4322
|
-
if (registrationStore.has(name) && (prev === persistedReg || registrationContentEqual(prev, persistedReg))) {
|
|
4333
|
+
if (registrationStore.has(name) && config.components[name] && (prev === persistedReg || registrationContentEqual(prev, persistedReg))) {
|
|
4323
4334
|
lastSynced.set(name, persistedReg);
|
|
4324
4335
|
continue;
|
|
4325
4336
|
}
|
|
@@ -4343,18 +4354,17 @@ function syncDesignComponents(getPuck) {
|
|
|
4343
4354
|
};
|
|
4344
4355
|
}
|
|
4345
4356
|
}
|
|
4346
|
-
config.components[name].fields =
|
|
4347
|
-
...getSlotFields(registration.html ?? ""),
|
|
4348
|
-
...getTransformableFields(registration)
|
|
4349
|
-
};
|
|
4357
|
+
config.components[name].fields = getSlotFields(registration.html ?? "");
|
|
4350
4358
|
}
|
|
4351
4359
|
let hasRemovals = false;
|
|
4352
4360
|
for (const [name] of registrationStore.getAll()) {
|
|
4353
4361
|
if (!(name in persisted)) {
|
|
4354
4362
|
registrationStore.delete(name);
|
|
4355
4363
|
lastSynced.delete(name);
|
|
4356
|
-
|
|
4357
|
-
|
|
4364
|
+
if (isDesignComponent(config.components[name])) {
|
|
4365
|
+
delete config.components[name];
|
|
4366
|
+
hasRemovals = true;
|
|
4367
|
+
}
|
|
4358
4368
|
}
|
|
4359
4369
|
}
|
|
4360
4370
|
if (createdSettled) {
|
|
@@ -4474,12 +4484,154 @@ var waitForIframeReady = async (root, imageTimeout = 1e4) => {
|
|
|
4474
4484
|
await waitForNextPaint(document2);
|
|
4475
4485
|
};
|
|
4476
4486
|
|
|
4487
|
+
// src/lib/capture-screenshot.ts
|
|
4488
|
+
init_react_import();
|
|
4489
|
+
var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
|
|
4490
|
+
|
|
4491
|
+
// src/lib/screenshot-size.ts
|
|
4492
|
+
init_react_import();
|
|
4493
|
+
var MAX_WEBP_DIMENSION = 16383;
|
|
4494
|
+
var CAPTURE_SCALE = 2;
|
|
4495
|
+
var getFitRatio = (width, height, dimensionLimit = MAX_WEBP_DIMENSION) => {
|
|
4496
|
+
if (width <= 0 || height <= 0) return 1;
|
|
4497
|
+
return Math.min(1, dimensionLimit / Math.max(width, height));
|
|
4498
|
+
};
|
|
4499
|
+
var getCaptureScale = (width, height, scale) => scale * getFitRatio(width * scale, height * scale);
|
|
4500
|
+
var scaleDimension = (value, ratio) => Math.max(1, Math.floor(value * ratio));
|
|
4501
|
+
var getDocumentSize = (root) => {
|
|
4502
|
+
const { body, documentElement } = root.ownerDocument;
|
|
4503
|
+
return {
|
|
4504
|
+
width: Math.max(
|
|
4505
|
+
body?.scrollWidth ?? 0,
|
|
4506
|
+
body?.offsetWidth ?? 0,
|
|
4507
|
+
body?.clientWidth ?? 0,
|
|
4508
|
+
documentElement?.scrollWidth ?? 0,
|
|
4509
|
+
documentElement?.offsetWidth ?? 0,
|
|
4510
|
+
documentElement?.clientWidth ?? 0
|
|
4511
|
+
),
|
|
4512
|
+
height: Math.max(
|
|
4513
|
+
body?.scrollHeight ?? 0,
|
|
4514
|
+
body?.offsetHeight ?? 0,
|
|
4515
|
+
body?.clientHeight ?? 0,
|
|
4516
|
+
documentElement?.scrollHeight ?? 0,
|
|
4517
|
+
documentElement?.offsetHeight ?? 0,
|
|
4518
|
+
documentElement?.clientHeight ?? 0
|
|
4519
|
+
)
|
|
4520
|
+
};
|
|
4521
|
+
};
|
|
4522
|
+
|
|
4523
|
+
// src/lib/screenshot-overflow.ts
|
|
4524
|
+
init_react_import();
|
|
4525
|
+
var applyBrowserOverflowStylesTo = (document2) => {
|
|
4526
|
+
for (const element of [document2.documentElement, document2.body]) {
|
|
4527
|
+
element?.style.setProperty("overflow", "visible", "important");
|
|
4528
|
+
}
|
|
4529
|
+
};
|
|
4530
|
+
|
|
4531
|
+
// src/lib/capture-screenshot.ts
|
|
4532
|
+
var editorOnlyClassPrefixes = ["_DraggableComponent--hover", "_ActionBar"];
|
|
4533
|
+
var releaseCanvas = (canvas) => {
|
|
4534
|
+
canvas.width = 0;
|
|
4535
|
+
canvas.height = 0;
|
|
4536
|
+
};
|
|
4537
|
+
var drawScaled = (source, ratio) => {
|
|
4538
|
+
const target = document.createElement("canvas");
|
|
4539
|
+
target.width = scaleDimension(source.width, ratio);
|
|
4540
|
+
target.height = scaleDimension(source.height, ratio);
|
|
4541
|
+
const ctx2 = target.getContext("2d");
|
|
4542
|
+
if (!ctx2) {
|
|
4543
|
+
releaseCanvas(target);
|
|
4544
|
+
return source;
|
|
4545
|
+
}
|
|
4546
|
+
ctx2.imageSmoothingEnabled = true;
|
|
4547
|
+
ctx2.imageSmoothingQuality = "high";
|
|
4548
|
+
ctx2.drawImage(source, 0, 0, target.width, target.height);
|
|
4549
|
+
return target;
|
|
4550
|
+
};
|
|
4551
|
+
var fitCanvas = (canvas) => {
|
|
4552
|
+
let remaining = getFitRatio(canvas.width, canvas.height);
|
|
4553
|
+
if (remaining >= 1) return canvas;
|
|
4554
|
+
let current = canvas;
|
|
4555
|
+
while (remaining < 0.5) {
|
|
4556
|
+
const next = drawScaled(current, 0.5);
|
|
4557
|
+
if (current !== canvas) releaseCanvas(current);
|
|
4558
|
+
current = next;
|
|
4559
|
+
remaining *= 2;
|
|
4560
|
+
}
|
|
4561
|
+
const fitted = drawScaled(current, remaining);
|
|
4562
|
+
if (current !== canvas) releaseCanvas(current);
|
|
4563
|
+
return fitted;
|
|
4564
|
+
};
|
|
4565
|
+
var toWebp = (canvas, quality) => new Promise((resolve, reject) => {
|
|
4566
|
+
canvas.toBlob(
|
|
4567
|
+
(blob) => {
|
|
4568
|
+
if (blob && blob.size > 0) {
|
|
4569
|
+
resolve(blob);
|
|
4570
|
+
return;
|
|
4571
|
+
}
|
|
4572
|
+
reject(
|
|
4573
|
+
new Error(
|
|
4574
|
+
`Could not encode a ${canvas.width}x${canvas.height} canvas as WebP`
|
|
4575
|
+
)
|
|
4576
|
+
);
|
|
4577
|
+
},
|
|
4578
|
+
"image/webp",
|
|
4579
|
+
quality
|
|
4580
|
+
);
|
|
4581
|
+
});
|
|
4582
|
+
var captureScreenshot = async (root, { scale = CAPTURE_SCALE, quality = 0.8, width } = {}) => {
|
|
4583
|
+
const documentSize = getDocumentSize(root);
|
|
4584
|
+
const safeWebPScale = getCaptureScale(
|
|
4585
|
+
width ?? documentSize.width,
|
|
4586
|
+
documentSize.height,
|
|
4587
|
+
scale
|
|
4588
|
+
);
|
|
4589
|
+
const canvas = await (0, import_html2canvas_pro.default)(root, {
|
|
4590
|
+
scale: safeWebPScale,
|
|
4591
|
+
backgroundColor: "#ffffff",
|
|
4592
|
+
...width === void 0 ? {} : { width, windowWidth: width },
|
|
4593
|
+
foreignObjectRendering: false,
|
|
4594
|
+
imageTimeout: 3e4,
|
|
4595
|
+
logging: false,
|
|
4596
|
+
allowTaint: false,
|
|
4597
|
+
useCORS: true,
|
|
4598
|
+
scrollY: 0,
|
|
4599
|
+
onclone: applyBrowserOverflowStylesTo,
|
|
4600
|
+
ignoreElements: (el) => Array.from(el.classList).some(
|
|
4601
|
+
(c) => editorOnlyClassPrefixes.some((prefix) => c.startsWith(prefix))
|
|
4602
|
+
)
|
|
4603
|
+
});
|
|
4604
|
+
const fitted = fitCanvas(canvas);
|
|
4605
|
+
try {
|
|
4606
|
+
return await toWebp(fitted, quality);
|
|
4607
|
+
} finally {
|
|
4608
|
+
if (fitted !== canvas) releaseCanvas(fitted);
|
|
4609
|
+
releaseCanvas(canvas);
|
|
4610
|
+
}
|
|
4611
|
+
};
|
|
4612
|
+
|
|
4613
|
+
// src/lib/client-tool-response.ts
|
|
4614
|
+
init_react_import();
|
|
4615
|
+
async function postClientToolResponse(host, body) {
|
|
4616
|
+
const response = await fetch(`${host.replace(/\/+$/, "")}/tool`, {
|
|
4617
|
+
method: "POST",
|
|
4618
|
+
headers: { "Content-Type": "application/json" },
|
|
4619
|
+
body: JSON.stringify(body)
|
|
4620
|
+
});
|
|
4621
|
+
if (!response.ok) {
|
|
4622
|
+
throw new Error(
|
|
4623
|
+
`Client tool endpoint returned ${response.status} ${response.statusText}`.trim()
|
|
4624
|
+
);
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
|
|
4477
4628
|
// src/components/Chat/index.tsx
|
|
4478
4629
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
4479
4630
|
var q = (0, import_qler.default)();
|
|
4480
4631
|
var DEFAULT_API_VERSION = "v2";
|
|
4481
4632
|
var BUILD_OP_DEBOUNCE_MS = 1e3 / 60;
|
|
4482
|
-
var
|
|
4633
|
+
var CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE = "Unable to verify the page data. Please enable the `/chat/tool` endpoint on the server and try again.";
|
|
4634
|
+
var PLUGIN_AI_VERSION = true ? "0.9.0-canary.f2867fd7" : "unknown";
|
|
4483
4635
|
var BENCHMARK = false;
|
|
4484
4636
|
var prefixedUlid = (prefix = "") => `${prefix ? `${prefix}_` : ""}${(0, import_ulid.ulid)()}`;
|
|
4485
4637
|
var getClassName18 = getClassNameFactory("Chat", styles_module_default);
|
|
@@ -4502,28 +4654,32 @@ function Chat2(props) {
|
|
|
4502
4654
|
} = chat ?? {};
|
|
4503
4655
|
const puckDispatch = usePuck((s) => s.dispatch);
|
|
4504
4656
|
const getPuck = (0, import_core5.useGetPuck)();
|
|
4505
|
-
const localChatId = (0,
|
|
4506
|
-
const inputRef = (0,
|
|
4507
|
-
const pluginRef = (0,
|
|
4508
|
-
const [mode, setMode] = (0,
|
|
4509
|
-
const modeRef = (0,
|
|
4657
|
+
const localChatId = (0, import_react27.useRef)("");
|
|
4658
|
+
const inputRef = (0, import_react27.useRef)(null);
|
|
4659
|
+
const pluginRef = (0, import_react27.useRef)(null);
|
|
4660
|
+
const [mode, setMode] = (0, import_react27.useState)(defaultMode);
|
|
4661
|
+
const modeRef = (0, import_react27.useRef)(mode);
|
|
4510
4662
|
const designModeVisible = typeof designMode === "boolean" ? designMode : designMode.visible ?? false;
|
|
4511
|
-
(0,
|
|
4663
|
+
(0, import_react27.useEffect)(() => {
|
|
4512
4664
|
modeRef.current = mode;
|
|
4513
4665
|
}, [mode]);
|
|
4514
4666
|
const puckData = usePuck((s) => s.appState.data);
|
|
4515
|
-
(0,
|
|
4667
|
+
(0, import_react27.useEffect)(() => {
|
|
4516
4668
|
syncDesignComponents(getPuck);
|
|
4517
4669
|
}, [puckData, getPuck]);
|
|
4518
|
-
const [error, setError] = (0,
|
|
4519
|
-
const [userError, setUserError] = (0,
|
|
4520
|
-
const
|
|
4521
|
-
const
|
|
4522
|
-
const
|
|
4523
|
-
const
|
|
4524
|
-
const
|
|
4525
|
-
const
|
|
4526
|
-
const
|
|
4670
|
+
const [error, setError] = (0, import_react27.useState)();
|
|
4671
|
+
const [userError, setUserError] = (0, import_react27.useState)();
|
|
4672
|
+
const clientToolEndpointUnavailableRef = (0, import_react27.useRef)(false);
|
|
4673
|
+
const stopChatRef = (0, import_react27.useRef)(null);
|
|
4674
|
+
const [composerAttachments, setComposerAttachments] = (0, import_react27.useState)([]);
|
|
4675
|
+
const removedAttachmentClientIdsRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
|
|
4676
|
+
const uploadControllersRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
|
|
4677
|
+
const pendingBuildOpsRef = (0, import_react27.useRef)([]);
|
|
4678
|
+
const lastStreamActivityRef = (0, import_react27.useRef)(0);
|
|
4679
|
+
const hiddenSinceRef = (0, import_react27.useRef)(null);
|
|
4680
|
+
const [toolStatus, setToolStatus] = (0, import_react27.useState)({});
|
|
4681
|
+
const [subagentState, setSubagentState] = (0, import_react27.useState)({});
|
|
4682
|
+
const attachmentConfig = (0, import_react27.useMemo)(
|
|
4527
4683
|
() => ({
|
|
4528
4684
|
accept: attachments?.accept ?? defaultAttachmentAccept,
|
|
4529
4685
|
enabled: attachments?.enabled ?? true,
|
|
@@ -4533,14 +4689,14 @@ function Chat2(props) {
|
|
|
4533
4689
|
}),
|
|
4534
4690
|
[attachments, host]
|
|
4535
4691
|
);
|
|
4536
|
-
(0,
|
|
4692
|
+
(0, import_react27.useEffect)(
|
|
4537
4693
|
() => () => {
|
|
4538
4694
|
uploadControllersRef.current.forEach((controller) => controller.abort());
|
|
4539
4695
|
uploadControllersRef.current.clear();
|
|
4540
4696
|
},
|
|
4541
4697
|
[]
|
|
4542
4698
|
);
|
|
4543
|
-
const deleteAttachment = (0,
|
|
4699
|
+
const deleteAttachment = (0, import_react27.useCallback)(
|
|
4544
4700
|
async (attachmentId) => {
|
|
4545
4701
|
try {
|
|
4546
4702
|
await fetch(`${attachmentConfig.endpoint}/${attachmentId}`, {
|
|
@@ -4552,7 +4708,7 @@ function Chat2(props) {
|
|
|
4552
4708
|
},
|
|
4553
4709
|
[attachmentConfig.endpoint]
|
|
4554
4710
|
);
|
|
4555
|
-
const uploadScreenshot = (0,
|
|
4711
|
+
const uploadScreenshot = (0, import_react27.useCallback)(
|
|
4556
4712
|
async (width, bucketUrl) => {
|
|
4557
4713
|
try {
|
|
4558
4714
|
const iframeDocument = document?.getElementById("preview-frame")?.contentDocument?.documentElement ?? null;
|
|
@@ -4560,24 +4716,7 @@ function Chat2(props) {
|
|
|
4560
4716
|
throw new Error("Preview frame not found");
|
|
4561
4717
|
}
|
|
4562
4718
|
await waitForIframeReady(iframeDocument);
|
|
4563
|
-
const
|
|
4564
|
-
scale: 2,
|
|
4565
|
-
backgroundColor: "#ffffff",
|
|
4566
|
-
width,
|
|
4567
|
-
windowWidth: width,
|
|
4568
|
-
foreignObjectRendering: false,
|
|
4569
|
-
imageTimeout: 3e4,
|
|
4570
|
-
logging: false,
|
|
4571
|
-
allowTaint: false,
|
|
4572
|
-
useCORS: true,
|
|
4573
|
-
scrollY: 0,
|
|
4574
|
-
ignoreElements: (el) => Array.from(el.classList).some(
|
|
4575
|
-
(c) => c.startsWith("_DraggableComponent--hover") || c.startsWith("_ActionBar")
|
|
4576
|
-
)
|
|
4577
|
-
});
|
|
4578
|
-
const image = canvas.toDataURL("image/webp", 0.8);
|
|
4579
|
-
const imageResponse = await fetch(image);
|
|
4580
|
-
const blob = await imageResponse.blob();
|
|
4719
|
+
const blob = await captureScreenshot(iframeDocument, { width });
|
|
4581
4720
|
const uploadResponse = await fetch(bucketUrl, {
|
|
4582
4721
|
method: "PUT",
|
|
4583
4722
|
body: blob
|
|
@@ -4624,15 +4763,50 @@ function Chat2(props) {
|
|
|
4624
4763
|
BUILD_OP_DEBOUNCE_MS,
|
|
4625
4764
|
{ maxWait: BUILD_OP_DEBOUNCE_MS }
|
|
4626
4765
|
);
|
|
4627
|
-
const queueBuildOp = (0,
|
|
4766
|
+
const queueBuildOp = (0, import_react27.useCallback)(
|
|
4628
4767
|
(operation) => {
|
|
4629
4768
|
pendingBuildOpsRef.current.push(operation);
|
|
4630
4769
|
debouncedFlushBuildOps();
|
|
4631
4770
|
},
|
|
4632
4771
|
[debouncedFlushBuildOps]
|
|
4633
4772
|
);
|
|
4634
|
-
const
|
|
4773
|
+
const handleClientToolEndpointUnavailable = (0, import_react27.useCallback)(() => {
|
|
4774
|
+
if (clientToolEndpointUnavailableRef.current) return;
|
|
4775
|
+
clientToolEndpointUnavailableRef.current = true;
|
|
4776
|
+
setError(CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE);
|
|
4777
|
+
console.error(CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE);
|
|
4778
|
+
setToolStatus((current) => {
|
|
4779
|
+
let changed = false;
|
|
4780
|
+
const next = {};
|
|
4781
|
+
for (const [id, toolState] of Object.entries(current)) {
|
|
4782
|
+
if (toolState.loading) {
|
|
4783
|
+
changed = true;
|
|
4784
|
+
next[id] = {
|
|
4785
|
+
...toolState,
|
|
4786
|
+
loading: false,
|
|
4787
|
+
label: "Verification unavailable"
|
|
4788
|
+
};
|
|
4789
|
+
} else {
|
|
4790
|
+
next[id] = toolState;
|
|
4791
|
+
}
|
|
4792
|
+
}
|
|
4793
|
+
return changed ? next : current;
|
|
4794
|
+
});
|
|
4795
|
+
stopChatRef.current?.();
|
|
4796
|
+
}, []);
|
|
4797
|
+
const sendClientToolResponse = (0, import_react27.useCallback)(
|
|
4798
|
+
async (body) => {
|
|
4799
|
+
try {
|
|
4800
|
+
await postClientToolResponse(host, body);
|
|
4801
|
+
} catch {
|
|
4802
|
+
handleClientToolEndpointUnavailable();
|
|
4803
|
+
}
|
|
4804
|
+
},
|
|
4805
|
+
[handleClientToolEndpointUnavailable, host]
|
|
4806
|
+
);
|
|
4807
|
+
const processData = (0, import_react27.useCallback)(
|
|
4635
4808
|
(dataPart) => {
|
|
4809
|
+
lastStreamActivityRef.current = Date.now();
|
|
4636
4810
|
switch (dataPart.type) {
|
|
4637
4811
|
case "data-new-chat-created": {
|
|
4638
4812
|
localChatId.current = dataPart.data.chatId;
|
|
@@ -4663,13 +4837,9 @@ function Chat2(props) {
|
|
|
4663
4837
|
debouncedFlushBuildOps.flush();
|
|
4664
4838
|
q.wait().then(() => {
|
|
4665
4839
|
const { appState } = getPuck();
|
|
4666
|
-
return
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
body: JSON.stringify({
|
|
4670
|
-
id: requestId,
|
|
4671
|
-
responses: [{ action, output: appState.data }]
|
|
4672
|
-
})
|
|
4840
|
+
return sendClientToolResponse({
|
|
4841
|
+
id: requestId,
|
|
4842
|
+
responses: [{ action, output: appState.data }]
|
|
4673
4843
|
});
|
|
4674
4844
|
}).catch((e) => {
|
|
4675
4845
|
console.error("Failed to respond to client request:", e);
|
|
@@ -4686,22 +4856,7 @@ function Chat2(props) {
|
|
|
4686
4856
|
throw new Error("Preview frame not found");
|
|
4687
4857
|
}
|
|
4688
4858
|
await waitForIframeReady(iframeDocument);
|
|
4689
|
-
const
|
|
4690
|
-
scale: 2,
|
|
4691
|
-
backgroundColor: "#ffffff",
|
|
4692
|
-
foreignObjectRendering: false,
|
|
4693
|
-
imageTimeout: 3e4,
|
|
4694
|
-
logging: false,
|
|
4695
|
-
allowTaint: false,
|
|
4696
|
-
useCORS: true,
|
|
4697
|
-
scrollY: 0,
|
|
4698
|
-
ignoreElements: (el) => Array.from(el.classList).some(
|
|
4699
|
-
(c) => c.startsWith("_DraggableComponent--hover") || c.startsWith("_ActionBar")
|
|
4700
|
-
)
|
|
4701
|
-
});
|
|
4702
|
-
const image = canvas.toDataURL("image/webp", 0.8);
|
|
4703
|
-
const imageResponse = await fetch(image);
|
|
4704
|
-
const blob = await imageResponse.blob();
|
|
4859
|
+
const blob = await captureScreenshot(iframeDocument);
|
|
4705
4860
|
const uploadResponse = await fetch(putUrl, {
|
|
4706
4861
|
method: "PUT",
|
|
4707
4862
|
body: blob
|
|
@@ -4711,16 +4866,16 @@ function Chat2(props) {
|
|
|
4711
4866
|
`Upload failed with status ${uploadResponse.status}`
|
|
4712
4867
|
);
|
|
4713
4868
|
}
|
|
4714
|
-
return
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
body: JSON.stringify({
|
|
4718
|
-
id: requestId,
|
|
4719
|
-
responses: [{ action, output: { sizeBytes: blob.size } }]
|
|
4720
|
-
})
|
|
4869
|
+
return sendClientToolResponse({
|
|
4870
|
+
id: requestId,
|
|
4871
|
+
responses: [{ action, output: { sizeBytes: blob.size } }]
|
|
4721
4872
|
});
|
|
4722
4873
|
}).catch((e) => {
|
|
4723
4874
|
console.error("Failed to respond to client request:", e);
|
|
4875
|
+
return sendClientToolResponse({
|
|
4876
|
+
id: requestId,
|
|
4877
|
+
responses: [{ action, output: { sizeBytes: 0 } }]
|
|
4878
|
+
});
|
|
4724
4879
|
});
|
|
4725
4880
|
}
|
|
4726
4881
|
return;
|
|
@@ -4764,6 +4919,7 @@ function Chat2(props) {
|
|
|
4764
4919
|
getPuck,
|
|
4765
4920
|
puckDispatch,
|
|
4766
4921
|
queueBuildOp,
|
|
4922
|
+
sendClientToolResponse,
|
|
4767
4923
|
uploadScreenshot
|
|
4768
4924
|
]
|
|
4769
4925
|
);
|
|
@@ -4833,12 +4989,14 @@ function Chat2(props) {
|
|
|
4833
4989
|
if (BENCHMARK) {
|
|
4834
4990
|
console.timeEnd("chat");
|
|
4835
4991
|
}
|
|
4836
|
-
|
|
4992
|
+
if (!clientToolEndpointUnavailableRef.current) {
|
|
4993
|
+
setError(e.message);
|
|
4994
|
+
}
|
|
4837
4995
|
},
|
|
4838
4996
|
onFinish: (options) => {
|
|
4839
4997
|
debouncedFlushBuildOps.flush();
|
|
4840
4998
|
q.wait().then(() => {
|
|
4841
|
-
if (!options.isAbort) {
|
|
4999
|
+
if (!options.isAbort || clientToolEndpointUnavailableRef.current) {
|
|
4842
5000
|
puckDispatch({
|
|
4843
5001
|
type: "set",
|
|
4844
5002
|
state: getPuck().appState,
|
|
@@ -4853,18 +5011,69 @@ function Chat2(props) {
|
|
|
4853
5011
|
});
|
|
4854
5012
|
}
|
|
4855
5013
|
});
|
|
4856
|
-
(0,
|
|
4857
|
-
|
|
5014
|
+
(0, import_react27.useEffect)(() => {
|
|
5015
|
+
stopChatRef.current = stop;
|
|
5016
|
+
return () => {
|
|
5017
|
+
stopChatRef.current = null;
|
|
4858
5018
|
stop();
|
|
4859
|
-
}
|
|
4860
|
-
|
|
4861
|
-
);
|
|
4862
|
-
|
|
4863
|
-
|
|
5019
|
+
};
|
|
5020
|
+
}, [stop]);
|
|
5021
|
+
const statusRef = (0, import_react27.useRef)(status);
|
|
5022
|
+
(0, import_react27.useEffect)(() => {
|
|
5023
|
+
statusRef.current = status;
|
|
5024
|
+
}, [status]);
|
|
5025
|
+
(0, import_react27.useEffect)(() => {
|
|
5026
|
+
lastStreamActivityRef.current = Date.now();
|
|
5027
|
+
}, [messages]);
|
|
5028
|
+
(0, import_react27.useEffect)(() => {
|
|
5029
|
+
const FROZEN_HIDDEN_MS = 3 * 6e4;
|
|
5030
|
+
const RESUME_GRACE_MS = 12e3;
|
|
5031
|
+
const isStreaming = () => statusRef.current === "streaming" || statusRef.current === "submitted";
|
|
5032
|
+
let graceTimer;
|
|
5033
|
+
const recoverIfSevered = () => {
|
|
5034
|
+
if (!isStreaming()) return;
|
|
5035
|
+
if (Date.now() - lastStreamActivityRef.current < RESUME_GRACE_MS) return;
|
|
5036
|
+
stop();
|
|
5037
|
+
setToolStatus((current) => {
|
|
5038
|
+
let changed = false;
|
|
5039
|
+
const next = {};
|
|
5040
|
+
for (const [id, toolState] of Object.entries(current)) {
|
|
5041
|
+
if (toolState.loading) {
|
|
5042
|
+
changed = true;
|
|
5043
|
+
next[id] = { ...toolState, loading: false, label: "Interrupted" };
|
|
5044
|
+
} else {
|
|
5045
|
+
next[id] = toolState;
|
|
5046
|
+
}
|
|
5047
|
+
}
|
|
5048
|
+
return changed ? next : current;
|
|
5049
|
+
});
|
|
5050
|
+
};
|
|
5051
|
+
const onVisibilityChange = () => {
|
|
5052
|
+
if (document.hidden) {
|
|
5053
|
+
hiddenSinceRef.current = isStreaming() ? Date.now() : null;
|
|
5054
|
+
return;
|
|
5055
|
+
}
|
|
5056
|
+
const hiddenSince = hiddenSinceRef.current;
|
|
5057
|
+
hiddenSinceRef.current = null;
|
|
5058
|
+
if (graceTimer) clearTimeout(graceTimer);
|
|
5059
|
+
if (hiddenSince === null || Date.now() - hiddenSince < FROZEN_HIDDEN_MS) {
|
|
5060
|
+
return;
|
|
5061
|
+
}
|
|
5062
|
+
lastStreamActivityRef.current = 0;
|
|
5063
|
+
graceTimer = setTimeout(recoverIfSevered, RESUME_GRACE_MS);
|
|
5064
|
+
};
|
|
5065
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
5066
|
+
return () => {
|
|
5067
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
5068
|
+
if (graceTimer) clearTimeout(graceTimer);
|
|
5069
|
+
};
|
|
5070
|
+
}, [stop]);
|
|
5071
|
+
const [forcedStatus, setForcedStatus] = (0, import_react27.useState)();
|
|
5072
|
+
const resolvedStatus = (0, import_react27.useMemo)(
|
|
4864
5073
|
() => forcedStatus ?? status,
|
|
4865
5074
|
[status, forcedStatus]
|
|
4866
5075
|
);
|
|
4867
|
-
(0,
|
|
5076
|
+
(0, import_react27.useEffect)(() => {
|
|
4868
5077
|
if (!scrollTrackingId) return;
|
|
4869
5078
|
dispatchScrollTrackingEvent({
|
|
4870
5079
|
id: scrollTrackingId,
|
|
@@ -4877,7 +5086,7 @@ function Chat2(props) {
|
|
|
4877
5086
|
});
|
|
4878
5087
|
};
|
|
4879
5088
|
}, [resolvedStatus, scrollTrackingId]);
|
|
4880
|
-
(0,
|
|
5089
|
+
(0, import_react27.useEffect)(() => {
|
|
4881
5090
|
window.__PUCK_AI = {
|
|
4882
5091
|
processData,
|
|
4883
5092
|
setMessages,
|
|
@@ -4909,6 +5118,8 @@ function Chat2(props) {
|
|
|
4909
5118
|
if (!text && readyAttachments.length === 0) {
|
|
4910
5119
|
return false;
|
|
4911
5120
|
}
|
|
5121
|
+
clientToolEndpointUnavailableRef.current = false;
|
|
5122
|
+
setError("");
|
|
4912
5123
|
setUserError("");
|
|
4913
5124
|
if (chat?.onSubmit) {
|
|
4914
5125
|
try {
|
|
@@ -5086,7 +5297,7 @@ function Chat2(props) {
|
|
|
5086
5297
|
if (!target?.attachmentId) return;
|
|
5087
5298
|
await deleteAttachment(target.attachmentId);
|
|
5088
5299
|
};
|
|
5089
|
-
const messagesWithStatuses = (0,
|
|
5300
|
+
const messagesWithStatuses = (0, import_react27.useMemo)(() => {
|
|
5090
5301
|
return messages.map((msg) => {
|
|
5091
5302
|
return {
|
|
5092
5303
|
...msg,
|
|
@@ -5148,6 +5359,7 @@ function Chat2(props) {
|
|
|
5148
5359
|
),
|
|
5149
5360
|
error,
|
|
5150
5361
|
handleRetry: () => {
|
|
5362
|
+
clientToolEndpointUnavailableRef.current = false;
|
|
5151
5363
|
setError("");
|
|
5152
5364
|
regenerate();
|
|
5153
5365
|
},
|
|
@@ -5270,8 +5482,8 @@ function AttachmentComposer({
|
|
|
5270
5482
|
maxFiles,
|
|
5271
5483
|
onChange
|
|
5272
5484
|
}) {
|
|
5273
|
-
const id = (0,
|
|
5274
|
-
const inputId = (0,
|
|
5485
|
+
const id = (0, import_react27.useId)();
|
|
5486
|
+
const inputId = (0, import_react27.useMemo)(() => `attachment-input-${id}`, []);
|
|
5275
5487
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: getClassName18("attachmentControls"), children: [
|
|
5276
5488
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5277
5489
|
"input",
|
|
@@ -5371,7 +5583,7 @@ function isScrolledIntoView(el) {
|
|
|
5371
5583
|
|
|
5372
5584
|
// src/components/ScrollTracking/ScrollTracking.tsx
|
|
5373
5585
|
init_react_import();
|
|
5374
|
-
var
|
|
5586
|
+
var import_react29 = require("react");
|
|
5375
5587
|
|
|
5376
5588
|
// src/lib/scroll-into-view-local.ts
|
|
5377
5589
|
init_react_import();
|
|
@@ -5394,9 +5606,9 @@ function scrollIntoViewLocal(el, win, behavior = "smooth") {
|
|
|
5394
5606
|
|
|
5395
5607
|
// src/lib/use-frame-mutation-observer.ts
|
|
5396
5608
|
init_react_import();
|
|
5397
|
-
var
|
|
5609
|
+
var import_react28 = require("react");
|
|
5398
5610
|
function useFrameMutationObserver(callback) {
|
|
5399
|
-
return (0,
|
|
5611
|
+
return (0, import_react28.useCallback)(() => {
|
|
5400
5612
|
const frame = document?.getElementById(
|
|
5401
5613
|
"preview-frame"
|
|
5402
5614
|
);
|
|
@@ -5441,9 +5653,9 @@ var ScrollTracking = ({
|
|
|
5441
5653
|
children,
|
|
5442
5654
|
trackingId
|
|
5443
5655
|
}) => {
|
|
5444
|
-
const followedRefs = (0,
|
|
5445
|
-
const enabledRef = (0,
|
|
5446
|
-
(0,
|
|
5656
|
+
const followedRefs = (0, import_react29.useRef)([]);
|
|
5657
|
+
const enabledRef = (0, import_react29.useRef)(false);
|
|
5658
|
+
(0, import_react29.useEffect)(() => {
|
|
5447
5659
|
return subscribeToScrollTrackingEvents(({ id, enabled }) => {
|
|
5448
5660
|
if (id !== trackingId) return;
|
|
5449
5661
|
enabledRef.current = enabled;
|
|
@@ -5462,7 +5674,7 @@ var ScrollTracking = ({
|
|
|
5462
5674
|
});
|
|
5463
5675
|
}
|
|
5464
5676
|
});
|
|
5465
|
-
(0,
|
|
5677
|
+
(0, import_react29.useEffect)(() => {
|
|
5466
5678
|
follow();
|
|
5467
5679
|
}, [follow]);
|
|
5468
5680
|
return children;
|
|
@@ -5475,7 +5687,7 @@ var import_core7 = require("@puckeditor/core");
|
|
|
5475
5687
|
// src/components/ManageComponents/index.tsx
|
|
5476
5688
|
init_react_import();
|
|
5477
5689
|
var import_core6 = require("@puckeditor/core");
|
|
5478
|
-
var
|
|
5690
|
+
var import_react30 = require("react");
|
|
5479
5691
|
|
|
5480
5692
|
// css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/ManageComponents/styles.module.css#css-module
|
|
5481
5693
|
init_react_import();
|
|
@@ -5484,7 +5696,7 @@ var styles_module_default10 = { "ManageComponents-cta": "_ManageComponents-cta_x
|
|
|
5484
5696
|
// src/components/ManageComponents/index.tsx
|
|
5485
5697
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
5486
5698
|
var cx10 = getClassNameFactory2("ManageComponents", styles_module_default10);
|
|
5487
|
-
var useRegistrations = () => (0,
|
|
5699
|
+
var useRegistrations = () => (0, import_react30.useSyncExternalStore)(
|
|
5488
5700
|
registrationStore.subscribe,
|
|
5489
5701
|
() => registrationStore.getAll(),
|
|
5490
5702
|
() => registrationStore.getAll()
|
|
@@ -5492,9 +5704,9 @@ var useRegistrations = () => (0, import_react31.useSyncExternalStore)(
|
|
|
5492
5704
|
function ManageModalContent({ onClose }) {
|
|
5493
5705
|
const getPuck = (0, import_core6.useGetPuck)();
|
|
5494
5706
|
const { visible, setVisible } = useModal();
|
|
5495
|
-
const [confirmTarget, setConfirmTarget] = (0,
|
|
5707
|
+
const [confirmTarget, setConfirmTarget] = (0, import_react30.useState)(null);
|
|
5496
5708
|
const entries = useRegistrations();
|
|
5497
|
-
(0,
|
|
5709
|
+
(0, import_react30.useEffect)(() => {
|
|
5498
5710
|
if (!visible) onClose();
|
|
5499
5711
|
}, [visible, onClose]);
|
|
5500
5712
|
const handleDelete = (name) => {
|
|
@@ -5549,9 +5761,9 @@ function ManageModalContent({ onClose }) {
|
|
|
5549
5761
|
] }) });
|
|
5550
5762
|
}
|
|
5551
5763
|
function ManageComponentsCta() {
|
|
5552
|
-
const [open, setOpen] = (0,
|
|
5764
|
+
const [open, setOpen] = (0, import_react30.useState)(false);
|
|
5553
5765
|
const entries = useRegistrations();
|
|
5554
|
-
const handleClose = (0,
|
|
5766
|
+
const handleClose = (0, import_react30.useCallback)(() => setOpen(false), []);
|
|
5555
5767
|
if (entries.length === 0) return null;
|
|
5556
5768
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
5557
5769
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("button", { className: cx10("cta"), onClick: () => setOpen(true), type: "button", children: [
|