@ohhwells/bridge 0.1.144 → 0.1.146
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.cjs +200 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +200 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -28,6 +28,14 @@ interface AiBlockNode {
|
|
|
28
28
|
align?: 'left' | 'center' | 'right';
|
|
29
29
|
slots?: Record<string, unknown>;
|
|
30
30
|
children?: AiBlockNode[];
|
|
31
|
+
/** Stable id for ordered insertion. Omitted on trees saved before slots. */
|
|
32
|
+
ref?: string;
|
|
33
|
+
/** Fixed slot inside a split (`left`/`right`) or grid (`cell-N`). Omit to keep index order. */
|
|
34
|
+
slot?: string;
|
|
35
|
+
/** Unfilled fixed slots on a group. The published page draws none of these. */
|
|
36
|
+
emptySlots?: string[];
|
|
37
|
+
/** Stack wrapped around a slot that was filled a second time. */
|
|
38
|
+
promoted?: true;
|
|
31
39
|
/** Shape is per-block-type, defined by the backend's `BlockDef.itemFields` (accordion's
|
|
32
40
|
* question/answer, media-strip's assetId/alt/href/linkTarget, footer link-list/hours/social-row). */
|
|
33
41
|
items?: Array<Record<string, unknown>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,14 @@ interface AiBlockNode {
|
|
|
28
28
|
align?: 'left' | 'center' | 'right';
|
|
29
29
|
slots?: Record<string, unknown>;
|
|
30
30
|
children?: AiBlockNode[];
|
|
31
|
+
/** Stable id for ordered insertion. Omitted on trees saved before slots. */
|
|
32
|
+
ref?: string;
|
|
33
|
+
/** Fixed slot inside a split (`left`/`right`) or grid (`cell-N`). Omit to keep index order. */
|
|
34
|
+
slot?: string;
|
|
35
|
+
/** Unfilled fixed slots on a group. The published page draws none of these. */
|
|
36
|
+
emptySlots?: string[];
|
|
37
|
+
/** Stack wrapped around a slot that was filled a second time. */
|
|
38
|
+
promoted?: true;
|
|
31
39
|
/** Shape is per-block-type, defined by the backend's `BlockDef.itemFields` (accordion's
|
|
32
40
|
* question/answer, media-strip's assetId/alt/href/linkTarget, footer link-list/hours/social-row). */
|
|
33
41
|
items?: Array<Record<string, unknown>>;
|
package/dist/index.js
CHANGED
|
@@ -2440,6 +2440,49 @@ function socialHrefKey(item) {
|
|
|
2440
2440
|
function socialIconKey(item) {
|
|
2441
2441
|
return item.querySelector(ICON_SELECTOR)?.dataset.ohwKey ?? null;
|
|
2442
2442
|
}
|
|
2443
|
+
var SOCIAL_PLATFORM_LABELS = {
|
|
2444
|
+
instagram: "Instagram",
|
|
2445
|
+
facebook: "Facebook",
|
|
2446
|
+
x: "X",
|
|
2447
|
+
twitter: "X",
|
|
2448
|
+
tiktok: "TikTok",
|
|
2449
|
+
youtube: "YouTube",
|
|
2450
|
+
linkedin: "LinkedIn",
|
|
2451
|
+
pinterest: "Pinterest",
|
|
2452
|
+
whatsapp: "WhatsApp",
|
|
2453
|
+
telegram: "Telegram",
|
|
2454
|
+
spotify: "Spotify",
|
|
2455
|
+
threads: "Threads",
|
|
2456
|
+
vimeo: "Vimeo",
|
|
2457
|
+
discord: "Discord",
|
|
2458
|
+
medium: "Medium",
|
|
2459
|
+
website: "Website"
|
|
2460
|
+
};
|
|
2461
|
+
function socialPlatformLabel(item, content) {
|
|
2462
|
+
const iconKey = socialIconKey(item);
|
|
2463
|
+
const chosen = iconKey ? (content[socialPlatformKey(iconKey)] ?? "").trim().toLowerCase() : "";
|
|
2464
|
+
if (chosen) return SOCIAL_PLATFORM_LABELS[chosen] ?? chosen.charAt(0).toUpperCase() + chosen.slice(1);
|
|
2465
|
+
const label = socialLabelElement(item);
|
|
2466
|
+
const words = label && !label.hasAttribute(SOCIALS_EMPTY_LABEL_ATTR) ? (label.textContent ?? "").replace(/\s+/g, " ").trim() : "";
|
|
2467
|
+
if (words) return words;
|
|
2468
|
+
const link = item.matches("a") ? item : item.querySelector("a");
|
|
2469
|
+
const aria = (link?.getAttribute("aria-label") ?? item.getAttribute("aria-label") ?? "").trim();
|
|
2470
|
+
if (aria) return aria;
|
|
2471
|
+
const href = (link?.getAttribute("href") ?? "").trim();
|
|
2472
|
+
if (/^https?:\/\//i.test(href)) {
|
|
2473
|
+
let host = "";
|
|
2474
|
+
try {
|
|
2475
|
+
host = new URL(href).hostname.replace(/^www\./i, "").toLowerCase();
|
|
2476
|
+
} catch {
|
|
2477
|
+
host = "";
|
|
2478
|
+
}
|
|
2479
|
+
if (host.includes("x.com") || host.includes("twitter.com")) return "X";
|
|
2480
|
+
for (const [id, name] of Object.entries(SOCIAL_PLATFORM_LABELS)) {
|
|
2481
|
+
if (host.includes(id)) return name;
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
return "Social";
|
|
2485
|
+
}
|
|
2443
2486
|
var SOCIALS_ORDER_KEY = "__ohw_socials_order";
|
|
2444
2487
|
function fromMarkup(markup) {
|
|
2445
2488
|
const holder = document.createElement("div");
|
|
@@ -6121,7 +6164,9 @@ function applyTreeToState(state, payload) {
|
|
|
6121
6164
|
...selfEdit ? priorEntry?.beforeSection ? { beforeSection: priorEntry.beforeSection } : {} : insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
6122
6165
|
...selfEdit ? priorEntry?.replaces ? { replaces: priorEntry.replaces } : {} : payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
6123
6166
|
tree: payload.tree,
|
|
6124
|
-
media
|
|
6167
|
+
// A column insert rebuilds the media map from the live DOM keys. The photo
|
|
6168
|
+
// still points at the ref it was generated with. Keep that ref.
|
|
6169
|
+
media: { ...priorEntry?.media ?? {}, ...payload.media ?? {} },
|
|
6125
6170
|
...payload.brand && typeof payload.brand === "object" ? { brand: payload.brand } : {}
|
|
6126
6171
|
};
|
|
6127
6172
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
@@ -9622,6 +9667,46 @@ function FooterSocialRowBlock({
|
|
|
9622
9667
|
}
|
|
9623
9668
|
);
|
|
9624
9669
|
}
|
|
9670
|
+
function EmptySlotPlaceholder({ name }) {
|
|
9671
|
+
return /* @__PURE__ */ jsx(
|
|
9672
|
+
"div",
|
|
9673
|
+
{
|
|
9674
|
+
"data-ai-slot": name,
|
|
9675
|
+
"data-ai-slot-empty": "",
|
|
9676
|
+
"aria-hidden": "true",
|
|
9677
|
+
style: {
|
|
9678
|
+
minHeight: 88,
|
|
9679
|
+
borderRadius: 12,
|
|
9680
|
+
border: "1px dashed #D6D3D1",
|
|
9681
|
+
display: "flex",
|
|
9682
|
+
alignItems: "center",
|
|
9683
|
+
justifyContent: "center",
|
|
9684
|
+
padding: 16,
|
|
9685
|
+
color: "#A8A29E",
|
|
9686
|
+
fontSize: 13,
|
|
9687
|
+
lineHeight: 1.4,
|
|
9688
|
+
textAlign: "center",
|
|
9689
|
+
pointerEvents: "none"
|
|
9690
|
+
},
|
|
9691
|
+
children: "Ask AI to add something here"
|
|
9692
|
+
}
|
|
9693
|
+
);
|
|
9694
|
+
}
|
|
9695
|
+
function splitSides(node) {
|
|
9696
|
+
const named = /* @__PURE__ */ new Map();
|
|
9697
|
+
const unnamed = [];
|
|
9698
|
+
(node.children ?? []).forEach((child, index) => {
|
|
9699
|
+
if (child.slot === "left" || child.slot === "right") {
|
|
9700
|
+
named.set(child.slot, { node: child, index });
|
|
9701
|
+
} else {
|
|
9702
|
+
unnamed.push({ node: child, index });
|
|
9703
|
+
}
|
|
9704
|
+
});
|
|
9705
|
+
return {
|
|
9706
|
+
left: named.get("left") ?? unnamed.shift() ?? null,
|
|
9707
|
+
right: named.get("right") ?? unnamed.shift() ?? null
|
|
9708
|
+
};
|
|
9709
|
+
}
|
|
9625
9710
|
function renderNode(node, ctx, path, ambientAlign) {
|
|
9626
9711
|
const slots = node.slots ?? {};
|
|
9627
9712
|
switch (node.type) {
|
|
@@ -9629,9 +9714,11 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9629
9714
|
return /* @__PURE__ */ jsx(TextBlock, { slots, ctx, path, align: node.align ?? ambientAlign });
|
|
9630
9715
|
// Layout container: arranges child blocks, contributes no content of its own. `grid` is a
|
|
9631
9716
|
// nested 12-column grid the children span (a collage is 3–5 media on it, bottom-aligned so
|
|
9632
|
-
// mixed aspects read as a composition); `split` is
|
|
9633
|
-
// is a column.
|
|
9634
|
-
//
|
|
9717
|
+
// mixed aspects read as a composition); `split` is left and right (index order when `slot`
|
|
9718
|
+
// is omitted); `stack` is a column. A missing split side is a canvas placeholder only when
|
|
9719
|
+
// `emptySlots` names it. A one-child split used to keep a row at span 12 (a testimonial
|
|
9720
|
+
// under a heading) sits centered at half the row width. Children render through this same
|
|
9721
|
+
// dispatcher, so edit markers, media resolution, and copy paths all work unchanged.
|
|
9635
9722
|
case "group": {
|
|
9636
9723
|
const layout = str(slots.layout);
|
|
9637
9724
|
const gap = slots.spacing === "tight" ? AI_TREE_TOKENS.spacing3 : slots.spacing === "airy" ? AI_TREE_TOKENS.spacing8 : AI_TREE_TOKENS.spacing6;
|
|
@@ -9729,24 +9816,38 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9729
9816
|
i
|
|
9730
9817
|
));
|
|
9731
9818
|
if (layout === "grid") {
|
|
9732
|
-
|
|
9819
|
+
const holes = ctx.keyFor ? node.emptySlots ?? [] : [];
|
|
9820
|
+
return /* @__PURE__ */ jsxs(
|
|
9733
9821
|
"div",
|
|
9734
9822
|
{
|
|
9735
9823
|
"data-ai-group": "grid",
|
|
9736
9824
|
style: { display: "grid", gridTemplateColumns: "repeat(12, 1fr)", gap, alignItems: "end" },
|
|
9737
|
-
children:
|
|
9825
|
+
children: [
|
|
9826
|
+
kids,
|
|
9827
|
+
holes.map((name) => /* @__PURE__ */ jsx("div", { style: { gridColumn: "span 6", minWidth: 0 }, children: /* @__PURE__ */ jsx(EmptySlotPlaceholder, { name }) }, name))
|
|
9828
|
+
]
|
|
9738
9829
|
}
|
|
9739
9830
|
);
|
|
9740
9831
|
}
|
|
9741
9832
|
if (layout === "split") {
|
|
9833
|
+
const { left, right } = splitSides(node);
|
|
9834
|
+
const open = new Set(ctx.keyFor ? node.emptySlots ?? [] : []);
|
|
9835
|
+
const side = (entry, name) => entry ? /* @__PURE__ */ jsx("div", { style: { minWidth: 0 }, children: renderNode(entry.node, ctx, `${path}.c${entry.index}`) }, name) : open.has(name) ? /* @__PURE__ */ jsx(EmptySlotPlaceholder, { name }, name) : null;
|
|
9836
|
+
if (!left && !open.has("left") || !right && !open.has("right")) {
|
|
9837
|
+
const only = left ?? right;
|
|
9838
|
+
return only ? /* @__PURE__ */ jsx("div", { "data-ai-group": "split", style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx("div", { style: { width: "50%", minWidth: 0 }, children: renderNode(only.node, ctx, `${path}.c${only.index}`) }) }) : null;
|
|
9839
|
+
}
|
|
9742
9840
|
const ratio = str(slots.ratio);
|
|
9743
9841
|
const cols = ratio === "3:5" ? "3fr 5fr" : ratio === "5:3" ? "5fr 3fr" : "1fr 1fr";
|
|
9744
|
-
return /* @__PURE__ */
|
|
9842
|
+
return /* @__PURE__ */ jsxs(
|
|
9745
9843
|
"div",
|
|
9746
9844
|
{
|
|
9747
9845
|
"data-ai-group": "split",
|
|
9748
9846
|
style: { display: "grid", gridTemplateColumns: cols, gap, alignItems: "center" },
|
|
9749
|
-
children:
|
|
9847
|
+
children: [
|
|
9848
|
+
side(left, "left"),
|
|
9849
|
+
side(right, "right")
|
|
9850
|
+
]
|
|
9750
9851
|
}
|
|
9751
9852
|
);
|
|
9752
9853
|
}
|
|
@@ -25087,36 +25188,72 @@ function OhhwellsBridge() {
|
|
|
25087
25188
|
const [selectedMedia, setSelectedMedia] = useState18(null);
|
|
25088
25189
|
const selectedMediaElRef = useRef14(null);
|
|
25089
25190
|
const mediaKeyDropTokenRef = useRef14(0);
|
|
25191
|
+
const selectedIconElRef = useRef14(null);
|
|
25192
|
+
const selectedSocialElRef = useRef14(null);
|
|
25193
|
+
const queueSectionKeyDrop = useCallback12((prev) => {
|
|
25194
|
+
const sectionEl = prev?.closest("[data-ohw-section]") ?? null;
|
|
25195
|
+
if (!sectionEl) return;
|
|
25196
|
+
const sectionInstanceId = instanceIdOf(movableUnit(sectionEl)) || null;
|
|
25197
|
+
if (!sectionInstanceId) return;
|
|
25198
|
+
const token = ++mediaKeyDropTokenRef.current;
|
|
25199
|
+
const onQueueDrained = (e) => {
|
|
25200
|
+
if (e.source !== window || e.data?.type !== "ow:media-key-drop" || e.data.token !== token) return;
|
|
25201
|
+
window.removeEventListener("message", onQueueDrained);
|
|
25202
|
+
if (aiSectionApiRef.current?.getSelectedId() !== sectionInstanceId) return;
|
|
25203
|
+
if (selectedMediaElRef.current || selectedIconElRef.current || selectedSocialElRef.current) return;
|
|
25204
|
+
postToParentRef.current({
|
|
25205
|
+
type: "ow:section-selected",
|
|
25206
|
+
sectionId: sectionEl.dataset.ohwSection ?? null,
|
|
25207
|
+
sectionLabel: sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? ""),
|
|
25208
|
+
key: null
|
|
25209
|
+
});
|
|
25210
|
+
};
|
|
25211
|
+
window.addEventListener("message", onQueueDrained);
|
|
25212
|
+
window.postMessage({ type: "ow:media-key-drop", token }, "*");
|
|
25213
|
+
}, []);
|
|
25090
25214
|
const clearMediaSelection = useCallback12(() => {
|
|
25091
25215
|
const prev = selectedMediaElRef.current;
|
|
25092
25216
|
selectedMediaElRef.current = null;
|
|
25093
25217
|
setSelectedMedia(null);
|
|
25094
|
-
|
|
25095
|
-
|
|
25096
|
-
const sectionInstanceId = instanceIdOf(movableUnit(sectionEl)) || null;
|
|
25097
|
-
if (!sectionInstanceId) return;
|
|
25098
|
-
const token = ++mediaKeyDropTokenRef.current;
|
|
25099
|
-
const onQueueDrained = (e) => {
|
|
25100
|
-
if (e.source !== window || e.data?.type !== "ow:media-key-drop" || e.data.token !== token) return;
|
|
25101
|
-
window.removeEventListener("message", onQueueDrained);
|
|
25102
|
-
if (aiSectionApiRef.current?.getSelectedId() !== sectionInstanceId) return;
|
|
25103
|
-
if (selectedMediaElRef.current) return;
|
|
25104
|
-
postToParentRef.current({
|
|
25105
|
-
type: "ow:section-selected",
|
|
25106
|
-
sectionId: sectionEl.dataset.ohwSection ?? null,
|
|
25107
|
-
sectionLabel: sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? ""),
|
|
25108
|
-
key: null
|
|
25109
|
-
});
|
|
25110
|
-
};
|
|
25111
|
-
window.addEventListener("message", onQueueDrained);
|
|
25112
|
-
window.postMessage({ type: "ow:media-key-drop", token }, "*");
|
|
25113
|
-
}
|
|
25114
|
-
}, []);
|
|
25218
|
+
queueSectionKeyDrop(prev);
|
|
25219
|
+
}, [queueSectionKeyDrop]);
|
|
25115
25220
|
const clearMediaSelectionRef = useRef14(clearMediaSelection);
|
|
25116
25221
|
clearMediaSelectionRef.current = clearMediaSelection;
|
|
25222
|
+
const clearIconSelection = useCallback12(() => {
|
|
25223
|
+
const prev = selectedIconElRef.current;
|
|
25224
|
+
if (!prev) return;
|
|
25225
|
+
selectedIconElRef.current = null;
|
|
25226
|
+
queueSectionKeyDrop(prev);
|
|
25227
|
+
}, [queueSectionKeyDrop]);
|
|
25228
|
+
const clearIconSelectionRef = useRef14(clearIconSelection);
|
|
25229
|
+
clearIconSelectionRef.current = clearIconSelection;
|
|
25230
|
+
const clearSocialSelection = useCallback12(() => {
|
|
25231
|
+
const prev = selectedSocialElRef.current;
|
|
25232
|
+
if (!prev) return;
|
|
25233
|
+
selectedSocialElRef.current = null;
|
|
25234
|
+
queueSectionKeyDrop(prev);
|
|
25235
|
+
}, [queueSectionKeyDrop]);
|
|
25236
|
+
const clearSocialSelectionRef = useRef14(clearSocialSelection);
|
|
25237
|
+
clearSocialSelectionRef.current = clearSocialSelection;
|
|
25238
|
+
const selectIconElement = useCallback12((el) => {
|
|
25239
|
+
if (selectedMediaElRef.current) clearMediaSelectionRef.current();
|
|
25240
|
+
selectedIconElRef.current = el;
|
|
25241
|
+
const sectionEl = el.closest("[data-ohw-section]");
|
|
25242
|
+
aiSectionApiRef.current?.selectFromElement(el, { report: false });
|
|
25243
|
+
postToParentRef.current({
|
|
25244
|
+
type: "ow:section-selected",
|
|
25245
|
+
sectionId: sectionEl?.dataset.ohwSection ?? null,
|
|
25246
|
+
sectionLabel: sectionEl ? sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? "") : null,
|
|
25247
|
+
key: el.dataset.ohwKey ?? null,
|
|
25248
|
+
keyLabel: "Icon"
|
|
25249
|
+
});
|
|
25250
|
+
}, []);
|
|
25251
|
+
const selectIconElementRef = useRef14(selectIconElement);
|
|
25252
|
+
selectIconElementRef.current = selectIconElement;
|
|
25117
25253
|
const selectMediaElement = useCallback12((el) => {
|
|
25118
25254
|
const r2 = el.getBoundingClientRect();
|
|
25119
25255
|
const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
|
|
25256
|
+
selectedIconElRef.current = null;
|
|
25120
25257
|
selectedMediaElRef.current = el;
|
|
25121
25258
|
setSelectedMedia({
|
|
25122
25259
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -25770,6 +25907,7 @@ function OhhwellsBridge() {
|
|
|
25770
25907
|
selectedElRef.current = null;
|
|
25771
25908
|
selectedHrefKeyRef.current = null;
|
|
25772
25909
|
selectedFooterColAttrRef.current = null;
|
|
25910
|
+
clearSocialSelectionRef.current();
|
|
25773
25911
|
setSelectedIsCta(false);
|
|
25774
25912
|
setSelectedIsSocial(false);
|
|
25775
25913
|
setSelectedIsSocialsRow(false);
|
|
@@ -26671,7 +26809,22 @@ function OhhwellsBridge() {
|
|
|
26671
26809
|
const select = useCallback12((anchor) => {
|
|
26672
26810
|
if (!isNavigationItem2(anchor)) return;
|
|
26673
26811
|
if (activeElRef.current) deactivate();
|
|
26674
|
-
|
|
26812
|
+
clearSocialSelectionRef.current();
|
|
26813
|
+
const socialItem = getSocialItem(anchor);
|
|
26814
|
+
if (socialItem) {
|
|
26815
|
+
selectedSocialElRef.current = socialItem;
|
|
26816
|
+
const sectionEl = socialItem.closest("[data-ohw-section]");
|
|
26817
|
+
aiSectionApiRef.current?.selectFromElement(anchor, { report: false });
|
|
26818
|
+
postToParentRef.current({
|
|
26819
|
+
type: "ow:section-selected",
|
|
26820
|
+
sectionId: sectionEl?.dataset.ohwSection ?? null,
|
|
26821
|
+
sectionLabel: sectionEl ? sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? "") : null,
|
|
26822
|
+
key: socialIconKey(socialItem) ?? socialItem.getAttribute("data-ohw-href-key"),
|
|
26823
|
+
keyLabel: socialPlatformLabel(socialItem, editContentRef.current)
|
|
26824
|
+
});
|
|
26825
|
+
} else {
|
|
26826
|
+
aiSectionApiRef.current?.selectFromElement(anchor);
|
|
26827
|
+
}
|
|
26675
26828
|
selectedElRef.current = anchor;
|
|
26676
26829
|
selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
|
|
26677
26830
|
selectedFooterColAttrRef.current = null;
|
|
@@ -27809,8 +27962,11 @@ function OhhwellsBridge() {
|
|
|
27809
27962
|
display: none !important;
|
|
27810
27963
|
}
|
|
27811
27964
|
/* Body text (no item-action toolbar) \u2014 first click enters text edit \u2192 I-beam.
|
|
27812
|
-
Exclude select-first nav/footer labels so grab/default on [data-ohw-href-key] can win.
|
|
27813
|
-
|
|
27965
|
+
Exclude select-first nav/footer labels so grab/default on [data-ohw-href-key] can win.
|
|
27966
|
+
Icons are excluded too: a glyph is replaced by a click, never typed into (OHH-623),
|
|
27967
|
+
so it takes the picker's pointer below, not an I-beam \u2014 this blanket !important used
|
|
27968
|
+
to beat the stylesheet's own non-!important icon rule (OHH-718). */
|
|
27969
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="link"]):not([data-ohw-editable="icon"]):not(:is([data-ohw-href-key] *)) {
|
|
27814
27970
|
cursor: text !important;
|
|
27815
27971
|
}
|
|
27816
27972
|
/* Select-first items: default arrow; grab only when drag-start is allowed (data-ohw-can-drag). */
|
|
@@ -27831,6 +27987,7 @@ function OhhwellsBridge() {
|
|
|
27831
27987
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
27832
27988
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
27833
27989
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
27990
|
+
[data-ohw-editable="icon"], [data-ohw-editable="icon"] * { cursor: pointer !important; }
|
|
27834
27991
|
/* A text/plain editable nested inside a media editable (e.g. a placeholder's fallback
|
|
27835
27992
|
label inside its bg-image box) is its own click target, not the media picker \u2014 the
|
|
27836
27993
|
blanket media cursor rule above would otherwise show pointer where a click actually
|
|
@@ -27982,6 +28139,9 @@ function OhhwellsBridge() {
|
|
|
27982
28139
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
27983
28140
|
clearMediaSelectionRef.current();
|
|
27984
28141
|
}
|
|
28142
|
+
if (selectedIconElRef.current && !selectedIconElRef.current.contains(target)) {
|
|
28143
|
+
clearIconSelectionRef.current();
|
|
28144
|
+
}
|
|
27985
28145
|
if (selectedMediaElRef.current && target.closest("[data-ohw-media-overlay]") && !findClosestButtonLike(target)) {
|
|
27986
28146
|
const hit = findImageAtPoint(e.clientX, e.clientY, false);
|
|
27987
28147
|
if (hit && hit !== selectedMediaElRef.current) {
|
|
@@ -28159,7 +28319,7 @@ function OhhwellsBridge() {
|
|
|
28159
28319
|
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
28160
28320
|
e.preventDefault();
|
|
28161
28321
|
e.stopPropagation();
|
|
28162
|
-
|
|
28322
|
+
selectIconElementRef.current(editable);
|
|
28163
28323
|
const aiIcon = editable.hasAttribute("data-ai-icon");
|
|
28164
28324
|
const featureIcon = aiIcon && /\.features\.\d+\.icon$/.test(editable.dataset.ohwKey ?? "");
|
|
28165
28325
|
postToParentRef.current({
|
|
@@ -29783,6 +29943,7 @@ function OhhwellsBridge() {
|
|
|
29783
29943
|
deactivateRef.current();
|
|
29784
29944
|
deselectRef.current();
|
|
29785
29945
|
clearMediaSelectionRef.current();
|
|
29946
|
+
clearIconSelectionRef.current();
|
|
29786
29947
|
};
|
|
29787
29948
|
clearInteractionChromeRef.current = clearInteractionChrome;
|
|
29788
29949
|
const applyTreeToLocalState = (payload) => {
|
|
@@ -30200,6 +30361,7 @@ function OhhwellsBridge() {
|
|
|
30200
30361
|
deselectRef.current();
|
|
30201
30362
|
deactivateRef.current();
|
|
30202
30363
|
clearMediaSelectionRef.current();
|
|
30364
|
+
clearIconSelectionRef.current();
|
|
30203
30365
|
};
|
|
30204
30366
|
window.addEventListener("message", handleDeactivate);
|
|
30205
30367
|
const handleToastAction = (e) => {
|
|
@@ -30289,6 +30451,10 @@ function OhhwellsBridge() {
|
|
|
30289
30451
|
clearMediaSelectionRef.current();
|
|
30290
30452
|
return;
|
|
30291
30453
|
}
|
|
30454
|
+
if (e.key === "Escape" && selectedIconElRef.current) {
|
|
30455
|
+
clearIconSelectionRef.current();
|
|
30456
|
+
return;
|
|
30457
|
+
}
|
|
30292
30458
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
30293
30459
|
e.preventDefault();
|
|
30294
30460
|
selectAllTextInEditable(activeElRef.current);
|
|
@@ -31310,7 +31476,7 @@ function OhhwellsBridge() {
|
|
|
31310
31476
|
postToParent2({
|
|
31311
31477
|
type: "ow:ready",
|
|
31312
31478
|
version: "1",
|
|
31313
|
-
bridgeVersion: "0.1.
|
|
31479
|
+
bridgeVersion: "0.1.145",
|
|
31314
31480
|
path: pathname,
|
|
31315
31481
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31316
31482
|
sections
|