@ohhwells/bridge 0.1.146 → 0.1.147

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,
@@ -6266,6 +6267,26 @@ function applyTreeToState(state, payload) {
6266
6267
  const others = state.sections.filter((existing) => existing.id !== entry.id);
6267
6268
  return { ...state, v: 1, sections: [...others, entry] };
6268
6269
  }
6270
+ function stripTextAlignCss(html) {
6271
+ return html.replace(/\sstyle="([^"]*)"/gi, (whole, value) => {
6272
+ if (!/text-align\s*:/i.test(value)) return whole;
6273
+ const kept = value.split(";").map((decl) => decl.trim()).filter((decl) => decl && !/^text-align\s*:/i.test(decl)).join("; ");
6274
+ return kept ? ` style="${kept}"` : "";
6275
+ });
6276
+ }
6277
+ function stripTextAlignInValue(value) {
6278
+ if (typeof value === "string") return stripTextAlignCss(value);
6279
+ if (Array.isArray(value)) return value.map(stripTextAlignInValue);
6280
+ if (value && typeof value === "object") {
6281
+ return Object.fromEntries(
6282
+ Object.entries(value).map(([key, inner]) => [
6283
+ key,
6284
+ stripTextAlignInValue(inner)
6285
+ ])
6286
+ );
6287
+ }
6288
+ return value;
6289
+ }
6269
6290
  function foldAlignIntoTrees(state, store) {
6270
6291
  const byId = new Map(state.sections.map((entry) => [entry.id, entry]));
6271
6292
  const nextTrees = /* @__PURE__ */ new Map();
@@ -6288,6 +6309,12 @@ function foldAlignIntoTrees(state, store) {
6288
6309
  return stripChildAligns(rest);
6289
6310
  })
6290
6311
  } : node;
6312
+ const stripContentAligns = (node) => ({
6313
+ ...node,
6314
+ ...node.slots ? { slots: stripTextAlignInValue(node.slots) } : {},
6315
+ ...node.children ? { children: node.children.map(stripContentAligns) } : {}
6316
+ });
6317
+ const authoritative = (block) => stripChildAligns(stripContentAligns(block));
6291
6318
  const nodes = {};
6292
6319
  for (const [key, override] of Object.entries(store.nodes)) {
6293
6320
  const match = override.align !== void 0 && key.startsWith(AI_SLOT_KEY_PREFIX) ? key.match(/^ai\.(.+?)\.r(\d+)\.b(\d+)(?:\.|$)/) : null;
@@ -6299,7 +6326,7 @@ function foldAlignIntoTrees(state, store) {
6299
6326
  nodes[key] = override;
6300
6327
  continue;
6301
6328
  }
6302
- row.blocks[blockIdx] = { ...stripChildAligns(block), align: override.align };
6329
+ row.blocks[blockIdx] = { ...authoritative(block), align: override.align };
6303
6330
  const rest = { ...override };
6304
6331
  delete rest.align;
6305
6332
  if (Object.keys(rest).length > 0) nodes[key] = rest;
@@ -6312,7 +6339,7 @@ function foldAlignIntoTrees(state, store) {
6312
6339
  continue;
6313
6340
  }
6314
6341
  for (const row of tree.rows) {
6315
- row.blocks = row.blocks.map((block) => ({ ...stripChildAligns(block), align: override.align }));
6342
+ row.blocks = row.blocks.map((block) => ({ ...authoritative(block), align: override.align }));
6316
6343
  }
6317
6344
  const rest = { ...override };
6318
6345
  delete rest.align;
@@ -30212,14 +30239,73 @@ function OhhwellsBridge() {
30212
30239
  value = JSON.stringify(foldedHeight.store);
30213
30240
  }
30214
30241
  }
