@ohhwells/bridge 0.1.146 → 0.1.148
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 +108 -14
- 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 +107 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -469,6 +469,13 @@ interface AiSectionsState {
|
|
|
469
469
|
}
|
|
470
470
|
/** Parse a persisted value defensively — malformed state renders nothing, never throws. */
|
|
471
471
|
declare function parseAiSectionsState(raw: string | null | undefined): AiSectionsState;
|
|
472
|
+
/**
|
|
473
|
+
* Drop every `text-align` declaration from the inline style attributes in one content string,
|
|
474
|
+
* removing a style attribute that carried nothing else. Regex rather than DOMParser so the fold
|
|
475
|
+
* stays pure and usable outside a browser; the only authors of these attributes are the bridge's
|
|
476
|
+
* own `sanitizeHtml` and the model's alignment wraps, which both emit double-quoted attributes.
|
|
477
|
+
*/
|
|
478
|
+
declare function stripTextAlignCss(html: string): string;
|
|
472
479
|
/**
|
|
473
480
|
* Fold alignment overrides that target GENERATED sections into their trees, where alignment is
|
|
474
481
|
* first-class data (block.align) that persists with the rest of the tree. A node override
|
|
@@ -867,4 +874,4 @@ declare function useOhwCarousel(key: string, initial: CarouselSlide[]): {
|
|
|
867
874
|
bind: Record<string, string>;
|
|
868
875
|
};
|
|
869
876
|
|
|
870
|
-
export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OhhwellsBridge, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, insertFooterHours, isEditSessionActive, isRenderableFooterTree, isRenderableTree, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, removeFooterBlock, resolveFooterCopyright, serializeAiFooterState, stepViableSlide, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
|
|
877
|
+
export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OhhwellsBridge, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, insertFooterHours, isEditSessionActive, isRenderableFooterTree, isRenderableTree, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, removeFooterBlock, resolveFooterCopyright, serializeAiFooterState, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
|
package/dist/index.d.ts
CHANGED
|
@@ -469,6 +469,13 @@ interface AiSectionsState {
|
|
|
469
469
|
}
|
|
470
470
|
/** Parse a persisted value defensively — malformed state renders nothing, never throws. */
|
|
471
471
|
declare function parseAiSectionsState(raw: string | null | undefined): AiSectionsState;
|
|
472
|
+
/**
|
|
473
|
+
* Drop every `text-align` declaration from the inline style attributes in one content string,
|
|
474
|
+
* removing a style attribute that carried nothing else. Regex rather than DOMParser so the fold
|
|
475
|
+
* stays pure and usable outside a browser; the only authors of these attributes are the bridge's
|
|
476
|
+
* own `sanitizeHtml` and the model's alignment wraps, which both emit double-quoted attributes.
|
|
477
|
+
*/
|
|
478
|
+
declare function stripTextAlignCss(html: string): string;
|
|
472
479
|
/**
|
|
473
480
|
* Fold alignment overrides that target GENERATED sections into their trees, where alignment is
|
|
474
481
|
* first-class data (block.align) that persists with the rest of the tree. A node override
|
|
@@ -867,4 +874,4 @@ declare function useOhwCarousel(key: string, initial: CarouselSlide[]): {
|
|
|
867
874
|
bind: Record<string, string>;
|
|
868
875
|
};
|
|
869
876
|
|
|
870
|
-
export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OhhwellsBridge, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, insertFooterHours, isEditSessionActive, isRenderableFooterTree, isRenderableTree, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, removeFooterBlock, resolveFooterCopyright, serializeAiFooterState, stepViableSlide, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
|
|
877
|
+
export { AI_DEFAULT_BRAND, AI_FOOTER_KEY, AI_TREE_SCHEMA_VERSIONS, AI_TREE_TOKENS, type AiBlockNode, type AiBrandKit, type AiFooterBottomBar, type AiFooterColumn, type AiFooterLayoutTree, AiFooterRenderer, type AiFooterRendererProps, type AiLayoutTree, AiTreeRenderer, type AiTreeRendererProps, type CarouselSlide, CustomToolbar, CustomToolbarButton, CustomToolbarDivider, DragHandle, DropIndicator, type DropIndicatorProps, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptySection, type EmptySectionProps, FOOTER_COLUMN_BLOCKS, FOOTER_COLUMN_SPANS, FOOTER_SOCIAL_PLATFORMS, ItemActionToolbar, type ItemActionToolbarProps, ItemInteractionLayer, type ItemInteractionLayerProps, type ItemInteractionState, LinkEditorPanel, type LinkModalMode, type LinkModalProps, type LinkPage, LinkPopover, type LinkSection, OhhwellsBridge, SchedulingWidget, type SectionScaffold, type SiteLegalLinks, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addFooterLinkColumn, appendFooterSocial, buildDefaultFooterTree, buildTarget, dropIndicatorVariants, ensureFooterTree, filterAvailablePages, foldAlignIntoTrees, getEditModeInitialState, insertFooterHours, isEditSessionActive, isRenderableFooterTree, isRenderableTree, isValidUrl, nextViableSlide, parseAiFooterState, parseAiSectionsState, parseTarget, removeFooterBlock, resolveFooterCopyright, serializeAiFooterState, stepViableSlide, stripTextAlignCss, toggleVariants, useOhwCarousel, validateUrlInput, viableSlides };
|
package/dist/index.js
CHANGED
|
@@ -1476,7 +1476,19 @@ function brandTrackedFontFamily(doc, stack) {
|
|
|
1476
1476
|
}
|
|
1477
1477
|
var paintLockByEl = /* @__PURE__ */ new WeakMap();
|
|
1478
1478
|
var paintObserverByEl = /* @__PURE__ */ new WeakMap();
|
|
1479
|
-
var
|
|
1479
|
+
var PAINT_GUARD_ATTRS = {
|
|
1480
|
+
attributes: true,
|
|
1481
|
+
attributeFilter: ["style", "class"]
|
|
1482
|
+
};
|
|
1483
|
+
function paintGuarded(el, assignment, tokens) {
|
|
1484
|
+
const observer = paintObserverByEl.get(el);
|
|
1485
|
+
observer?.disconnect();
|
|
1486
|
+
try {
|
|
1487
|
+
paintButtonChrome(el, assignment, tokens);
|
|
1488
|
+
} finally {
|
|
1489
|
+
observer?.observe(el, PAINT_GUARD_ATTRS);
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1480
1492
|
function paintButtonChrome(el, assignment, tokens) {
|
|
1481
1493
|
const origin = captureButtonOrigin(el);
|
|
1482
1494
|
const chrome = tokens.variants[assignment.variant];
|
|
@@ -1515,14 +1527,11 @@ function paintButtonChrome(el, assignment, tokens) {
|
|
|
1515
1527
|
function guardTemplateHover(el) {
|
|
1516
1528
|
if (paintObserverByEl.has(el)) return;
|
|
1517
1529
|
const observer = new MutationObserver(() => {
|
|
1518
|
-
if (paintingButton) return;
|
|
1519
1530
|
const lock = paintLockByEl.get(el);
|
|
1520
1531
|
if (!lock) return;
|
|
1521
|
-
|
|
1522
|
-
paintButtonChrome(el, lock.assignment, lock.tokens);
|
|
1523
|
-
paintingButton = false;
|
|
1532
|
+
paintGuarded(el, lock.assignment, lock.tokens);
|
|
1524
1533
|
});
|
|
1525
|
-
observer.observe(el,
|
|
1534
|
+
observer.observe(el, PAINT_GUARD_ATTRS);
|
|
1526
1535
|
paintObserverByEl.set(el, observer);
|
|
1527
1536
|
}
|
|
1528
1537
|
function paintedTokensOf(el) {
|
|
@@ -1539,10 +1548,8 @@ function applyButtonStyle(el, assignment, tokens) {
|
|
|
1539
1548
|
}
|
|
1540
1549
|
};
|
|
1541
1550
|
paintLockByEl.set(el, { assignment, tokens: tracked });
|
|
1542
|
-
paintingButton = true;
|
|
1543
|
-
paintButtonChrome(el, assignment, tracked);
|
|
1544
|
-
paintingButton = false;
|
|
1545
1551
|
guardTemplateHover(el);
|
|
1552
|
+
paintGuarded(el, assignment, tracked);
|
|
1546
1553
|
}
|
|
1547
1554
|
function applyButtonStylesFromContent(doc, content) {
|
|
1548
1555
|
const assignments = readAssignments(content);
|
|
@@ -6172,6 +6179,26 @@ function applyTreeToState(state, payload) {
|
|
|
6172
6179
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
6173
6180
|
return { ...state, v: 1, sections: [...others, entry] };
|
|
6174
6181
|
}
|
|
6182
|
+
function stripTextAlignCss(html) {
|
|
6183
|
+
return html.replace(/\sstyle="([^"]*)"/gi, (whole, value) => {
|
|
6184
|
+
if (!/text-align\s*:/i.test(value)) return whole;
|
|
6185
|
+
const kept = value.split(";").map((decl) => decl.trim()).filter((decl) => decl && !/^text-align\s*:/i.test(decl)).join("; ");
|
|
6186
|
+
return kept ? ` style="${kept}"` : "";
|
|
6187
|
+
});
|
|
6188
|
+
}
|
|
6189
|
+
function stripTextAlignInValue(value) {
|
|
6190
|
+
if (typeof value === "string") return stripTextAlignCss(value);
|
|
6191
|
+
if (Array.isArray(value)) return value.map(stripTextAlignInValue);
|
|
6192
|
+
if (value && typeof value === "object") {
|
|
6193
|
+
return Object.fromEntries(
|
|
6194
|
+
Object.entries(value).map(([key, inner]) => [
|
|
6195
|
+
key,
|
|
6196
|
+
stripTextAlignInValue(inner)
|
|
6197
|
+
])
|
|
6198
|
+
);
|
|
6199
|
+
}
|
|
6200
|
+
return value;
|
|
6201
|
+
}
|
|
6175
6202
|
function foldAlignIntoTrees(state, store) {
|
|
6176
6203
|
const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
|
|
6177
6204
|
const nextTrees = /* @__PURE__ */ new Map();
|
|
@@ -6194,6 +6221,12 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6194
6221
|
return stripChildAligns(rest);
|
|
6195
6222
|
})
|
|
6196
6223
|
} : node;
|
|
6224
|
+
const stripContentAligns = (node) => ({
|
|
6225
|
+
...node,
|
|
6226
|
+
...node.slots ? { slots: stripTextAlignInValue(node.slots) } : {},
|
|
6227
|
+
...node.children ? { children: node.children.map(stripContentAligns) } : {}
|
|
6228
|
+
});
|
|
6229
|
+
const authoritative = (block) => stripChildAligns(stripContentAligns(block));
|
|
6197
6230
|
const nodes = {};
|
|
6198
6231
|
for (const [key, override] of Object.entries(store.nodes)) {
|
|
6199
6232
|
const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
|
|
@@ -6205,7 +6238,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6205
6238
|
nodes[key] = override;
|
|
6206
6239
|
continue;
|
|
6207
6240
|
}
|
|
6208
|
-
row.blocks[blockIdx] = { ...
|
|
6241
|
+
row.blocks[blockIdx] = { ...authoritative(block), align: override.align };
|
|
6209
6242
|
const rest = { ...override };
|
|
6210
6243
|
delete rest.align;
|
|
6211
6244
|
if (Object.keys(rest).length > 0) nodes[key] = rest;
|
|
@@ -6218,7 +6251,7 @@ function foldAlignIntoTrees(state, store) {
|
|
|
6218
6251
|
continue;
|
|
6219
6252
|
}
|
|
6220
6253
|
for (const row of tree.rows) {
|
|
6221
|
-
row.blocks = row.blocks.map((block) => ({ ...
|
|
6254
|
+
row.blocks = row.blocks.map((block) => ({ ...authoritative(block), align: override.align }));
|
|
6222
6255
|
}
|
|
6223
6256
|
const rest = { ...override };
|
|
6224
6257
|
delete rest.align;
|
|
@@ -30124,14 +30157,73 @@ function OhhwellsBridge() {
|
|
|
30124
30157
|
value = JSON.stringify(foldedHeight.store);
|
|
30125
30158
|
}
|
|
30126
30159
|
}
|
|
30160
|
+
const restoreNodes = e.data.restoreNodes;
|
|
30161
|
+
const restored = [];
|
|
30162
|
+
if (restoreNodes && typeof restoreNodes === "object") {
|
|
30163
|
+
for (const [key, html] of Object.entries(restoreNodes)) {
|
|
30164
|
+
if (typeof html !== "string") continue;
|
|
30165
|
+
const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
30166
|
+
if (els.length === 0) continue;
|
|
30167
|
+
for (const el of Array.from(els)) el.innerHTML = html;
|
|
30168
|
+
editContentRef.current = { ...editContentRef.current, [key]: html };
|
|
30169
|
+
restored.push({ key, text: html });
|
|
30170
|
+
}
|
|
30171
|
+
}
|
|
30172
|
+
const previousNodes = {};
|
|
30173
|
+
const strippedNodes = [];
|
|
30174
|
+
if (!restoreNodes) {
|
|
30175
|
+
const aligned = parseStyleStore(value);
|
|
30176
|
+
const prior = parseStyleStore(previous);
|
|
30177
|
+
const keys = /* @__PURE__ */ new Set();
|
|
30178
|
+
if (aligned) {
|
|
30179
|
+
for (const [key, override] of Object.entries(aligned.nodes)) {
|
|
30180
|
+
if (override.align === void 0) continue;
|
|
30181
|
+
if (prior?.nodes[key]?.align === override.align) continue;
|
|
30182
|
+
keys.add(key);
|
|
30183
|
+
}
|
|
30184
|
+
for (const [sectionId, override] of Object.entries(aligned.sections)) {
|
|
30185
|
+
if (override.align === void 0) continue;
|
|
30186
|
+
if (prior?.sections[sectionId]?.align === override.align) continue;
|
|
30187
|
+
const escaped = CSS.escape(sectionId);
|
|
30188
|
+
const markers = document.querySelectorAll(
|
|
30189
|
+
`[data-ohw-instance="${escaped}"], [data-ohw-section="${escaped}"]`
|
|
30190
|
+
);
|
|
30191
|
+
for (const marker of Array.from(markers)) {
|
|
30192
|
+
const editables = marker.querySelectorAll(
|
|
30193
|
+
'[data-ohw-key][data-ohw-editable="text"], [data-ohw-key][data-ohw-editable="plain"]'
|
|
30194
|
+
);
|
|
30195
|
+
for (const el of Array.from(editables)) {
|
|
30196
|
+
const key = el.getAttribute("data-ohw-key");
|
|
30197
|
+
if (key) keys.add(key);
|
|
30198
|
+
}
|
|
30199
|
+
}
|
|
30200
|
+
}
|
|
30201
|
+
}
|
|
30202
|
+
for (const key of keys) {
|
|
30203
|
+
if (key.startsWith(AI_SLOT_KEY_PREFIX) || key.startsWith("__ohw_")) continue;
|
|
30204
|
+
const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
30205
|
+
if (els.length === 0) continue;
|
|
30206
|
+
const before = sanitizeHtml(els[0].innerHTML);
|
|
30207
|
+
const after = stripTextAlignCss(before);
|
|
30208
|
+
if (after === before) continue;
|
|
30209
|
+
for (const el of Array.from(els)) el.innerHTML = after;
|
|
30210
|
+
previousNodes[key] = before;
|
|
30211
|
+
editContentRef.current = { ...editContentRef.current, [key]: after };
|
|
30212
|
+
strippedNodes.push({ key, text: after });
|
|
30213
|
+
}
|
|
30214
|
+
}
|
|
30127
30215
|
stylesRef.current = value;
|
|
30128
30216
|
applyStylesToDom(parseStyleStore(value));
|
|
30129
|
-
postToParentRef.current({
|
|
30217
|
+
postToParentRef.current({
|
|
30218
|
+
type: "ow:change",
|
|
30219
|
+
nodes: [{ key: STYLE_STORE_KEY, text: value }, ...strippedNodes, ...restored]
|
|
30220
|
+
});
|
|
30130
30221
|
postToParentRef.current({
|
|
30131
30222
|
type: "ow:ai-styles-applied",
|
|
30132
30223
|
previous,
|
|
30133
30224
|
value,
|
|
30134
|
-
...previousSections !== void 0 ? { previousSections } : {}
|
|
30225
|
+
...previousSections !== void 0 ? { previousSections } : {},
|
|
30226
|
+
...Object.keys(previousNodes).length > 0 ? { previousNodes } : {}
|
|
30135
30227
|
});
|
|
30136
30228
|
};
|
|
30137
30229
|
window.addEventListener("message", handleAiSetStyles);
|
|
@@ -31476,7 +31568,7 @@ function OhhwellsBridge() {
|
|
|
31476
31568
|
postToParent2({
|
|
31477
31569
|
type: "ow:ready",
|
|
31478
31570
|
version: "1",
|
|
31479
|
-
bridgeVersion: "0.1.
|
|
31571
|
+
bridgeVersion: "0.1.147",
|
|
31480
31572
|
path: pathname,
|
|
31481
31573
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31482
31574
|
sections
|
|
@@ -32706,6 +32798,7 @@ export {
|
|
|
32706
32798
|
resolveFooterCopyright,
|
|
32707
32799
|
serializeAiFooterState,
|
|
32708
32800
|
stepViableSlide,
|
|
32801
|
+
stripTextAlignCss,
|
|
32709
32802
|
toggleVariants,
|
|
32710
32803
|
useOhwCarousel,
|
|
32711
32804
|
validateUrlInput,
|