@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 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,
@@ -1570,7 +1571,19 @@ function brandTrackedFontFamily(doc, stack) {
1570
1571
  }
1571
1572
  var paintLockByEl = /* @__PURE__ */ new WeakMap();
1572
1573
  var paintObserverByEl = /* @__PURE__ */ new WeakMap();
1573
- var paintingButton = false;
1574
+ var PAINT_GUARD_ATTRS = {
1575
+ attributes: true,
1576
+ attributeFilter: ["style", "class"]
1577
+ };
1578
+ function paintGuarded(el, assignment, tokens) {
1579
+ const observer = paintObserverByEl.get(el);
1580
+ observer?.disconnect();
1581
+ try {
1582
+ paintButtonChrome(el, assignment, tokens);
1583
+ } finally {
1584
+ observer?.observe(el, PAINT_GUARD_ATTRS);
1585
+ }
1586
+ }
1574
1587
  function paintButtonChrome(el, assignment, tokens) {
1575
1588
  const origin = captureButtonOrigin(el);
1576
1589
  const chrome = tokens.variants[assignment.variant];
@@ -1609,14 +1622,11 @@ function paintButtonChrome(el, assignment, tokens) {
1609
1622
  function guardTemplateHover(el) {
1610
1623
  if (paintObserverByEl.has(el)) return;
1611
1624
  const observer = new MutationObserver(() => {
1612
- if (paintingButton) return;
1613
1625
  const lock = paintLockByEl.get(el);
1614
1626
  if (!lock) return;
1615
- paintingButton = true;
1616
- paintButtonChrome(el, lock.assignment, lock.tokens);
1617
- paintingButton = false;
1627
+ paintGuarded(el, lock.assignment, lock.tokens);
1618
1628
  });
1619
- observer.observe(el, { attributes: true, attributeFilter: ["style", "class"] });
1629
+ observer.observe(el, PAINT_GUARD_ATTRS);
1620
1630
  paintObserverByEl.set(el, observer);
1621
1631
  }
1622
1632
  function paintedTokensOf(el) {
@@ -1633,10 +1643,8 @@ function applyButtonStyle(el, assignment, tokens) {
1633
1643
  }
1634
1644
  };
1635
1645
  paintLockByEl.set(el, { assignment, tokens: tracked });
1636
- paintingButton = true;
1637
- paintButtonChrome(el, assignment, tracked);
1638
- paintingButton = false;
1639
1646
  guardTemplateHover(el);
1647
+ paintGuarded(el, assignment, tracked);
1640
1648
  }
1641
1649
  function applyButtonStylesFromContent(doc, content) {
1642
1650
  const assignments = readAssignments(content);
@@ -6266,6 +6274,26 @@ function applyTreeToState(state, payload) {
6266
6274
  const others = state.sections.filter((existing) => existing.id !== entry.id);
6267
6275
  return { ...state, v: 1, sections: [...others, entry] };
6268
6276
  }
6277
+ function stripTextAlignCss(html) {
6278
+ return html.replace(/\sstyle="([^"]*)"/gi, (whole, value) => {
6279
+ if (!/text-align\s*:/i.test(value)) return whole;
6280
+ const kept = value.split(";").map((decl) => decl.trim()).filter((decl) => decl && !/^text-align\s*:/i.test(decl)).join("; ");
6281
+ return kept ? ` style="${kept}"` : "";
6282
+ });
6283
+ }
6284
+ function stripTextAlignInValue(value) {
6285
+ if (typeof value === "string") return stripTextAlignCss(value);
6286
+ if (Array.isArray(value)) return value.map(stripTextAlignInValue);
6287
+ if (value && typeof value === "object") {
6288
+ return Object.fromEntries(
6289
+ Object.entries(value).map(([key, inner]) => [
6290
+ key,
6291
+ stripTextAlignInValue(inner)
6292
+ ])
6293
+ );
6294
+ }
6295
+ return value;
6296
+ }
6269
6297
  function foldAlignIntoTrees(state, store) {
6270
6298
  const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
6271
6299
  const nextTrees = /* @__PURE__ */ new Map();
@@ -6288,6 +6316,12 @@ function foldAlignIntoTrees(state, store) {
6288
6316
  return stripChildAligns(rest);
6289
6317
  })
6290
6318
  } : node;
6319
+ const stripContentAligns = (node) => ({
6320
+ ...node,
6321
+ ...node.slots ? { slots: stripTextAlignInValue(node.slots) } : {},
6322
+ ...node.children ? { children: node.children.map(stripContentAligns) } : {}
6323
+ });
6324
+ const authoritative = (block) => stripChildAligns(stripContentAligns(block));
6291
6325
  const nodes = {};
