@ohhwells/bridge 0.1.139-next.393 → 0.1.139-next.398
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 +141 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +140 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -87,6 +87,7 @@ __export(index_exports, {
|
|
|
87
87
|
resolveFooterCopyright: () => resolveFooterCopyright,
|
|
88
88
|
serializeAiFooterState: () => serializeAiFooterState,
|
|
89
89
|
stepViableSlide: () => stepViableSlide,
|
|
90
|
+
stripTextAlignCss: () => stripTextAlignCss,
|
|
90
91
|
toggleVariants: () => toggleVariants,
|
|
91
92
|
useOhwCarousel: () => useOhwCarousel,
|
|
92
93
|
validateUrlInput: () => validateUrlInput,
|
|
@@ -1718,7 +1719,8 @@ function labelElement2(el) {
|
|
|
1718
1719
|
return el.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? el.querySelector("[data-ohw-key]");
|
|
1719
1720
|
}
|
|
1720
1721
|
function buttonLabel(el) {
|
|
1721
|
-
|
|
1722
|
+
const label = labelElement2(el);
|
|
1723
|
+
return (label ? label.innerHTML : el.textContent ?? "").trim();
|
|
1722
1724
|
}
|
|
1723
1725
|
function buttonHref(el) {
|
|
1724
1726
|
return el.getAttribute("href") ?? "";
|
|
@@ -1857,7 +1859,7 @@ function duplicateButton(source, content) {
|
|
|
1857
1859
|
stampVariantClass(copy, copyAssignment.variant);
|
|
1858
1860
|
applyButtonStyle(copy, copyAssignment, paintedTokensOf(source) ?? tokens);
|
|
1859
1861
|
const copyLabelEl = labelElement2(copy);
|
|
1860
|
-
if (copyLabelEl) copyLabelEl.
|
|
1862
|
+
if (copyLabelEl) copyLabelEl.innerHTML = label;
|
|
1861
1863
|
let collection = buttonCollectionOf(source);
|
|
1862
1864
|
const collections = readCollections(content);
|
|
1863
1865
|
let collectionId = collection?.getAttribute(COLLECTION_ATTR) ?? "";
|
|
@@ -2183,7 +2185,7 @@ function applySnapshotContent(el, snapshot, content) {
|
|
|
2183
2185
|
const label = labelElement2(el);
|
|
2184
2186
|
if (label) {
|
|
2185
2187
|
if (label.getAttribute("data-ohw-key") !== labelKey) label.setAttribute("data-ohw-key", labelKey);
|
|
2186
|
-
if (label.
|
|
2188
|
+
if (label.innerHTML !== text) label.innerHTML = text;
|
|
2187
2189
|
}
|
|
2188
2190
|
}
|
|
2189
2191
|
function reconcileButtonCollections(doc, content) {
|
|
@@ -4268,7 +4270,7 @@ function buildNavLink(index, href, label, template) {
|
|
|
4268
4270
|
const span = document.createElement("span");
|
|
4269
4271
|
span.setAttribute("data-ohw-editable", "text");
|
|
4270
4272
|
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
4271
|
-
span.
|
|
4273
|
+
span.innerHTML = label;
|
|
4272
4274
|
anchor.appendChild(span);
|
|
4273
4275
|
return anchor;
|
|
4274
4276
|
}
|
|
@@ -6266,6 +6268,26 @@ function applyTreeToState(state, payload) {
|
|
|
6266
6268
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
6267
6269
|
return { ...state, v: 1, sections: [...others, entry] };
|
|
6268
6270
|
}
|
|
6271
|
+
function stripTextAlignCss(html) {
|
|
6272
|
+
return html.replace(/\sstyle="([^"]*)"/gi, (whole, value) => {
|
|
6273
|
+
if (!/text-align\s*:/i.test(value)) return whole;
|
|
6274
|
+
const kept = value.split(";").map((decl) => decl.trim()).filter((decl) => decl && !/^text-align\s*:/i.test(decl)).join("; ");
|
|
6275
|
+
return kept ? ` style="${kept}"` : "";
|
|
6276
|
+
});
|
|
6277
|
+
}
|
|
6278
|
+
function stripTextAlignInValue(value) {
|
|
6279
|
+
if (typeof value === "string") return stripTextAlignCss(value);
|
|
6280
|
+
if (Array.isArray(value)) return value.map(stripTextAlignInValue);
|
|
6281
|
+
if (value && typeof value === "object") {
|
|
6282
|
+
return Object.fromEntries(
|
|
6283
|
+
Object.entries(value).map(([key, inner]) => [
|
|
6284
|
+
key,
|
|
6285
|
+
stripTextAlignInValue(inner)
|
|
6286
|
+
])
|
|
6287
|
+
);
|
|
6288
|
+
}
|
|
6289
|
+
return value;
|
|
6290
|
+
}
|
|
6269
6291
|
function foldAlignIntoTrees(state, store) {
|
|
6270
6292
|
const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
|
|
6271
6293
|
const nextTrees = /* @__PURE__ */ new Map();
|
|
@@ -6288,6 +6310,12 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6288
6310
|
return stripChildAligns(rest);
|
|
6289
6311
|
})
|
|
6290
6312
|
} : node;
|
|
6313
|
+
const stripContentAligns = (node) => ({
|
|
6314
|
+
...node,
|
|
6315
|
+
...node.slots ? { slots: stripTextAlignInValue(node.slots) } : {},
|
|
6316
|
+
...node.children ? { children: node.children.map(stripContentAligns) } : {}
|
|
6317
|
+
});
|
|
6318
|
+
const authoritative = (block) => stripChildAligns(stripContentAligns(block));
|
|
6291
6319
|
const nodes = {};
|
|
6292
6320
|
for (const [key, override] of Object.entries(store.nodes)) {
|
|
6293
6321
|
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
@@ -6299,7 +6327,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6299
6327
|
nodes[key] = override;
|
|
6300
6328
|
continue;
|
|
6301
6329
|
}
|
|
6302
|
-
row.blocks[blockIdx] = { ...
|
|
6330
|
+
row.blocks[blockIdx] = { ...authoritative(block), align: override.align };
|
|
6303
6331
|
const rest = { ...override };
|
|
6304
6332
|
delete rest.align;
|
|
6305
6333
|
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
@@ -6312,7 +6340,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6312
6340
|
continue;
|
|
6313
6341
|
}
|
|
6314
6342
|
for (const row of tree.rows) {
|
|
6315
|
-
row.blocks = row.blocks.map((block) => ({ ...
|
|
6343
|
+
row.blocks = row.blocks.map((block) => ({ ...authoritative(block), align: override.align }));
|
|
6316
6344
|
}
|
|
6317
6345
|
const rest = { ...override };
|
|
6318
6346
|
delete rest.align;
|
|
@@ -10390,7 +10418,12 @@ function AiTreeRenderer({
|
|
|
10390
10418
|
// the full row height instead of clumping at the top.
|
|
10391
10419
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
10392
10420
|
},
|
|
10393
|
-
children: renderNode(
|
|
10421
|
+
children: renderNode(
|
|
10422
|
+
block,
|
|
10423
|
+
ctx,
|
|
10424
|
+
`r${r2}.b${b}`,
|
|
10425
|
+
settings.alignment === "center" ? "center" : "left"
|
|
10426
|
+
)
|
|
10394
10427
|
},
|
|
10395
10428
|
b
|
|
10396
10429
|
))
|
|
@@ -30297,17 +30330,114 @@ function OhhwellsBridge() {
|
|
|
30297
30330
|
value = JSON.stringify(foldedHeight.store);
|
|
30298
30331
|
}
|
|
30299
30332
|
}
|
|
30333
|
+
const restoreNodes = e.data.restoreNodes;
|
|
30334
|
+
const restored = [];
|
|
30335
|
+
if (restoreNodes && typeof restoreNodes === "object") {
|
|
30336
|
+
for (const [key, html] of Object.entries(restoreNodes)) {
|
|
30337
|
+
if (typeof html !== "string") continue;
|
|
30338
|
+
const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
30339
|
+
if (els.length === 0) continue;
|
|
30340
|
+
for (const el of Array.from(els)) el.innerHTML = html;
|
|
30341
|
+
editContentRef.current = { ...editContentRef.current, [key]: html };
|
|
30342
|
+
restored.push({ key, text: html });
|
|
30343
|
+
}
|
|
30344
|
+
}
|
|
30345
|
+
const previousNodes = {};
|
|
30346
|
+
const strippedNodes = [];
|
|
30347
|
+
if (!restoreNodes) {
|
|
30348
|
+
const aligned = parseStyleStore(value);
|
|
30349
|
+
const prior = parseStyleStore(previous);
|
|
30350
|
+
const keys = /* @__PURE__ */ new Set();
|
|
30351
|
+
if (aligned) {
|
|
30352
|
+
for (const [key, override] of Object.entries(aligned.nodes)) {
|
|
30353
|
+
if (override.align === void 0) continue;
|
|
30354
|
+
if (prior?.nodes[key]?.align === override.align) continue;
|
|
30355
|
+
keys.add(key);
|
|
30356
|
+
}
|
|
30357
|
+
for (const [sectionId, override] of Object.entries(aligned.sections)) {
|
|
30358
|
+
if (override.align === void 0) continue;
|
|
30359
|
+
if (prior?.sections[sectionId]?.align === override.align) continue;
|
|
30360
|
+
const escaped = CSS.escape(sectionId);
|
|
30361
|
+
const markers = document.querySelectorAll(
|
|
30362
|
+
`[data-ohw-instance="${escaped}"], [data-ohw-section="${escaped}"]`
|
|
30363
|
+
);
|
|
30364
|
+
for (const marker of Array.from(markers)) {
|
|
30365
|
+
const editables = marker.querySelectorAll(
|
|
30366
|
+
'[data-ohw-key][data-ohw-editable="text"], [data-ohw-key][data-ohw-editable="plain"]'
|
|
30367
|
+
);
|
|
30368
|
+
for (const el of Array.from(editables)) {
|
|
30369
|
+
const key = el.getAttribute("data-ohw-key");
|
|
30370
|
+
if (key) keys.add(key);
|
|
30371
|
+
}
|
|
30372
|
+
}
|
|
30373
|
+
}
|
|
30374
|
+
}
|
|
30375
|
+
for (const key of keys) {
|
|
30376
|
+
if (key.startsWith(AI_SLOT_KEY_PREFIX) || key.startsWith("__ohw_")) continue;
|
|
30377
|
+
const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
30378
|
+
if (els.length === 0) continue;
|
|
30379
|
+
const before = sanitizeHtml(els[0].innerHTML);
|
|
30380
|
+
const after = stripTextAlignCss(before);
|
|
30381
|
+
if (after === before) continue;
|
|
30382
|
+
for (const el of Array.from(els)) el.innerHTML = after;
|
|
30383
|
+
previousNodes[key] = before;
|
|
30384
|
+
editContentRef.current = { ...editContentRef.current, [key]: after };
|
|
30385
|
+
strippedNodes.push({ key, text: after });
|
|
30386
|
+
}
|
|
30387
|
+
}
|
|
30300
30388
|
stylesRef.current = value;
|
|
30301
30389
|
applyStylesToDom(parseStyleStore(value));
|
|
30302
|
-
postToParentRef.current({
|
|
30390
|
+
postToParentRef.current({
|
|
30391
|
+
type: "ow:change",
|
|
30392
|
+
nodes: [{ key: STYLE_STORE_KEY, text: value }, ...strippedNodes, ...restored]
|
|
30393
|
+
});
|
|
30303
30394
|
postToParentRef.current({
|
|
30304
30395
|
type: "ow:ai-styles-applied",
|
|
30305
30396
|
previous,
|
|
30306
30397
|
value,
|
|
30307
|
-
...previousSections !== void 0 ? { previousSections } : {}
|
|
30398
|
+
...previousSections !== void 0 ? { previousSections } : {},
|
|
30399
|
+
...Object.keys(previousNodes).length > 0 ? { previousNodes } : {}
|
|
30308
30400
|
});
|
|
30309
30401
|
};
|
|
30310
30402
|
window.addEventListener("message", handleAiSetStyles);
|
|
30403
|
+
const handleAiSetButtonStyle = (e) => {
|
|
30404
|
+
if (e.data?.type !== "ow:ai-set-button-style") return;
|
|
30405
|
+
const nodeKey = typeof e.data.hrefKey === "string" ? e.data.hrefKey : "";
|
|
30406
|
+
const keyed = nodeKey ? document.querySelector(
|
|
30407
|
+
`[data-ohw-href-key="${CSS.escape(nodeKey)}"], [data-ohw-key="${CSS.escape(nodeKey)}"]`
|
|
30408
|
+
) : null;
|
|
30409
|
+
const hrefKey = buttonId(keyed);
|
|
30410
|
+
const el = hrefKey ? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) : null;
|
|
30411
|
+
const previous = editContentRef.current[BUTTON_ASSIGNMENTS_KEY] ?? "";
|
|
30412
|
+
if (!el || !hrefKey || !isCtaButton(el)) {
|
|
30413
|
+
postToParentRef.current({ type: "ow:ai-button-style-applied", ok: false, previous, value: previous });
|
|
30414
|
+
return;
|
|
30415
|
+
}
|
|
30416
|
+
const tokens = tokensFromButton(el);
|
|
30417
|
+
const current = assignmentFor(el, editContentRef.current, tokens);
|
|
30418
|
+
const patch = e.data.assignment;
|
|
30419
|
+
const next = {
|
|
30420
|
+
variant: patch?.variant ?? current.variant,
|
|
30421
|
+
size: patch?.size ?? current.size
|
|
30422
|
+
};
|
|
30423
|
+
const value = typeof e.data.assignments === "string" ? e.data.assignments : JSON.stringify(withAssignment(editContentRef.current, hrefKey, next));
|
|
30424
|
+
editContentRef.current = { ...editContentRef.current, [BUTTON_ASSIGNMENTS_KEY]: value };
|
|
30425
|
+
applyButtonStyle(el, next, tokens);
|
|
30426
|
+
postToParentRef.current({
|
|
30427
|
+
type: "ow:change",
|
|
30428
|
+
nodes: [{ key: BUTTON_ASSIGNMENTS_KEY, text: value }]
|
|
30429
|
+
});
|
|
30430
|
+
postToParentRef.current({
|
|
30431
|
+
type: "ow:ai-button-style-applied",
|
|
30432
|
+
ok: true,
|
|
30433
|
+
// The resolved id, which may differ from the key the editor sent — undo must target this one.
|
|
30434
|
+
hrefKey,
|
|
30435
|
+
previous,
|
|
30436
|
+
previousAssignment: current,
|
|
30437
|
+
value
|
|
30438
|
+
});
|
|
30439
|
+
};
|
|
30440
|
+
window.addEventListener("message", handleAiSetButtonStyle);
|
|
30311
30441
|
const handleGetBrand = (e) => {
|
|
30312
30442
|
if (e.data?.type !== "ow:get-brand") return;
|
|
30313
30443
|
const template = deriveTemplateBrand();
|
|
@@ -31347,6 +31477,7 @@ function OhhwellsBridge() {
|
|
|
31347
31477
|
window.removeEventListener("message", handleAiSetSections);
|
|
31348
31478
|
window.removeEventListener("message", handleAiSetBrand);
|
|
31349
31479
|
window.removeEventListener("message", handleAiSetStyles);
|
|
31480
|
+
window.removeEventListener("message", handleAiSetButtonStyle);
|
|
31350
31481
|
window.removeEventListener("message", handleCollectItems);
|
|
31351
31482
|
window.removeEventListener("message", handleAiApplyItems);
|
|
31352
31483
|
window.removeEventListener("message", handleGetBrand);
|
|
@@ -32886,6 +33017,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
|
|
|
32886
33017
|
resolveFooterCopyright,
|
|
32887
33018
|
serializeAiFooterState,
|
|
32888
33019
|
stepViableSlide,
|
|
33020
|
+
stripTextAlignCss,
|
|
32889
33021
|
toggleVariants,
|
|
32890
33022
|
useOhwCarousel,
|
|
32891
33023
|
validateUrlInput,
|