30242
+ const restoreNodes = e.data.restoreNodes;
30243
+ const restored = [];
30244
+ if (restoreNodes && typeof restoreNodes === "object") {
30245
+ for (const [key, html] of Object.entries(restoreNodes)) {
30246
+ if (typeof html !== "string") continue;
30247
+ const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
30248
+ if (els.length === 0) continue;
30249
+ for (const el of Array.from(els)) el.innerHTML = html;
30250
+ editContentRef.current = { ...editContentRef.current, [key]: html };
30251
+ restored.push({ key, text: html });
30252
+ }
30253
+ }
30254
+ const previousNodes = {};
30255
+ const strippedNodes = [];
30256
+ if (!restoreNodes) {
30257
+ const aligned = parseStyleStore(value);
30258
+ const prior = parseStyleStore(previous);
30259
+ const keys = /* @__PURE__ */ new Set();
30260
+ if (aligned) {
30261
+ for (const [key, override] of Object.entries(aligned.nodes)) {
30262
+ if (override.align === void 0) continue;
30263
+ if (prior?.nodes[key]?.align === override.align) continue;
30264
+ keys.add(key);
30265
+ }
30266
+ for (const [sectionId, override] of Object.entries(aligned.sections)) {
30267
+ if (override.align === void 0) continue;
30268
+ if (prior?.sections[sectionId]?.align === override.align) continue;
30269
+ const escaped = CSS.escape(sectionId);
30270
+ const markers = document.querySelectorAll(
30271
+ `[data-ohw-instance="${escaped}"], [data-ohw-section="${escaped}"]`
30272
+ );
30273
+ for (const marker of Array.from(markers)) {
30274
+ const editables = marker.querySelectorAll(
30275
+ '[data-ohw-key][data-ohw-editable="text"], [data-ohw-key][data-ohw-editable="plain"]'
30276
+ );
30277
+ for (const el of Array.from(editables)) {
30278
+ const key = el.getAttribute("data-ohw-key");
30279
+ if (key) keys.add(key);
30280
+ }
30281
+ }
30282
+ }
30283
+ }
30284
+ for (const key of keys) {
30285
+ if (key.startsWith(AI_SLOT_KEY_PREFIX) || key.startsWith("__ohw_")) continue;
30286
+ const els = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
30287
+ if (els.length === 0) continue;
30288
+ const before = sanitizeHtml(els[0].innerHTML);
30289
+ const after = stripTextAlignCss(before);
30290
+ if (after === before) continue;
30291
+ for (const el of Array.from(els)) el.innerHTML = after;
30292
+ previousNodes[key] = before;
30293
+ editContentRef.current = { ...editContentRef.current, [key]: after };
30294
+ strippedNodes.push({ key, text: after });
30295
+ }
30296
+ }
30215
30297
  stylesRef.current = value;
30216
30298
  applyStylesToDom(parseStyleStore(value));
30217
- postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
30299
+ postToParentRef.current({
30300
+ type: "ow:change",
30301
+ nodes: [{ key: STYLE_STORE_KEY, text: value }, ...strippedNodes, ...restored]
30302
+ });
30218
30303
  postToParentRef.current({
30219
30304
  type: "ow:ai-styles-applied",
30220
30305
  previous,
30221
30306
  value,
30222
- ...previousSections !== void 0 ? { previousSections } : {}
30307
+ ...previousSections !== void 0 ? { previousSections } : {},
30308
+ ...Object.keys(previousNodes).length > 0 ? { previousNodes } : {}
30223
30309
  });
30224
30310
  };
30225
30311
  window.addEventListener("message", handleAiSetStyles);
@@ -31564,7 +31650,7 @@ function OhhwellsBridge() {
31564
31650
  postToParent2({
31565
31651
  type: "ow:ready",
31566
31652
  version: "1",
31567
- bridgeVersion: "0.1.145",
31653
+ bridgeVersion: "0.1.146",
31568
31654
  path: pathname,
31569
31655
  nodes: collectEditableNodes(editContentRef.current),
31570
31656
  sections
@@ -32795,6 +32881,7 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
32795
32881
  resolveFooterCopyright,
32796
32882
  serializeAiFooterState,
32797
32883
  stepViableSlide,
32884
+ stripTextAlignCss,
32798
32885
  toggleVariants,
32799
32886
  useOhwCarousel,
32800
32887
  validateUrlInput,