@ohhwells/bridge 0.1.87 → 0.1.88

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