@ohhwells/bridge 0.1.87 → 0.1.89

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.js CHANGED
@@ -1876,6 +1876,7 @@ function findTemplateSection(id) {
1876
1876
  return null;
1877
1877
  }
1878
1878
  function findPlacementAnchor(id, exclude) {
1879
+ if (CHROME_SECTION_IDS.has(id)) return null;
1879
1880
  for (const el of document.querySelectorAll(`[data-ohw-section="${CSS.escape(id)}"]`)) {
1880
1881
  if (el === exclude) continue;
1881
1882
  if (el.parentElement?.closest("[data-ohw-section]")) continue;
@@ -8177,6 +8178,27 @@ function deleteSectionInstance(instanceId, currentPath, existingEntries) {
8177
8178
  function restoreSectionInstance(instanceId, currentPath, existingEntries) {
8178
8179
  return setSectionRemoved(instanceId, currentPath, existingEntries, false);
8179
8180
  }
8181
+ function duplicateSectionInstance(instanceId, newId, currentPath, existingEntries) {
8182
+ const original = findByInstanceId(instanceId);
8183
+ if (!original) return null;
8184
+ const clone = original.cloneNode(true);
8185
+ clone.setAttribute("data-ohw-instance", newId);
8186
+ const keyRekeys = rekeySectionSubtree(clone, newId);
8187
+ original.insertAdjacentElement("afterend", clone);
8188
+ const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
8189
+ const entries = topLevelSections().map((el, order) => {
8190
+ const id = instanceIdOf(el);
8191
+ return {
8192
+ instanceId: id,
8193
+ type: el.getAttribute("data-ohw-section") ?? "",
8194
+ order,
8195
+ pagePath: currentPath,
8196
+ ...byId.get(id)?.removed ? { removed: true } : {}
8197
+ };
8198
+ });
8199
+ applyPersistedOrder(entries);
8200
+ return { entries, keyRekeys };
8201
+ }
8180
8202
  function newInstanceId() {
8181
8203
  return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `instance-${Date.now()}-${Math.random().toString(36).slice(2)}`;
8182
8204
  }
@@ -8191,14 +8213,20 @@ function getPageSectionOrderEntries(raw, currentPath) {
8191
8213
  }
8192
8214
  function rekeySectionSubtree(root, instanceId) {
8193
8215
  const suffix = `::${instanceId}`;
8216
+ const pairs = [];
8194
8217
  const rekey = (el, attr) => {
8195
8218
  const current = el.getAttribute(attr);
8196
- if (current) el.setAttribute(attr, `${current}${suffix}`);
8219
+ if (!current) return;
8220
+ const base = current.includes("::") ? current.slice(0, current.indexOf("::")) : current;
8221
+ const next = `${base}${suffix}`;
8222
+ el.setAttribute(attr, next);
8223
+ pairs.push({ from: current, to: next });
8197
8224
  };
8198
8225
  if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
8199
8226
  if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
8200
8227
  root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
8201
8228
  root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
8229
+ return pairs;
8202
8230
  }
8203
8231
  function initSectionInstancesFromContent(content, currentPath) {
8204
8232
  document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
@@ -17902,6 +17930,7 @@ function OhhwellsBridge() {
17902
17930
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
17903
17931
  }
17904
17932
  applyBrandChrome(content);
17933
+ initSectionInstancesFromContent(content, window.location.pathname);
17905
17934
  for (const [key, val] of Object.entries(content)) {
17906
17935
  if (key === "__ohw_sections") continue;
17907
17936
  if (key === AI_SECTIONS_KEY) continue;
@@ -17957,7 +17986,6 @@ function OhhwellsBridge() {
17957
17986
  if (isEditModeRef.current) requestMissingSocialIconsRef.current();
17958
17987
  enforceLinkHrefs();
17959
17988
  initSectionsFromContent(content, true);
17960
- initSectionInstancesFromContent(content, window.location.pathname);
17961
17989
  sectionsLoadedRef.current = true;
17962
17990
  pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
17963
17991
  if (imageLoads.length === 0) return Promise.resolve();
@@ -20023,6 +20051,7 @@ function OhhwellsBridge() {
20023
20051
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
20024
20052
  }
20025
20053
  applyBrandChrome(content);
20054
+ initSectionInstancesFromContent(content, window.location.pathname);
20026
20055
  let sectionsJson = null;
20027
20056
  for (const [key, val] of Object.entries(content)) {
20028
20057
  if (key === "__ohw_sections") {
@@ -20064,7 +20093,6 @@ function OhhwellsBridge() {
20064
20093
  sectionsLoadedRef.current = true;
20065
20094
  pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
20066
20095
  }
20067
- initSectionInstancesFromContent(content, window.location.pathname);
20068
20096
  editContentRef.current = { ...editContentRef.current, ...content };
20069
20097
  reconcileNavbarItemsFromContent(editContentRef.current);
20070
20098
  reconcileFooterOrderFromContent(editContentRef.current);
@@ -20286,6 +20314,34 @@ function OhhwellsBridge() {
20286
20314
  });
20287
20315
  };
20288
20316
  window.addEventListener("message", handleDeleteSection);
20317
+ const handleDuplicateSection = (e) => {
20318
+ if (e.data?.type !== "ow:duplicate-section") return;
20319
+ const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
20320
+ if (!instanceId) return;
20321
+ const newId = newInstanceId();
20322
+ const currentEntries = getPageSectionOrderEntries(editContentRef.current[SECTION_ORDER_KEY], window.location.pathname);
20323
+ const result = duplicateSectionInstance(instanceId, newId, window.location.pathname, currentEntries);
20324
+ if (!result) return;
20325
+ const { entries, keyRekeys } = result;
20326
+ const orderJson = JSON.stringify(entries);
20327
+ const nodes = [{ key: SECTION_ORDER_KEY, text: orderJson }];
20328
+ for (const { from, to } of keyRekeys) {
20329
+ const inherited = editContentRef.current[from];
20330
+ if (inherited !== void 0) nodes.push({ key: to, text: inherited });
20331
+ }
20332
+ editContentRef.current = {
20333
+ ...editContentRef.current,
20334
+ ...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
20335
+ };
20336
+ setAiSectionOrder(orderJson, window.location.pathname);
20337
+ postToParentRef.current({ type: "ow:change", nodes });
20338
+ window.dispatchEvent(new Event("resize"));
20339
+ const duplicateHeight = document.body.scrollHeight;
20340
+ if (duplicateHeight > 50) postToParentRef.current({ type: "ow:height", height: duplicateHeight });
20341
+ const clone = document.querySelector(`[data-ohw-instance="${CSS.escape(newId)}"]`);
20342
+ if (clone) aiSectionApiRef.current?.selectFromElement(clone);
20343
+ };
20344
+ window.addEventListener("message", handleDuplicateSection);
20289
20345
  const handleDeactivate = (e) => {
20290
20346
  if (e.data?.type !== "ow:deactivate") return;
20291
20347
  if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
@@ -20972,6 +21028,7 @@ function OhhwellsBridge() {
20972
21028
  window.removeEventListener("message", handleMoveSection);
20973
21029
  window.removeEventListener("message", handlePanelDragging);
20974
21030
  window.removeEventListener("message", handleDeleteSection);
21031
+ window.removeEventListener("message", handleDuplicateSection);
20975
21032
  window.removeEventListener("message", handleDeactivate);
20976
21033
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
20977
21034
  window.removeEventListener("message", handleToastAction);
@@ -21179,7 +21236,7 @@ function OhhwellsBridge() {
21179
21236
  postToParent2({
21180
21237
  type: "ow:ready",
21181
21238
  version: "1",
21182
- bridgeVersion: "0.1.86",
21239
+ bridgeVersion: "0.1.88",
21183
21240
  path: pathname,
21184
21241
  nodes: collectEditableNodes(editContentRef.current),
21185
21242
  sections