@ohhwells/bridge 0.1.91 → 0.1.92
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 +138 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +138 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -142,6 +142,7 @@ function isRenderableTree(value) {
|
|
|
142
142
|
|
|
143
143
|
// src/lib/ai-sections-store.ts
|
|
144
144
|
var AI_SECTIONS_KEY = "__ohw_ai_sections";
|
|
145
|
+
var AI_SLOT_KEY_PREFIX = "ai.";
|
|
145
146
|
var EMPTY_AI_SECTIONS = { v: 1, sections: [] };
|
|
146
147
|
function parseAiSectionsState(raw) {
|
|
147
148
|
if (!raw) return EMPTY_AI_SECTIONS;
|
|
@@ -185,6 +186,63 @@ function applyTreeToState(state, payload) {
|
|
|
185
186
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
186
187
|
return { ...state, v: 1, sections: [...others, entry] };
|
|
187
188
|
}
|
|
189
|
+
function foldAlignIntoTrees(state, store) {
|
|
190
|
+
const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
|
|
191
|
+
const nextTrees = /* @__PURE__ */ new Map();
|
|
192
|
+
const treeFor = (id) => {
|
|
193
|
+
const cloned = nextTrees.get(id);
|
|
194
|
+
if (cloned) return cloned;
|
|
195
|
+
const entry = byId.get(id);
|
|
196
|
+
if (!entry) return void 0;
|
|
197
|
+
const fresh = {
|
|
198
|
+
...entry.tree,
|
|
199
|
+
rows: entry.tree.rows.map((row) => ({ ...row, blocks: row.blocks.map((block) => ({ ...block })) }))
|
|
200
|
+
};
|
|
201
|
+
nextTrees.set(id, fresh);
|
|
202
|
+
return fresh;
|
|
203
|
+
};
|
|
204
|
+
const nodes = {};
|
|
205
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
206
|
+
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
207
|
+
const tree = match ? treeFor(match[1]) : void 0;
|
|
208
|
+
const block = match && tree ? tree.rows[Number(match[2])]?.blocks[Number(match[3])] : void 0;
|
|
209
|
+
if (!block) {
|
|
210
|
+
nodes[key] = override;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
block.align = override.align;
|
|
214
|
+
const rest = { ...override };
|
|
215
|
+
delete rest.align;
|
|
216
|
+
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
217
|
+
}
|
|
218
|
+
const sections = {};
|
|
219
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
220
|
+
const tree = override.align !== void 0 ? treeFor(sectionId) : void 0;
|
|
221
|
+
if (!tree) {
|
|
222
|
+
sections[sectionId] = override;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
for (const row of tree.rows) {
|
|
226
|
+
for (const block of row.blocks) block.align = override.align;
|
|
227
|
+
}
|
|
228
|
+
const rest = { ...override };
|
|
229
|
+
delete rest.align;
|
|
230
|
+
if (Object.keys(rest).length > 0) sections[sectionId] = rest;
|
|
231
|
+
}
|
|
232
|
+
if (nextTrees.size === 0) return { state, store, changed: false };
|
|
233
|
+
return {
|
|
234
|
+
state: {
|
|
235
|
+
...state,
|
|
236
|
+
v: 1,
|
|
237
|
+
sections: state.sections.map((entry) => {
|
|
238
|
+
const tree = nextTrees.get(entry.id);
|
|
239
|
+
return tree ? { ...entry, tree } : entry;
|
|
240
|
+
})
|
|
241
|
+
},
|
|
242
|
+
store: { v: 1, sections, nodes },
|
|
243
|
+
changed: true
|
|
244
|
+
};
|
|
245
|
+
}
|
|
188
246
|
function removeFromState(state, id) {
|
|
189
247
|
return { ...state, v: 1, sections: state.sections.filter((entry) => entry.id !== id) };
|
|
190
248
|
}
|
|
@@ -403,6 +461,9 @@ function styleSheetCss() {
|
|
|
403
461
|
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
404
462
|
);
|
|
405
463
|
}
|
|
464
|
+
for (const align of ["left", "center", "right"]) {
|
|
465
|
+
rules.push(`[data-ohw-style-align="${align}"] { text-align: ${align} !important; }`);
|
|
466
|
+
}
|
|
406
467
|
return rules.join("\n");
|
|
407
468
|
}
|
|
408
469
|
var STYLE_FONT_LINK_ID = "ohw-style-fonts";
|
|
@@ -429,10 +490,24 @@ var SECTION_ATTRS = {
|
|
|
429
490
|
textDistribution: "data-ohw-style-distribution",
|
|
430
491
|
headlineScale: "data-ohw-style-headline",
|
|
431
492
|
imageAspect: "data-ohw-style-aspect",
|
|
432
|
-
spacing: "data-ohw-style-spacing"
|
|
493
|
+
spacing: "data-ohw-style-spacing",
|
|
494
|
+
align: "data-ohw-style-align"
|
|
433
495
|
};
|
|
434
496
|
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
435
|
-
var NODE_PROPS = [
|
|
497
|
+
var NODE_PROPS = [
|
|
498
|
+
"color",
|
|
499
|
+
"font-family",
|
|
500
|
+
"font-size",
|
|
501
|
+
"background",
|
|
502
|
+
"text-align",
|
|
503
|
+
"justify-content",
|
|
504
|
+
"align-items"
|
|
505
|
+
];
|
|
506
|
+
var ALIGN_JUSTIFY = {
|
|
507
|
+
left: "flex-start",
|
|
508
|
+
center: "center",
|
|
509
|
+
right: "flex-end"
|
|
510
|
+
};
|
|
436
511
|
function saveInline(el, prop) {
|
|
437
512
|
const attr = `data-ohw-style-prev-${prop}`;
|
|
438
513
|
if (el.hasAttribute(attr)) return;
|
|
@@ -476,6 +551,10 @@ function clearNodeProps(root) {
|
|
|
476
551
|
function buttonSurfaceOf(el) {
|
|
477
552
|
return el.closest("a, button") ?? el;
|
|
478
553
|
}
|
|
554
|
+
function alignSubjectOf(el) {
|
|
555
|
+
const button = el.closest('[data-ohw-role="button"]');
|
|
556
|
+
return button?.parentElement ?? el;
|
|
557
|
+
}
|
|
479
558
|
function applyStylesToDom(store) {
|
|
480
559
|
ensureStyleSheet();
|
|
481
560
|
clearSectionAttrs(document);
|
|
@@ -521,6 +600,18 @@ function applyStylesToDom(store) {
|
|
|
521
600
|
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
522
601
|
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
523
602
|
}
|
|
603
|
+
if (override.align !== void 0) {
|
|
604
|
+
const subject = alignSubjectOf(el);
|
|
605
|
+
saveInline(subject, "text-align");
|
|
606
|
+
saveInline(subject, "justify-content");
|
|
607
|
+
subject.style.setProperty("text-align", override.align, "important");
|
|
608
|
+
subject.style.setProperty(
|
|
609
|
+
"justify-content",
|
|
610
|
+
ALIGN_JUSTIFY[override.align] ?? "flex-start",
|
|
611
|
+
"important"
|
|
612
|
+
);
|
|
613
|
+
subject.setAttribute(NODE_WROTE_ATTR, "");
|
|
614
|
+
}
|
|
524
615
|
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
525
616
|
const surface = buttonSurfaceOf(el);
|
|
526
617
|
if (override.buttonBackground !== void 0) {
|
|
@@ -729,7 +820,7 @@ function TextBlock({ slots, ctx, path }) {
|
|
|
729
820
|
}
|
|
730
821
|
function SectionHeaderBlock({ node, ctx, path }) {
|
|
731
822
|
const slots = node.slots ?? {};
|
|
732
|
-
const align = slots.alignment === "center" ? "center" : "left";
|
|
823
|
+
const align = node.align ?? (slots.alignment === "center" ? "center" : "left");
|
|
733
824
|
const children = node.children ?? [];
|
|
734
825
|
const buttonRowIdx = children.findIndex((c) => c.type === "button-row");
|
|
735
826
|
const buttonRow = buttonRowIdx >= 0 ? children[buttonRowIdx] : void 0;
|
|
@@ -773,7 +864,7 @@ function SectionHeaderBlock({ node, ctx, path }) {
|
|
|
773
864
|
display: "flex",
|
|
774
865
|
gap: AI_TREE_TOKENS.spacing6,
|
|
775
866
|
marginTop: AI_TREE_TOKENS.spacing8,
|
|
776
|
-
justifyContent: align === "center" ? "center" : "flex-start"
|
|
867
|
+
justifyContent: align === "center" ? "center" : align === "right" ? "flex-end" : "flex-start"
|
|
777
868
|
},
|
|
778
869
|
children: (buttonRow.children ?? []).map((button, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
779
870
|
ButtonEl,
|
|
@@ -1106,7 +1197,7 @@ function CardBlock({ node, ctx, path }) {
|
|
|
1106
1197
|
editPath: `${path}.media`
|
|
1107
1198
|
}
|
|
1108
1199
|
) : null;
|
|
1109
|
-
const centered = slots.alignment === "center";
|
|
1200
|
+
const centered = (node.align ?? slots.alignment) === "center";
|
|
1110
1201
|
const content = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1111
1202
|
"div",
|
|
1112
1203
|
{
|
|
@@ -1825,6 +1916,19 @@ function AiTreeRenderer({
|
|
|
1825
1916
|
}
|
|
1826
1917
|
})();
|
|
1827
1918
|
const distributed = !isOverlay && settings.textDistribution;
|
|
1919
|
+
const rowAlignItems = (rowAlign) => {
|
|
1920
|
+
if (rowAlign === "top") return "start";
|
|
1921
|
+
if (rowAlign === "bottom") return "end";
|
|
1922
|
+
if (rowAlign === "center" || rowAlign === "stretch") return rowAlign;
|
|
1923
|
+
if (distributed === "space-between") return "stretch";
|
|
1924
|
+
return (distributed ?? settings.verticalPosition) === "top" ? "start" : "center";
|
|
1925
|
+
};
|
|
1926
|
+
const cellAlignStyle = (blockAlign) => blockAlign ? {
|
|
1927
|
+
display: "flex",
|
|
1928
|
+
flexDirection: "column",
|
|
1929
|
+
alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
|
|
1930
|
+
textAlign: blockAlign
|
|
1931
|
+
} : {};
|
|
1828
1932
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1829
1933
|
"section",
|
|
1830
1934
|
{
|
|
@@ -1861,7 +1965,7 @@ function AiTreeRenderer({
|
|
|
1861
1965
|
display: "grid",
|
|
1862
1966
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1863
1967
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1864
|
-
alignItems:
|
|
1968
|
+
alignItems: rowAlignItems(row.align),
|
|
1865
1969
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1866
1970
|
},
|
|
1867
1971
|
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1871,6 +1975,8 @@ function AiTreeRenderer({
|
|
|
1871
1975
|
style: {
|
|
1872
1976
|
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1873
1977
|
minWidth: 0,
|
|
1978
|
+
// Horizontal placement of the block's content within its column.
|
|
1979
|
+
...cellAlignStyle(block.align),
|
|
1874
1980
|
// space-between: each column becomes a flex column whose content spreads over
|
|
1875
1981
|
// the full row height instead of clumping at the top.
|
|
1876
1982
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -20324,12 +20430,35 @@ function OhhwellsBridge() {
|
|
|
20324
20430
|
window.addEventListener("message", handleAiSetBrand);
|
|
20325
20431
|
const handleAiSetStyles = (e) => {
|
|
20326
20432
|
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
20327
|
-
|
|
20433
|
+
let value = typeof e.data.value === "string" ? e.data.value : "";
|
|
20328
20434
|
const previous = stylesRef.current;
|
|
20435
|
+
let previousSections;
|
|
20436
|
+
const store = parseStyleStore(value);
|
|
20437
|
+
if (store) {
|
|
20438
|
+
const folded = foldAlignIntoTrees(parseAiSectionsState(aiSectionsRef.current), store);
|
|
20439
|
+
if (folded.changed) {
|
|
20440
|
+
const nextSections = serializeAiSectionsState(folded.state);
|
|
20441
|
+
if (nextSections !== aiSectionsRef.current) {
|
|
20442
|
+
previousSections = aiSectionsRef.current;
|
|
20443
|
+
aiSectionsRef.current = nextSections;
|
|
20444
|
+
applyAiSectionsToDom(folded.state);
|
|
20445
|
+
postToParentRef.current({
|
|
20446
|
+
type: "ow:change",
|
|
20447
|
+
nodes: [{ key: AI_SECTIONS_KEY, text: nextSections }]
|
|
20448
|
+
});
|
|
20449
|
+
}
|
|
20450
|
+
value = JSON.stringify(folded.store);
|
|
20451
|
+
}
|
|
20452
|
+
}
|
|
20329
20453
|
stylesRef.current = value;
|
|
20330
20454
|
applyStylesToDom(parseStyleStore(value));
|
|
20331
20455
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
20332
|
-
postToParentRef.current({
|
|
20456
|
+
postToParentRef.current({
|
|
20457
|
+
type: "ow:ai-styles-applied",
|
|
20458
|
+
previous,
|
|
20459
|
+
value,
|
|
20460
|
+
...previousSections !== void 0 ? { previousSections } : {}
|
|
20461
|
+
});
|
|
20333
20462
|
};
|
|
20334
20463
|
window.addEventListener("message", handleAiSetStyles);
|
|
20335
20464
|
const handleGetBrand = (e) => {
|
|
@@ -21350,7 +21479,7 @@ function OhhwellsBridge() {
|
|
|
21350
21479
|
postToParent2({
|
|
21351
21480
|
type: "ow:ready",
|
|
21352
21481
|
version: "1",
|
|
21353
|
-
bridgeVersion: "0.1.
|
|
21482
|
+
bridgeVersion: "0.1.91",
|
|
21354
21483
|
path: pathname,
|
|
21355
21484
|
nodes: collectEditableNodes(editContentRef.current),
|
|
21356
21485
|
sections
|