@ohhwells/bridge 0.1.139 → 0.1.141
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 +269 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -1
- package/dist/index.d.ts +135 -1
- package/dist/index.js +267 -76
- package/dist/index.js.map +1 -1
- package/dist/styles.css +19 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2827,14 +2827,22 @@ function isInactiveFooterChrome(el) {
|
|
|
2827
2827
|
if (footer && footer.style.display === "none") return true;
|
|
2828
2828
|
return false;
|
|
2829
2829
|
}
|
|
2830
|
+
function isIncidentalFooter(el) {
|
|
2831
|
+
return Boolean(el.closest("blockquote, article, figure"));
|
|
2832
|
+
}
|
|
2830
2833
|
function getFooterRoot() {
|
|
2831
2834
|
const ai = document.querySelector("footer[data-ai-footer]");
|
|
2832
2835
|
if (ai) return ai;
|
|
2833
2836
|
for (const el of Array.from(
|
|
2834
|
-
document.querySelectorAll('footer[data-ohw-section="footer"]
|
|
2837
|
+
document.querySelectorAll('footer[data-ohw-section="footer"]')
|
|
2835
2838
|
)) {
|
|
2839
|
+
if (isInactiveFooterChrome(el)) continue;
|
|
2840
|
+
return el;
|
|
2841
|
+
}
|
|
2842
|
+
for (const el of Array.from(document.querySelectorAll("footer"))) {
|
|
2836
2843
|
if (el.hasAttribute("data-ai-footer")) continue;
|
|
2837
2844
|
if (isInactiveFooterChrome(el)) continue;
|
|
2845
|
+
if (isIncidentalFooter(el)) continue;
|
|
2838
2846
|
return el;
|
|
2839
2847
|
}
|
|
2840
2848
|
return null;
|
|
@@ -3245,8 +3253,8 @@ function buildFooterLink(colIndex, itemIndex, href, label, template) {
|
|
|
3245
3253
|
return anchor;
|
|
3246
3254
|
}
|
|
3247
3255
|
function footerColumnExistsInDom(colIndex) {
|
|
3248
|
-
const
|
|
3249
|
-
return
|
|
3256
|
+
const scope = getFooterLinksContainer() ?? getFooterRoot() ?? document;
|
|
3257
|
+
return scope.querySelector(`[data-ohw-footer-col="${colIndex}"]`) !== null || scope.querySelector(`[data-ohw-href-key^="footer-${colIndex}-"]`) !== null || scope.querySelector(`[data-ohw-key="footer-${colIndex}-heading"]`) !== null;
|
|
3250
3258
|
}
|
|
3251
3259
|
function getFooterLinkTemplate() {
|
|
3252
3260
|
for (const col of listFooterColumns()) {
|
|
@@ -5196,19 +5204,21 @@ function findIndexSegment(keys) {
|
|
|
5196
5204
|
if (len < 2 || tokenLists.some((t) => t.length !== len)) return null;
|
|
5197
5205
|
let position = -1;
|
|
5198
5206
|
for (let p = 0; p < len; p++) {
|
|
5199
|
-
const
|
|
5200
|
-
const allSame =
|
|
5207
|
+
const values2 = tokenLists.map((t) => t[p]);
|
|
5208
|
+
const allSame = values2.every((v) => v === values2[0]);
|
|
5201
5209
|
if (allSame) continue;
|
|
5202
|
-
|
|
5203
|
-
if (!allNumeric || position !== -1) return null;
|
|
5210
|
+
if (position !== -1) return null;
|
|
5204
5211
|
position = p;
|
|
5205
5212
|
}
|
|
5206
5213
|
if (position === -1) return null;
|
|
5214
|
+
const values = tokenLists.map((t) => t[position]);
|
|
5215
|
+
const numericCount = values.filter((v) => /^\d+$/.test(v)).length;
|
|
5216
|
+
if (numericCount !== 0 && numericCount !== values.length) return null;
|
|
5217
|
+
if (numericCount === 0 && position === len - 1) return null;
|
|
5207
5218
|
const group = tokenLists[0].slice(0, position).join("-");
|
|
5208
5219
|
if (!group) return null;
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
return { position, group };
|
|
5220
|
+
if (new Set(values).size !== values.length) return null;
|
|
5221
|
+
return numericCount === values.length ? { position, group } : { position, group, slug: true };
|
|
5212
5222
|
}
|
|
5213
5223
|
function singleIndexSegment(key) {
|
|
5214
5224
|
const tokens = baseKey(key).split("-");
|
|
@@ -5254,7 +5264,19 @@ function detectItemGroups(sectionEl) {
|
|
|
5254
5264
|
list.push(m);
|
|
5255
5265
|
byShape.set(shape, list);
|
|
5256
5266
|
}
|
|
5257
|
-
|
|
5267
|
+
const shaped = Array.from(byShape.values());
|
|
5268
|
+
clusters.push(...shaped.filter((c) => c.length >= 2));
|
|
5269
|
+
const singles = shaped.filter((c) => c.length === 1).map((c) => c[0]);
|
|
5270
|
+
const bySlugShape = /* @__PURE__ */ new Map();
|
|
5271
|
+
for (const m of singles) {
|
|
5272
|
+
const primary = primaryKey(keyedDescendants(m));
|
|
5273
|
+
const tokens = baseKey(primary ?? "").split("-");
|
|
5274
|
+
const slugShape = `${tokens.length}|${tokens[0]}|${tokens[tokens.length - 1]}`;
|
|
5275
|
+
const list = bySlugShape.get(slugShape) ?? [];
|
|
5276
|
+
list.push(m);
|
|
5277
|
+
bySlugShape.set(slugShape, list);
|
|
5278
|
+
}
|
|
5279
|
+
clusters.push(...Array.from(bySlugShape.values()));
|
|
5258
5280
|
}
|
|
5259
5281
|
for (const members of clusters) {
|
|
5260
5282
|
const keyedPerMember = members.map((m) => keyedDescendants(m));
|
|
@@ -5265,11 +5287,28 @@ function detectItemGroups(sectionEl) {
|
|
|
5265
5287
|
const dedupeKey = `${segment.group}`;
|
|
5266
5288
|
if (seenParents.has(dedupeKey)) continue;
|
|
5267
5289
|
seenParents.add(dedupeKey);
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5290
|
+
let items;
|
|
5291
|
+
if (segment.slug) {
|
|
5292
|
+
const tokens = members.map((_, i) => baseKey(primaries[i]).split("-")[segment.position]);
|
|
5293
|
+
let nextOriginal = 1;
|
|
5294
|
+
const indices = tokens.map((t) => {
|
|
5295
|
+
const cloneMatch = t.match(/^x(\d+)$/);
|
|
5296
|
+
return cloneMatch ? parseInt(cloneMatch[1], 10) : nextOriginal++;
|
|
5297
|
+
});
|
|
5298
|
+
if (new Set(indices).size !== indices.length) continue;
|
|
5299
|
+
items = members.map((el, i) => ({
|
|
5300
|
+
el,
|
|
5301
|
+
index: indices[i],
|
|
5302
|
+
keyed: keyedPerMember[i],
|
|
5303
|
+
slugToken: tokens[i]
|
|
5304
|
+
}));
|
|
5305
|
+
} else {
|
|
5306
|
+
items = members.map((el, i) => ({
|
|
5307
|
+
el,
|
|
5308
|
+
index: indexFromKey(primaries[i], segment.position),
|
|
5309
|
+
keyed: keyedPerMember[i]
|
|
5310
|
+
}));
|
|
5311
|
+
}
|
|
5273
5312
|
groups.push({ group: segment.group, parent, nested: false, items });
|
|
5274
5313
|
}
|
|
5275
5314
|
}
|
|
@@ -5393,6 +5432,18 @@ function rekeyItemClone(clone, source, sibling, group, newIndex) {
|
|
|
5393
5432
|
const delta = newIndex - source.index;
|
|
5394
5433
|
const cloneKeyed = keyedDescendants(clone);
|
|
5395
5434
|
const pairs = [];
|
|
5435
|
+
if (source.slugToken) {
|
|
5436
|
+
source.keyed.forEach((src, i) => {
|
|
5437
|
+
const target = cloneKeyed[i];
|
|
5438
|
+
if (!target || target.attr !== src.attr) return;
|
|
5439
|
+
const tokens = baseKey(src.key).split("-");
|
|
5440
|
+
if (!tokens.includes(source.slugToken)) return;
|
|
5441
|
+
const next = tokens.map((t) => t === source.slugToken ? `x${newIndex}` : t).join("-") + keySuffix(src.key);
|
|
5442
|
+
target.el.setAttribute(src.attr, next);
|
|
5443
|
+
pairs.push({ from: src.key, to: next });
|
|
5444
|
+
});
|
|
5445
|
+
return pairs;
|
|
5446
|
+
}
|
|
5396
5447
|
source.keyed.forEach((src, i) => {
|
|
5397
5448
|
const target = cloneKeyed[i];
|
|
5398
5449
|
if (!target || target.attr !== src.attr) return;
|
|
@@ -5436,7 +5487,12 @@ function syncGroup(detected, state) {
|
|
|
5436
5487
|
clone.setAttribute(ITEM_ATTR, `${detected.group}:${entry.index}`);
|
|
5437
5488
|
rekeyItemClone(clone, source, sibling, detected.group, entry.index);
|
|
5438
5489
|
source.el.insertAdjacentElement("afterend", clone);
|
|
5439
|
-
byIndex.set(entry.index, {
|
|
5490
|
+
byIndex.set(entry.index, {
|
|
5491
|
+
el: clone,
|
|
5492
|
+
index: entry.index,
|
|
5493
|
+
keyed: keyedDescendants(clone),
|
|
5494
|
+
...source.slugToken ? { slugToken: `x${entry.index}` } : {}
|
|
5495
|
+
});
|
|
5440
5496
|
}
|
|
5441
5497
|
const listed = state.items.map((e) => byIndex.get(e.index)?.el).filter((el) => !!el);
|
|
5442
5498
|
let prev = null;
|
|
@@ -5538,9 +5594,16 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5538
5594
|
const nodes = [];
|
|
5539
5595
|
const added = [];
|
|
5540
5596
|
let elements = syncGroup(detected, state);
|
|
5597
|
+
const sluggy = detected.items.some((item) => item.slugToken);
|
|
5598
|
+
const slugTokenOf = (index) => detected.items.find((item) => item.index === index)?.slugToken ?? (sluggy ? `x${index}` : void 0);
|
|
5541
5599
|
for (const add of ops.add ?? []) {
|
|
5542
5600
|
const sourceEl = elements.get(add.cloneOf);
|
|
5543
|
-
const source = sourceEl ? {
|
|
5601
|
+
const source = sourceEl ? {
|
|
5602
|
+
el: sourceEl,
|
|
5603
|
+
index: add.cloneOf,
|
|
5604
|
+
keyed: keyedDescendants(sourceEl),
|
|
5605
|
+
...slugTokenOf(add.cloneOf) ? { slugToken: slugTokenOf(add.cloneOf) } : {}
|
|
5606
|
+
} : void 0;
|
|
5544
5607
|
if (!source) continue;
|
|
5545
5608
|
const newIndex = Math.max(...state.items.map((e) => e.index), ...detected.items.map((i) => i.index)) + 1;
|
|
5546
5609
|
const sibling = detected.items.find((item) => item.index !== add.cloneOf && !item.el.hasAttribute(ITEM_CLONE_ATTR)) ?? null;
|
|
@@ -5567,7 +5630,12 @@ function applyItemOps(store, ops, currentContent) {
|
|
|
5567
5630
|
if (anchor) anchor.insertAdjacentElement("afterend", clone);
|
|
5568
5631
|
else source.el.insertAdjacentElement("afterend", clone);
|
|
5569
5632
|
elements.set(newIndex, clone);
|
|
5570
|
-
detected.items.push({
|
|
5633
|
+
detected.items.push({
|
|
5634
|
+
el: clone,
|
|
5635
|
+
index: newIndex,
|
|
5636
|
+
keyed: cloneKeyed,
|
|
5637
|
+
...sluggy ? { slugToken: `x${newIndex}` } : {}
|
|
5638
|
+
});
|
|
5571
5639
|
added.push(newIndex);
|
|
5572
5640
|
elements = syncGroup(detected, state);
|
|
5573
5641
|
}
|
|
@@ -6010,16 +6078,25 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6010
6078
|
nextTrees.set(id, fresh);
|
|
6011
6079
|
return fresh;
|
|
6012
6080
|
};
|
|
6081
|
+
const stripChildAligns = (node) => node.children ? {
|
|
6082
|
+
...node,
|
|
6083
|
+
children: node.children.map((child) => {
|
|
6084
|
+
const { align: _dropped, ...rest } = child;
|
|
6085
|
+
return stripChildAligns(rest);
|
|
6086
|
+
})
|
|
6087
|
+
} : node;
|
|
6013
6088
|
const nodes = {};
|
|
6014
6089
|
for (const [key, override] of Object.entries(store.nodes)) {
|
|
6015
6090
|
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
6016
6091
|
const tree = match ? treeFor(match[1]) : void 0;
|
|
6017
|
-
const
|
|
6018
|
-
|
|
6092
|
+
const row = match && tree ? tree.rows[Number(match[2])] : void 0;
|
|
6093
|
+
const blockIdx = match ? Number(match[3]) : -1;
|
|
6094
|
+
const block = row?.blocks[blockIdx];
|
|
6095
|
+
if (!row || !block) {
|
|
6019
6096
|
nodes[key] = override;
|
|
6020
6097
|
continue;
|
|
6021
6098
|
}
|
|
6022
|
-
|
|
6099
|
+
row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
|
|
6023
6100
|
const rest = { ...override };
|
|
6024
6101
|
delete rest.align;
|
|
6025
6102
|
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
@@ -6032,7 +6109,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6032
6109
|
continue;
|
|
6033
6110
|
}
|
|
6034
6111
|
for (const row of tree.rows) {
|
|
6035
|
-
|
|
6112
|
+
row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
|
|
6036
6113
|
}
|
|
6037
6114
|
const rest = { ...override };
|
|
6038
6115
|
delete rest.align;
|
|
@@ -6263,6 +6340,20 @@ function applyBrandChrome(content) {
|
|
|
6263
6340
|
|
|
6264
6341
|
// src/lib/brand-kit.ts
|
|
6265
6342
|
var BRAND_KIT_KEY = "__ohw_brand";
|
|
6343
|
+
var appliedPalette = null;
|
|
6344
|
+
var appliedFonts = null;
|
|
6345
|
+
function getAppliedBrand() {
|
|
6346
|
+
if (!appliedPalette) return null;
|
|
6347
|
+
return appliedFonts ? { palette: appliedPalette, fonts: appliedFonts } : { palette: appliedPalette };
|
|
6348
|
+
}
|
|
6349
|
+
function brandForGenerated(fallback) {
|
|
6350
|
+
const applied = getAppliedBrand();
|
|
6351
|
+
if (!applied) return fallback ?? void 0;
|
|
6352
|
+
return {
|
|
6353
|
+
palette: applied.palette,
|
|
6354
|
+
fonts: applied.fonts ?? fallback?.fonts ?? AI_DEFAULT_BRAND.fonts
|
|
6355
|
+
};
|
|
6356
|
+
}
|
|
6266
6357
|
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
6267
6358
|
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
6268
6359
|
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
@@ -6566,6 +6657,8 @@ function loadCustomFonts(fonts) {
|
|
|
6566
6657
|
function applyBrandToDom(kit) {
|
|
6567
6658
|
const root = document.documentElement;
|
|
6568
6659
|
if (!kit) {
|
|
6660
|
+
appliedPalette = null;
|
|
6661
|
+
appliedFonts = null;
|
|
6569
6662
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...BUTTON_VAR_NAMES]) {
|
|
6570
6663
|
root.style.removeProperty(name);
|
|
6571
6664
|
}
|
|
@@ -6579,11 +6672,16 @@ function applyBrandToDom(kit) {
|
|
|
6579
6672
|
const applyFonts = kit.touched ? kit.touched.fonts === true : true;
|
|
6580
6673
|
if (kit.palette) {
|
|
6581
6674
|
if (applyPalette) {
|
|
6675
|
+
appliedPalette = kit.palette;
|
|
6582
6676
|
for (const [name, value] of Object.entries(brandColorVars(kit.palette))) root.style.setProperty(name, value);
|
|
6583
6677
|
} else {
|
|
6678
|
+
appliedPalette = null;
|
|
6584
6679
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
|
|
6585
6680
|
}
|
|
6586
6681
|
}
|
|
6682
|
+
if (kit.fonts) {
|
|
6683
|
+
appliedFonts = applyFonts ? kit.fonts : null;
|
|
6684
|
+
}
|
|
6587
6685
|
if (kit.buttons) {
|
|
6588
6686
|
for (const name of BUTTON_VAR_NAMES) root.style.removeProperty(name);
|
|
6589
6687
|
for (const [name, value] of Object.entries(buttonStyleVars({ ...kit, buttons: kit.buttons }))) root.style.setProperty(name, value);
|
|
@@ -7116,6 +7214,35 @@ function withThemeFonts(brand) {
|
|
|
7116
7214
|
}
|
|
7117
7215
|
};
|
|
7118
7216
|
}
|
|
7217
|
+
function liveBrandColor(role, fallback) {
|
|
7218
|
+
if (role === "dark") {
|
|
7219
|
+
return `var(--brand-text, var(--ohw-brand-dark, var(--color-dark, ${fallback})))`;
|
|
7220
|
+
}
|
|
7221
|
+
if (role === "light") {
|
|
7222
|
+
return `var(--brand-background, var(--ohw-brand-light, var(--color-light, ${fallback})))`;
|
|
7223
|
+
}
|
|
7224
|
+
return `var(--brand-${role}, var(--ohw-brand-${role}, var(--color-${role}, ${fallback})))`;
|
|
7225
|
+
}
|
|
7226
|
+
function withLivePalette(brand, source) {
|
|
7227
|
+
const sourceOf = (color) => {
|
|
7228
|
+
const value = color.trim().toLowerCase();
|
|
7229
|
+
const entries = Object.entries(source.palette);
|
|
7230
|
+
return entries.find(([, hex]) => hex.trim().toLowerCase() === value)?.[0] ?? null;
|
|
7231
|
+
};
|
|
7232
|
+
const map = (color) => {
|
|
7233
|
+
const role = sourceOf(color);
|
|
7234
|
+
return role ? liveBrandColor(role, source.palette[role]) : color;
|
|
7235
|
+
};
|
|
7236
|
+
return {
|
|
7237
|
+
...brand,
|
|
7238
|
+
palette: {
|
|
7239
|
+
dark: map(brand.palette.dark),
|
|
7240
|
+
primary: map(brand.palette.primary),
|
|
7241
|
+
accent: map(brand.palette.accent),
|
|
7242
|
+
light: map(brand.palette.light)
|
|
7243
|
+
}
|
|
7244
|
+
};
|
|
7245
|
+
}
|
|
7119
7246
|
function footerLogoStyle(fallbackFont, fallbackColor) {
|
|
7120
7247
|
return {
|
|
7121
7248
|
fontFamily: `var(--brand-font-heading, var(--font-heading, var(--font-display, ${quotedFont(fallbackFont)})))`,
|
|
@@ -7143,6 +7270,7 @@ var blockAlignStyle = (blockAlign) => blockAlign ? {
|
|
|
7143
7270
|
alignItems: blockAlign === "left" ? "flex-start" : blockAlign === "right" ? "flex-end" : "center",
|
|
7144
7271
|
textAlign: blockAlign
|
|
7145
7272
|
} : {};
|
|
7273
|
+
var fullBleedBlock = (block) => block.type === "carousel" || block.type === "group" && str(block.slots?.layout) === "overlap";
|
|
7146
7274
|
var featureLines = (value) => value.split(/\n|<br\s*\/?>/i).map((line) => line.trim()).filter(Boolean);
|
|
7147
7275
|
var AI_MOBILE_CSS = [
|
|
7148
7276
|
// Unscoped (applies at every viewport, not just mobile): re-enables pointer-events for the
|
|
@@ -7333,7 +7461,7 @@ function hexContrast(a, b) {
|
|
|
7333
7461
|
function primaryButtonLabel(brand) {
|
|
7334
7462
|
const darkC = hexContrast(brand.palette.primary, brand.palette.dark);
|
|
7335
7463
|
const lightC = hexContrast(brand.palette.primary, AI_TREE_TOKENS.textPrimaryForeground);
|
|
7336
|
-
if (darkC === null || lightC === null) return AI_TREE_TOKENS.textPrimaryForeground
|
|
7464
|
+
if (darkC === null || lightC === null) return `var(--brand-on-primary, ${AI_TREE_TOKENS.textPrimaryForeground})`;
|
|
7337
7465
|
return darkC > lightC ? brand.palette.dark : AI_TREE_TOKENS.textPrimaryForeground;
|
|
7338
7466
|
}
|
|
7339
7467
|
function accentBandContext(brand) {
|
|
@@ -7357,7 +7485,11 @@ function readableForeground(bg, brand) {
|
|
|
7357
7485
|
return darkC > lightC ? brand.palette.dark : AI_TREE_TOKENS.textPrimaryForeground;
|
|
7358
7486
|
}
|
|
7359
7487
|
function hexWithAlpha(hex, alpha) {
|
|
7360
|
-
const
|
|
7488
|
+
const value = hex.trim();
|
|
7489
|
+
if (value.startsWith("var(") || value.startsWith("color-mix(")) {
|
|
7490
|
+
return `color-mix(in srgb, ${value} ${Math.round(alpha * 100)}%, transparent)`;
|
|
7491
|
+
}
|
|
7492
|
+
const m = /^#([0-9a-f]{6})$/i.exec(value);
|
|
7361
7493
|
if (!m) return hex;
|
|
7362
7494
|
const r2 = parseInt(m[1].slice(0, 2), 16);
|
|
7363
7495
|
const g = parseInt(m[1].slice(2, 4), 16);
|
|
@@ -7630,12 +7762,10 @@ function ButtonEl({
|
|
|
7630
7762
|
cursor: "pointer",
|
|
7631
7763
|
whiteSpace: "nowrap",
|
|
7632
7764
|
...buttonShellStyle(ctx, variant, fullWidth),
|
|
7633
|
-
...tokenColorStyle ?? (secondary ? { border: `1px solid ${secondaryColor ?? ctx.brand.palette.dark}`, color: secondaryColor ?? ctx.brand.palette.dark } :
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
!ctx.buttonLabel && ctx.buttonStyle?.background ? { background: ctx.buttonStyle.background, color: ctx.buttonStyle.color } : { background: ctx.brand.palette.primary, color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand) }
|
|
7638
|
-
))
|
|
7765
|
+
...tokenColorStyle ?? (secondary ? { border: `1px solid ${secondaryColor ?? ctx.brand.palette.dark}`, color: secondaryColor ?? ctx.brand.palette.dark } : {
|
|
7766
|
+
background: ctx.brand.palette.primary,
|
|
7767
|
+
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
7768
|
+
})
|
|
7639
7769
|
},
|
|
7640
7770
|
children: /* @__PURE__ */ jsx("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
|
|
7641
7771
|
}
|
|
@@ -9206,8 +9336,8 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9206
9336
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9207
9337
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9208
9338
|
// the full section width instead of reading at the usual content width.
|
|
9209
|
-
/* @__PURE__ */ jsx("div", { style: { maxWidth: AI_TREE_TOKENS.sectionMaxWidth, margin: "0 auto", padding: "0 40px", width: "100%", boxSizing: "border-box" }, children: renderNode(child, ctx, `${path}.c${i}`, child.align ?? "center") })
|
|
9210
|
-
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? "center" : void 0),
|
|
9339
|
+
/* @__PURE__ */ jsx("div", { style: { maxWidth: AI_TREE_TOKENS.sectionMaxWidth, margin: "0 auto", padding: "0 40px", width: "100%", boxSizing: "border-box" }, children: renderNode(child, ctx, `${path}.c${i}`, child.align ?? node.align ?? "center") })
|
|
9340
|
+
) : renderNode(child, ctx, `${path}.c${i}`, i > 0 ? child.align ?? node.align ?? "center" : void 0),
|
|
9211
9341
|
i === 0 && needsBaseScrim && /* @__PURE__ */ jsx(
|
|
9212
9342
|
"div",
|
|
9213
9343
|
{
|
|
@@ -9240,7 +9370,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9240
9370
|
// child otherwise stretches full-width (unchanged pre-existing behaviour).
|
|
9241
9371
|
...blockAlignStyle(child.align ?? ambientAlign)
|
|
9242
9372
|
},
|
|
9243
|
-
children: renderNode(child, ctx, `${path}.c${i}`, ambientAlign)
|
|
9373
|
+
children: renderNode(child, ctx, `${path}.c${i}`, node.align ?? ambientAlign)
|
|
9244
9374
|
},
|
|
9245
9375
|
i
|
|
9246
9376
|
));
|
|
@@ -9270,8 +9400,20 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9270
9400
|
}
|
|
9271
9401
|
case "button":
|
|
9272
9402
|
return /* @__PURE__ */ jsx(ButtonEl, { slots, ctx, path });
|
|
9273
|
-
case "button-row":
|
|
9274
|
-
|
|
9403
|
+
case "button-row": {
|
|
9404
|
+
const rowAlign = node.align ?? ambientAlign;
|
|
9405
|
+
return /* @__PURE__ */ jsx(
|
|
9406
|
+
"div",
|
|
9407
|
+
{
|
|
9408
|
+
style: {
|
|
9409
|
+
display: "flex",
|
|
9410
|
+
gap: AI_TREE_TOKENS.spacing6,
|
|
9411
|
+
justifyContent: rowAlign === "left" ? "flex-start" : rowAlign === "right" ? "flex-end" : "center"
|
|
9412
|
+
},
|
|
9413
|
+
children: (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }, i))
|
|
9414
|
+
}
|
|
9415
|
+
);
|
|
9416
|
+
}
|
|
9275
9417
|
case "media":
|
|
9276
9418
|
return /* @__PURE__ */ jsx(
|
|
9277
9419
|
MediaBox,
|
|
@@ -9480,10 +9622,10 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9480
9622
|
...buttonShellStyle(ctx, "primary"),
|
|
9481
9623
|
// Brand-styled: the template button's measured fill/label pair off-band, else
|
|
9482
9624
|
// primary fill with a brand-derived label so it reads on custom palettes.
|
|
9483
|
-
...buttonColorStyle(ctx, "primary") ??
|
|
9625
|
+
...buttonColorStyle(ctx, "primary") ?? {
|
|
9484
9626
|
background: ctx.brand.palette.primary,
|
|
9485
9627
|
color: ctx.buttonLabel ?? primaryButtonLabel(ctx.brand)
|
|
9486
|
-
}
|
|
9628
|
+
}
|
|
9487
9629
|
},
|
|
9488
9630
|
children: /* @__PURE__ */ jsx("span", { ...textAttrs(ctx, `${path}.c${i}.label`), children: str(cs.label) })
|
|
9489
9631
|
},
|
|
@@ -9527,7 +9669,7 @@ function AiTreeRenderer({
|
|
|
9527
9669
|
}
|
|
9528
9670
|
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
9529
9671
|
const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
|
|
9530
|
-
const blockBrand = band?.brand ?? resolvedBrand;
|
|
9672
|
+
const blockBrand = withLivePalette(band?.brand ?? resolvedBrand, resolvedBrand);
|
|
9531
9673
|
const placeholderMap = buildPlaceholderMap(tree);
|
|
9532
9674
|
const hasOverlapBackground = tree.scaffold === "overlay" && tree.rows.some(
|
|
9533
9675
|
(row) => (row.blocks ?? []).some((b) => b.type === "group" && str(b.slots?.layout) === "overlap")
|
|
@@ -9543,7 +9685,7 @@ function AiTreeRenderer({
|
|
|
9543
9685
|
// standalone resolve), so generated galleries, image rows, and overlay backgrounds arrive with
|
|
9544
9686
|
// photos instead of grey boxes.
|
|
9545
9687
|
resolveMedia: (ref) => resolveMedia?.(ref) ?? placeholderMap[ref] ?? resolvePlaceholderRef(ref),
|
|
9546
|
-
cardSurface:
|
|
9688
|
+
cardSurface: resolvedBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${blockBrand.palette.light} 90%, ${blockBrand.palette.dark})`,
|
|
9547
9689
|
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
|
|
9548
9690
|
sectionAlignment: (tree.settings ?? {}).alignment === "center" ? "center" : "left",
|
|
9549
9691
|
buttonStyle,
|
|
@@ -9560,7 +9702,7 @@ function AiTreeRenderer({
|
|
|
9560
9702
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
9561
9703
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
9562
9704
|
const toneBackground = (() => {
|
|
9563
|
-
const { dark, primary, light } =
|
|
9705
|
+
const { dark, primary, light } = blockBrand.palette;
|
|
9564
9706
|
switch (settings.sectionBackground) {
|
|
9565
9707
|
case "surface":
|
|
9566
9708
|
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
@@ -9650,7 +9792,7 @@ function AiTreeRenderer({
|
|
|
9650
9792
|
// its own horizontal `align`, which takes priority for that block.
|
|
9651
9793
|
...fillHeight ? { display: "grid" } : {},
|
|
9652
9794
|
// Horizontal placement of the block's content within its column.
|
|
9653
|
-
...cellAlignStyle(block.align),
|
|
9795
|
+
...fullBleedBlock(block) ? {} : cellAlignStyle(block.align),
|
|
9654
9796
|
// space-between: each column becomes a flex column whose content spreads over
|
|
9655
9797
|
// the full row height instead of clumping at the top.
|
|
9656
9798
|
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
@@ -9681,14 +9823,15 @@ function AiFooterRenderer({
|
|
|
9681
9823
|
if (!isRenderableFooterTree(tree)) {
|
|
9682
9824
|
return null;
|
|
9683
9825
|
}
|
|
9684
|
-
const
|
|
9826
|
+
const hexBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
9827
|
+
const resolvedBrand = withLivePalette(hexBrand, brand ?? AI_DEFAULT_BRAND);
|
|
9685
9828
|
const bandBg = surface?.background ?? resolvedBrand.palette.dark;
|
|
9686
9829
|
const bandText = surface?.text ?? resolvedBrand.palette.light;
|
|
9687
9830
|
const onDark = surface ? isDarkColor(surface.background) : true;
|
|
9688
9831
|
const ctx = {
|
|
9689
9832
|
brand: resolvedBrand,
|
|
9690
9833
|
resolveMedia: (ref) => resolveMedia?.(ref) ?? resolvePlaceholderRef(ref),
|
|
9691
|
-
cardSurface:
|
|
9834
|
+
cardSurface: hexBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${resolvedBrand.palette.light} 90%, ${resolvedBrand.palette.dark})`,
|
|
9692
9835
|
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
|
|
9693
9836
|
logoUrl: logoUrl ?? null,
|
|
9694
9837
|
resolvePageHref
|
|
@@ -10264,10 +10407,9 @@ function syncSoftRemovedGenerated() {
|
|
|
10264
10407
|
}
|
|
10265
10408
|
function applyAiSectionsToDom(state, options) {
|
|
10266
10409
|
if (typeof document === "undefined") return;
|
|
10267
|
-
const brandOverride = deriveBrandOverride();
|
|
10268
10410
|
const templateBrand = deriveTemplateBrand();
|
|
10269
10411
|
const templateButtonStyle = deriveTemplateButtonStyle();
|
|
10270
|
-
const brandKey =
|
|
10412
|
+
const brandKey = JSON.stringify(getAppliedBrand() ?? deriveBrandOverride() ?? null);
|
|
10271
10413
|
const pagePath = window.location.pathname;
|
|
10272
10414
|
const pageSections = state.sections.filter((entry) => (entry.path ?? "/") === pagePath);
|
|
10273
10415
|
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
@@ -10310,7 +10452,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10310
10452
|
AiTreeRenderer,
|
|
10311
10453
|
{
|
|
10312
10454
|
tree: entry.tree,
|
|
10313
|
-
brand:
|
|
10455
|
+
brand: brandForGenerated(deriveBrandOverride() ?? entry.brand ?? options?.brand ?? templateBrand),
|
|
10314
10456
|
buttonStyle: templateButtonStyle,
|
|
10315
10457
|
resolveMedia,
|
|
10316
10458
|
editKeyPrefix: `ai.${entry.id}`
|
|
@@ -10476,7 +10618,7 @@ function applyAiFooterToDom(state, content) {
|
|
|
10476
10618
|
const templateFooter = findTemplateFooter();
|
|
10477
10619
|
captureTemplateFooterSurface(templateFooter);
|
|
10478
10620
|
const surface = capturedSurface ?? null;
|
|
10479
|
-
const brand = mountOptions.brand ?? deriveTemplateBrand();
|
|
10621
|
+
const brand = brandForGenerated(mountOptions.brand ?? deriveTemplateBrand());
|
|
10480
10622
|
const logoUrl = resolveLogoFromContent(content, templateFooter);
|
|
10481
10623
|
const serialized = JSON.stringify(state) + JSON.stringify(brand ?? null) + (logoUrl ?? "") + JSON.stringify(surface) + JSON.stringify(defaultLegal());
|
|
10482
10624
|
if (mounted2 && mounted2.serialized === serialized && mounted2.container.isConnected) {
|
|
@@ -18284,10 +18426,23 @@ function setPricingCardStyle(tree, index, style) {
|
|
|
18284
18426
|
});
|
|
18285
18427
|
}
|
|
18286
18428
|
function setPricingCardFeaturedTag(tree, index, on) {
|
|
18287
|
-
return
|
|
18429
|
+
return withPricingCollection(tree, (collection) => {
|
|
18430
|
+
const children = collection.children;
|
|
18431
|
+
if (index < 0 || index >= children.length) return false;
|
|
18432
|
+
if (on) {
|
|
18433
|
+
children.forEach((card, i) => {
|
|
18434
|
+
if (i === index) return;
|
|
18435
|
+
const prev2 = featuredOf(card);
|
|
18436
|
+
if (prev2.enabled !== true || badgeOf(prev2).length === 0) return;
|
|
18437
|
+
card.slots = card.slots ?? {};
|
|
18438
|
+
card.slots.featured = composeFeatured(pricingCardStyleOf(prev2), false, badgeOf(prev2));
|
|
18439
|
+
});
|
|
18440
|
+
}
|
|
18441
|
+
const target = children[index];
|
|
18442
|
+
target.slots = target.slots ?? {};
|
|
18288
18443
|
const prev = featuredOf(target);
|
|
18289
|
-
|
|
18290
|
-
|
|
18444
|
+
target.slots.featured = composeFeatured(pricingCardStyleOf(prev), on, badgeOf(prev));
|
|
18445
|
+
return true;
|
|
18291
18446
|
});
|
|
18292
18447
|
}
|
|
18293
18448
|
function pricingCardStyleOf(featured) {
|
|
@@ -18537,25 +18692,40 @@ function ToolbarSeparator() {
|
|
|
18537
18692
|
}
|
|
18538
18693
|
function CardStyleMenu({
|
|
18539
18694
|
value,
|
|
18540
|
-
onChange
|
|
18695
|
+
onChange,
|
|
18696
|
+
disabled = false
|
|
18541
18697
|
}) {
|
|
18542
18698
|
const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
|
|
18699
|
+
const trigger = /* @__PURE__ */ jsxs11(
|
|
18700
|
+
"button",
|
|
18701
|
+
{
|
|
18702
|
+
type: "button",
|
|
18703
|
+
"aria-label": "Card style",
|
|
18704
|
+
disabled,
|
|
18705
|
+
className: cn(
|
|
18706
|
+
"inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
|
|
18707
|
+
disabled && "cursor-not-allowed opacity-40 hover:bg-transparent"
|
|
18708
|
+
),
|
|
18709
|
+
children: [
|
|
18710
|
+
/* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
|
|
18711
|
+
/* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
|
|
18712
|
+
/* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
18713
|
+
]
|
|
18714
|
+
}
|
|
18715
|
+
);
|
|
18716
|
+
if (disabled) {
|
|
18717
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18718
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground opacity-50", children: "Card style" }),
|
|
18719
|
+
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18720
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: trigger }) }),
|
|
18721
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: "Mark as featured to edit card style" })
|
|
18722
|
+
] })
|
|
18723
|
+
] });
|
|
18724
|
+
}
|
|
18543
18725
|
return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
|
|
18544
18726
|
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
|
|
18545
18727
|
/* @__PURE__ */ jsxs11(DropdownMenu, { modal: false, children: [
|
|
18546
|
-
/* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children:
|
|
18547
|
-
"button",
|
|
18548
|
-
{
|
|
18549
|
-
type: "button",
|
|
18550
|
-
"aria-label": "Card style",
|
|
18551
|
-
className: "inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
|
|
18552
|
-
children: [
|
|
18553
|
-
/* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
|
|
18554
|
-
/* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
|
|
18555
|
-
/* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
|
|
18556
|
-
]
|
|
18557
|
-
}
|
|
18558
|
-
) }),
|
|
18728
|
+
/* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: trigger }),
|
|
18559
18729
|
/* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
|
|
18560
18730
|
const selected = style.value === value;
|
|
18561
18731
|
return /* @__PURE__ */ jsxs11(
|
|
@@ -18619,23 +18789,35 @@ function PricingCardToolbar({
|
|
|
18619
18789
|
mobile ? "flex-wrap justify-center" : "flex-nowrap"
|
|
18620
18790
|
),
|
|
18621
18791
|
children: [
|
|
18622
|
-
/* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle }),
|
|
18623
18792
|
/* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
18624
18793
|
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
18625
18794
|
CustomToolbarButton,
|
|
18626
18795
|
{
|
|
18627
18796
|
type: "button",
|
|
18628
|
-
"aria-label": featuredTag ? "
|
|
18797
|
+
"aria-label": featuredTag ? "Unmark as featured" : "Mark as featured",
|
|
18629
18798
|
"aria-pressed": featuredTag,
|
|
18630
|
-
active: featuredTag,
|
|
18631
18799
|
onClick: () => onSetFeaturedTag(!featuredTag),
|
|
18632
|
-
className: "size-8",
|
|
18633
|
-
children: /* @__PURE__ */ jsx20(
|
|
18800
|
+
className: "group size-8",
|
|
18801
|
+
children: /* @__PURE__ */ jsx20(
|
|
18802
|
+
Star2,
|
|
18803
|
+
{
|
|
18804
|
+
size: 16,
|
|
18805
|
+
fill: "currentColor",
|
|
18806
|
+
strokeWidth: 0,
|
|
18807
|
+
className: cn(
|
|
18808
|
+
"transition-colors",
|
|
18809
|
+
featuredTag ? "text-[#f59e0b] group-hover:text-[#d97706]" : "text-[#d6d3d1] group-hover:text-[#fbbf24]"
|
|
18810
|
+
),
|
|
18811
|
+
style: { pointerEvents: "none" }
|
|
18812
|
+
}
|
|
18813
|
+
)
|
|
18634
18814
|
}
|
|
18635
18815
|
) }),
|
|
18636
|
-
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "
|
|
18816
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Unmark featured" : "Mark as featured" })
|
|
18637
18817
|
] }),
|
|
18638
18818
|
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18819
|
+
/* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle, disabled: !featuredTag }),
|
|
18820
|
+
/* @__PURE__ */ jsx20(ToolbarSeparator, {}),
|
|
18639
18821
|
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx20(ButtonGlyph, {}) }),
|
|
18640
18822
|
/* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs11("span", { className: "relative inline-flex", children: [
|
|
18641
18823
|
/* @__PURE__ */ jsx20(ButtonGlyph, {}),
|
|
@@ -18778,7 +18960,12 @@ function AiPricingCardOverlay({
|
|
|
18778
18960
|
index: active.index,
|
|
18779
18961
|
pending,
|
|
18780
18962
|
error,
|
|
18781
|
-
onAddTier: () =>
|
|
18963
|
+
onAddTier: () => {
|
|
18964
|
+
const newIndex = pricingCardCount(activeEntry.tree);
|
|
18965
|
+
void runMutation(active.sectionId, addPricingTier).then((applied) => {
|
|
18966
|
+
if (applied) setActive({ sectionId: active.sectionId, index: newIndex });
|
|
18967
|
+
});
|
|
18968
|
+
},
|
|
18782
18969
|
onRemoveTier: () => {
|
|
18783
18970
|
void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
|
|
18784
18971
|
(applied) => {
|
|
@@ -27195,7 +27382,7 @@ function OhhwellsBridge() {
|
|
|
27195
27382
|
if (!subdomain) return {};
|
|
27196
27383
|
return contentCache.get(subdomain) ?? {};
|
|
27197
27384
|
};
|
|
27198
|
-
const observeRoots = () => [document.querySelector("nav"),
|
|
27385
|
+
const observeRoots = () => [document.querySelector("nav"), getFooterRoot()].filter(
|
|
27199
27386
|
(el) => Boolean(el)
|
|
27200
27387
|
);
|
|
27201
27388
|
const roots = observeRoots();
|
|
@@ -27666,7 +27853,7 @@ function OhhwellsBridge() {
|
|
|
27666
27853
|
{
|
|
27667
27854
|
const formEl = getFormElement(target);
|
|
27668
27855
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
27669
|
-
if (formEl && formKeyOf(formEl) && !onSuccessText) {
|
|
27856
|
+
if (formEl && formKeyOf(formEl) && !onSuccessText && !isCtaButton(target)) {
|
|
27670
27857
|
const fieldEl = getFieldWrapper(target);
|
|
27671
27858
|
if (fieldEl) {
|
|
27672
27859
|
const label = target.closest("label");
|
|
@@ -29559,6 +29746,7 @@ function OhhwellsBridge() {
|
|
|
29559
29746
|
brandKitRef.current = value;
|
|
29560
29747
|
applyBrandToDom(parseBrandKit(value));
|
|
29561
29748
|
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
29749
|
+
applyAiFooterFromContent(editContentRef.current);
|
|
29562
29750
|
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
29563
29751
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
29564
29752
|
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
@@ -30190,9 +30378,10 @@ function OhhwellsBridge() {
|
|
|
30190
30378
|
if (e.data?.type !== "ow:collect-section") return;
|
|
30191
30379
|
const sectionId = e.data.sectionId;
|
|
30192
30380
|
if (typeof sectionId !== "string" || !sectionId) return;
|
|
30193
|
-
const
|
|
30381
|
+
const foundEl = document.querySelector(
|
|
30194
30382
|
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
30195
30383
|
);
|
|
30384
|
+
const sectionEl = foundEl && !foundEl.hasAttribute("data-ohw-ai-template-hidden") && !foundEl.hasAttribute("data-ohw-ai-removed") && !foundEl.hasAttribute("data-ohw-ai-replaced-by") ? foundEl : null;
|
|
30196
30385
|
const nodes = sectionEl ? collectEditableNodes(void 0, sectionEl).filter(
|
|
30197
30386
|
(n) => n.key && !n.key.startsWith("__ohw_") && !["meta", "sections", "video-setting"].includes(n.type)
|
|
30198
30387
|
).map((n) => ({ ...n, text: n.text ?? "", type: normalizeAiNodeType(n.type) })) : [];
|
|
@@ -30931,7 +31120,7 @@ function OhhwellsBridge() {
|
|
|
30931
31120
|
postToParent2({
|
|
30932
31121
|
type: "ow:ready",
|
|
30933
31122
|
version: "1",
|
|
30934
|
-
bridgeVersion: "0.1.
|
|
31123
|
+
bridgeVersion: "0.1.140",
|
|
30935
31124
|
path: pathname,
|
|
30936
31125
|
nodes: collectEditableNodes(editContentRef.current),
|
|
30937
31126
|
sections
|
|
@@ -32146,6 +32335,7 @@ export {
|
|
|
32146
32335
|
dropIndicatorVariants,
|
|
32147
32336
|
ensureFooterTree,
|
|
32148
32337
|
filterAvailablePages,
|
|
32338
|
+
foldAlignIntoTrees,
|
|
32149
32339
|
getEditModeInitialState,
|
|
32150
32340
|
insertFooterHours,
|
|
32151
32341
|
isEditSessionActive,
|
|
@@ -32154,6 +32344,7 @@ export {
|
|
|
32154
32344
|
isValidUrl,
|
|
32155
32345
|
nextViableSlide,
|
|
32156
32346
|
parseAiFooterState,
|
|
32347
|
+
parseAiSectionsState,
|
|
32157
32348
|
parseTarget,
|
|
32158
32349
|
removeFooterBlock,
|
|
32159
32350
|
resolveFooterCopyright,
|