6292
6326
  for (const [key, override] of Object.entries(store.nodes)) {
6293
6327
  const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
@@ -6299,7 +6333,7 @@ function foldAlignIntoTrees(state, store) {
6299
6333
  nodes[key] = override;
6300
6334
  continue;
6301
6335
  }
6302
- row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
6336
+ row.blocks[blockIdx] = { ...authoritative(block), align: override.align };
6303
6337
  const rest = { ...override };
6304
6338
  delete rest.align;
6305
6339
  if (Object.keys(rest).length > 0) nodes[key] = rest;
@@ -6312,7 +6346,7 @@ function foldAlignIntoTrees(state, store) {
6312
6346
  continue;
6313
6347
  }
6314
6348
  for (const row of tree.rows) {
6315
- row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
6349
+ row.blocks = row.blocks.map((block) => ({ ...authoritative(block), align: override.align }));
6316
6350
  }
6317
6351
  const rest = { ...override };
6318
6352
  delete rest.align;
@@ -30212,14 +30246,73 @@ function OhhwellsBridge() {
30212
30246
  value = JSON.stringify(foldedHeight.store);
30213
30247
  }
30214
30248
  }
30249
+ const restoreNodes = e.data.restoreNodes;
30250
+ const restored = [];
30251
+ if (restoreNodes && typeof restoreNodes === "object") {
30252
+ for (const [key, html] of Object.entries(restoreNodes)) {
30253
+ if (typeof html !== "string") continue;
30254
+ const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
30255
+ if (els.length === 0) continue;
30256
+ for (const el of Array.from(els)) el.innerHTML = html;
30257
+ editContentRef.current = { ...editContentRef.current, [key]: html };
30258
+ restored.push({ key, text: html });
30259
+ }
30260
+ }
30261
+ const previousNodes = {};
30262
+ const strippedNodes = [];
30263
+ if (!restoreNodes) {
30264
+ const aligned = parseStyleStore(value);
30265
+ const prior = parseStyleStore(previous);
30266
+ const keys = /* @__PURE__ */ new Set();
30267
+ if (aligned) {
30268
+ for (const [key, override] of Object.entries(aligned.nodes)) {
30269
+ if (override.align === void 0) continue;
30270
+ if (prior?.nodes[key]?.align === override.align) continue;
30271
+ keys.add(key);
30272
+ }
30273
+ for (const [sectionId, override] of Object.entries(aligned.sections)) {
30274
+ if (override.align === void 0) continue;
30275
+ if (prior?.sections[sectionId]?.align === override.align) continue;
30276
+ const escaped = CSS.escape(sectionId);
30277
+ const markers = document.querySelectorAll(
30278
+ `[data-ohw-instance="${escaped}"], [data-ohw-section="${escaped}"]`
30279
+ );
30280
+ for (const marker of Array.from(markers)) {
30281
+ const editables = marker.querySelectorAll(
30282
+ '[data-ohw-key][data-ohw-editable="text"], [data-ohw-key][data-ohw-editable="plain"]'
30283
+ );
30284
+ for (const el of Array.from(editables)) {
30285
+ const key = el.getAttribute("data-ohw-key");
30286
+ if (key) keys.add(key);
30287
+ }
30288
+ }
30289
+ }
30290
+ }
30291
+ for (const key of keys) {
30292
+ if (key.startsWith(AI_SLOT_KEY_PREFIX) || key.startsWith("__ohw_")) continue;
30293
+ const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
30294
+ if (els.length === 0) continue;
30295
+ const before = sanitizeHtml(els[0].innerHTML);
30296
+ const after = stripTextAlignCss(before);
30297
+ if (after === before) continue;
30298
+ for (const el of Array.from(els)) el.innerHTML = after;
30299
+ previousNodes[key] = before;
30300
+ editContentRef.current = { ...editContentRef.current, [key]: after };
30301
+ strippedNodes.push({ key, text: after });
30302
+ }
30303
+ }
30215
30304
  stylesRef.current = value;
30216
30305
  applyStylesToDom(parseStyleStore(value));
30217
- postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
30306
+ postToParentRef.current({
30307
+ type: "ow:change",
30308
+ nodes: [{ key: STYLE_STORE_KEY, text: value }, ...strippedNodes, ...restored]
30309
+ });
30218
30310
  postToParentRef.current({
30219
30311
  type: "ow:ai-styles-applied",
30220
30312
  previous,
30221
30313
  value,
30222
- ...previousSections !== void 0 ? { previousSections } : {}
30314
+ ...previousSections !== void 0 ? { previousSections } : {},
30315
+ ...Object.keys(previousNodes).length > 0 ? { previousNodes } : {}
30223
30316
  });
30224
30317
  };
30225
30318
  window.addEventListener("message", handleAiSetStyles);
@@ -31564,7 +31657,7 @@ function OhhwellsBridge() {
31564
31657
  postToParent2({
31565
31658
  type: "ow:ready",
31566
31659
  version: "1",
31567
- bridgeVersion: "0.1.145",
31660
+ bridgeVersion: "0.1.147",
31568
31661
  path: pathname,
31569
31662
  nodes: collectEditableNodes(editContentRef.current),
31570
31663
  sections
@@ -32795,6 +32888,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
32795
32888
  resolveFooterCopyright,
32796
32889
  serializeAiFooterState,
32797
32890
  stepViableSlide,
32891
+ stripTextAlignCss,
32798
32892
  toggleVariants,
32799
32893
  useOhwCarousel,
32800
32894
  validateUrlInput,