@ohhwells/bridge 0.1.80-next.242 → 0.1.80-next.244
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 +107 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +107 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -143,6 +143,7 @@ function isRenderableTree(value) {
|
|
|
143
143
|
|
|
144
144
|
// src/lib/ai-sections-store.ts
|
|
145
145
|
var AI_SECTIONS_KEY = "__ohw_ai_sections";
|
|
146
|
+
var AI_SLOT_KEY_PREFIX = "ai.";
|
|
146
147
|
var EMPTY_AI_SECTIONS = { v: 1, sections: [] };
|
|
147
148
|
function parseAiSectionsState(raw) {
|
|
148
149
|
if (!raw) return EMPTY_AI_SECTIONS;
|
|
@@ -186,6 +187,63 @@ function applyTreeToState(state, payload) {
|
|
|
186
187
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
187
188
|
return { ...state, v: 1, sections: [...others, entry] };
|
|
188
189
|
}
|
|
190
|
+
function foldAlignIntoTrees(state, store) {
|
|
191
|
+
const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
|
|
192
|
+
const nextTrees = /* @__PURE__ */ new Map();
|
|
193
|
+
const treeFor = (id) => {
|
|
194
|
+
const cloned = nextTrees.get(id);
|
|
195
|
+
if (cloned) return cloned;
|
|
196
|
+
const entry = byId.get(id);
|
|
197
|
+
if (!entry) return void 0;
|
|
198
|
+
const fresh = {
|
|
199
|
+
...entry.tree,
|
|
200
|
+
rows: entry.tree.rows.map((row) => ({ ...row, blocks: row.blocks.map((block) => ({ ...block })) }))
|
|
201
|
+
};
|
|
202
|
+
nextTrees.set(id, fresh);
|
|
203
|
+
return fresh;
|
|
204
|
+
};
|
|
205
|
+
const nodes = {};
|
|
206
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
207
|
+
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
208
|
+
const tree = match ? treeFor(match[1]) : void 0;
|
|
209
|
+
const block = match && tree ? tree.rows[Number(match[2])]?.blocks[Number(match[3])] : void 0;
|
|
210
|
+
if (!block) {
|
|
211
|
+
nodes[key] = override;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
block.align = override.align;
|
|
215
|
+
const rest = { ...override };
|
|
216
|
+
delete rest.align;
|
|
217
|
+
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
218
|
+
}
|
|
219
|
+
const sections = {};
|
|
220
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
221
|
+
const tree = override.align !== void 0 ? treeFor(sectionId) : void 0;
|
|
222
|
+
if (!tree) {
|
|
223
|
+
sections[sectionId] = override;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
for (const row of tree.rows) {
|
|
227
|
+
for (const block of row.blocks) block.align = override.align;
|
|
228
|
+
}
|
|
229
|
+
const rest = { ...override };
|
|
230
|
+
delete rest.align;
|
|
231
|
+
if (Object.keys(rest).length > 0) sections[sectionId] = rest;
|
|
232
|
+
}
|
|
233
|
+
if (nextTrees.size === 0) return { state, store, changed: false };
|
|
234
|
+
return {
|
|
235
|
+
state: {
|
|
236
|
+
...state,
|
|
237
|
+
v: 1,
|
|
238
|
+
sections: state.sections.map((entry) => {
|
|
239
|
+
const tree = nextTrees.get(entry.id);
|
|
240
|
+
return tree ? { ...entry, tree } : entry;
|
|
241
|
+
})
|
|
242
|
+
},
|
|
243
|
+
store: { v: 1, sections, nodes },
|
|
244
|
+
changed: true
|
|
245
|
+
};
|
|
246
|
+
}
|
|
189
247
|
function removeFromState(state, id) {
|
|
190
248
|
return { ...state, v: 1, sections: state.sections.filter((entry) => entry.id !== id) };
|
|
191
249
|
}
|
|
@@ -378,6 +436,9 @@ function styleSheetCss() {
|
|
|
378
436
|
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
379
437
|
);
|
|
380
438
|
}
|
|
439
|
+
for (const align of ["left", "center", "right"]) {
|
|
440
|
+
rules.push(`[data-ohw-style-align="${align}"] { text-align: ${align} !important; }`);
|
|
441
|
+
}
|
|
381
442
|
return rules.join("\n");
|
|
382
443
|
}
|
|
383
444
|
var STYLE_FONT_LINK_ID = "ohw-style-fonts";
|
|
@@ -404,7 +465,8 @@ var SECTION_ATTRS = {
|
|
|
404
465
|
textDistribution: "data-ohw-style-distribution",
|
|
405
466
|
headlineScale: "data-ohw-style-headline",
|
|
406
467
|
imageAspect: "data-ohw-style-aspect",
|
|
407
|
-
spacing: "data-ohw-style-spacing"
|
|
468
|
+
spacing: "data-ohw-style-spacing",
|
|
469
|
+
align: "data-ohw-style-align"
|
|
408
470
|
};
|
|
409
471
|
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
410
472
|
var NODE_PROPS = [
|
|
@@ -413,7 +475,8 @@ var NODE_PROPS = [
|
|
|
413
475
|
"font-size",
|
|
414
476
|
"background",
|
|
415
477
|
"text-align",
|
|
416
|
-
"justify-content"
|
|
478
|
+
"justify-content",
|
|
479
|
+
"align-items"
|
|
417
480
|
];
|
|
418
481
|
var ALIGN_JUSTIFY = {
|
|
419
482
|
left: "flex-start",
|
|
@@ -463,6 +526,13 @@ function clearNodeProps(root) {
|
|
|
463
526
|
function buttonSurfaceOf(el) {
|
|
464
527
|
return el.closest("a, button") ?? el;
|
|
465
528
|
}
|
|
529
|
+
function alignSubjectOf(el) {
|
|
530
|
+
const button = el.closest('[data-ohw-role="button"]');
|
|
531
|
+
return button?.parentElement ?? el;
|
|
532
|
+
}
|
|
533
|
+
function horizontalFlexProp(el) {
|
|
534
|
+
return getComputedStyle(el).flexDirection.startsWith("column") ? "align-items" : "justify-content";
|
|
535
|
+
}
|
|
466
536
|
function applyStylesToDom(store) {
|
|
467
537
|
ensureStyleSheet();
|
|
468
538
|
clearSectionAttrs(document);
|
|
@@ -509,11 +579,13 @@ function applyStylesToDom(store) {
|
|
|
509
579
|
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
510
580
|
}
|
|
511
581
|
if (override.align !== void 0) {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
582
|
+
const subject = alignSubjectOf(el);
|
|
583
|
+
const flexProp = horizontalFlexProp(subject);
|
|
584
|
+
saveInline(subject, "text-align");
|
|
585
|
+
saveInline(subject, flexProp);
|
|
586
|
+
subject.style.setProperty("text-align", override.align, "important");
|
|
587
|
+
subject.style.setProperty(flexProp, ALIGN_JUSTIFY[override.align] ?? "flex-start", "important");
|
|
588
|
+
subject.setAttribute(NODE_WROTE_ATTR, "");
|
|
517
589
|
}
|
|
518
590
|
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
519
591
|
const surface = buttonSurfaceOf(el);
|
|
@@ -743,7 +815,7 @@ function TextBlock({ slots, ctx, path }) {
|
|
|
743
815
|
}
|
|
744
816
|
function SectionHeaderBlock({ node, ctx, path }) {
|
|
745
817
|
const slots = node.slots ?? {};
|
|
746
|
-
const align = slots.alignment === "center" ? "center" : "left";
|
|
818
|
+
const align = node.align ?? (slots.alignment === "center" ? "center" : "left");
|
|
747
819
|
const children = node.children ?? [];
|
|
748
820
|
const buttonRowIdx = children.findIndex((c) => c.type === "button-row");
|
|
749
821
|
const buttonRow = buttonRowIdx >= 0 ? children[buttonRowIdx] : void 0;
|
|
@@ -787,7 +859,7 @@ function SectionHeaderBlock({ node, ctx, path }) {
|
|
|
787
859
|
display: "flex",
|
|
788
860
|
gap: AI_TREE_TOKENS.spacing6,
|
|
789
861
|
marginTop: AI_TREE_TOKENS.spacing8,
|
|
790
|
-
justifyContent: align === "center" ? "center" : "flex-start"
|
|
862
|
+
justifyContent: align === "center" ? "center" : align === "right" ? "flex-end" : "flex-start"
|
|
791
863
|
},
|
|
792
864
|
children: (buttonRow.children ?? []).map((button, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
793
865
|
ButtonEl,
|
|
@@ -1120,7 +1192,7 @@ function CardBlock({ node, ctx, path }) {
|
|
|
1120
1192
|
editPath: `${path}.media`
|
|
1121
1193
|
}
|
|
1122
1194
|
) : null;
|
|
1123
|
-
const centered = slots.alignment === "center";
|
|
1195
|
+
const centered = (node.align ?? slots.alignment) === "center";
|
|
1124
1196
|
const content = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1125
1197
|
"div",
|
|
1126
1198
|
{
|
|
@@ -20295,12 +20367,35 @@ function OhhwellsBridge() {
|
|
|
20295
20367
|
window.addEventListener("message", handleAiSetBrand);
|
|
20296
20368
|
const handleAiSetStyles = (e) => {
|
|
20297
20369
|
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
20298
|
-
|
|
20370
|
+
let value = typeof e.data.value === "string" ? e.data.value : "";
|
|
20299
20371
|
const previous = stylesRef.current;
|
|
20372
|
+
let previousSections;
|
|
20373
|
+
const store = parseStyleStore(value);
|
|
20374
|
+
if (store) {
|
|
20375
|
+
const folded = foldAlignIntoTrees(parseAiSectionsState(aiSectionsRef.current), store);
|
|
20376
|
+
if (folded.changed) {
|
|
20377
|
+
const nextSections = serializeAiSectionsState(folded.state);
|
|
20378
|
+
if (nextSections !== aiSectionsRef.current) {
|
|
20379
|
+
previousSections = aiSectionsRef.current;
|
|
20380
|
+
aiSectionsRef.current = nextSections;
|
|
20381
|
+
applyAiSectionsToDom(folded.state);
|
|
20382
|
+
postToParentRef.current({
|
|
20383
|
+
type: "ow:change",
|
|
20384
|
+
nodes: [{ key: AI_SECTIONS_KEY, text: nextSections }]
|
|
20385
|
+
});
|
|
20386
|
+
}
|
|
20387
|
+
value = JSON.stringify(folded.store);
|
|
20388
|
+
}
|
|
20389
|
+
}
|
|
20300
20390
|
stylesRef.current = value;
|
|
20301
20391
|
applyStylesToDom(parseStyleStore(value));
|
|
20302
20392
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
20303
|
-
postToParentRef.current({
|
|
20393
|
+
postToParentRef.current({
|
|
20394
|
+
type: "ow:ai-styles-applied",
|
|
20395
|
+
previous,
|
|
20396
|
+
value,
|
|
20397
|
+
...previousSections !== void 0 ? { previousSections } : {}
|
|
20398
|
+
});
|
|
20304
20399
|
};
|
|
20305
20400
|
window.addEventListener("message", handleAiSetStyles);
|
|
20306
20401
|
const handleGetBrand = (e) => {
|