@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.cjs CHANGED
@@ -8250,6 +8250,27 @@ function deleteSectionInstance(instanceId, currentPath, existingEntries) {
8250
8250
  function restoreSectionInstance(instanceId, currentPath, existingEntries) {
8251
8251
  return setSectionRemoved(instanceId, currentPath, existingEntries, false);
8252
8252
  }
8253
+ function duplicateSectionInstance(instanceId, newId, currentPath, existingEntries) {
8254
+ const original = findByInstanceId(instanceId);
8255
+ if (!original) return null;
8256
+ const clone = original.cloneNode(true);
8257
+ clone.setAttribute("data-ohw-instance", newId);
8258
+ const keyRekeys = rekeySectionSubtree(clone, newId);
8259
+ original.insertAdjacentElement("afterend", clone);
8260
+ const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
8261
+ const entries = topLevelSections().map((el, order) => {
8262
+ const id = instanceIdOf(el);
8263
+ return {
8264
+ instanceId: id,
8265
+ type: el.getAttribute("data-ohw-section") ?? "",
8266
+ order,
8267
+ pagePath: currentPath,
8268
+ ...byId.get(id)?.removed ? { removed: true } : {}
8269
+ };
8270
+ });
8271
+ applyPersistedOrder(entries);
8272
+ return { entries, keyRekeys };
8273
+ }
8253
8274
  function newInstanceId() {
8254
8275
  return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `instance-${Date.now()}-${Math.random().toString(36).slice(2)}`;
8255
8276
  }
@@ -8264,14 +8285,20 @@ function getPageSectionOrderEntries(raw, currentPath) {
8264
8285
  }
8265
8286
  function rekeySectionSubtree(root, instanceId) {
8266
8287
  const suffix = `::${instanceId}`;
8288
+ const pairs = [];
8267
8289
  const rekey = (el, attr) => {
8268
8290
  const current = el.getAttribute(attr);
8269
- if (current) el.setAttribute(attr, `${current}${suffix}`);
8291
+ if (!current) return;
8292
+ const base = current.includes("::") ? current.slice(0, current.indexOf("::")) : current;
8293
+ const next = `${base}${suffix}`;
8294
+ el.setAttribute(attr, next);
8295
+ pairs.push({ from: current, to: next });
8270
8296
  };
8271
8297
  if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
8272
8298
  if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
8273
8299
  root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
8274
8300
  root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
8301
+ return pairs;
8275
8302
  }
8276
8303
  function initSectionInstancesFromContent(content, currentPath) {
8277
8304
  document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
@@ -17969,6 +17996,7 @@ function OhhwellsBridge() {
17969
17996
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
17970
17997
  }
17971
17998
  applyBrandChrome(content);
17999
+ initSectionInstancesFromContent(content, window.location.pathname);
17972
18000
  for (const [key, val] of Object.entries(content)) {
17973
18001
  if (key === "__ohw_sections") continue;
17974
18002
  if (key === AI_SECTIONS_KEY) continue;
@@ -18024,7 +18052,6 @@ function OhhwellsBridge() {
18024
18052
  if (isEditModeRef.current) requestMissingSocialIconsRef.current();
18025
18053
  enforceLinkHrefs();
18026
18054
  initSectionsFromContent(content, true);
18027
- initSectionInstancesFromContent(content, window.location.pathname);
18028
18055
  sectionsLoadedRef.current = true;
18029
18056
  pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
18030
18057
  if (imageLoads.length === 0) return Promise.resolve();
@@ -20090,6 +20117,7 @@ function OhhwellsBridge() {
20090
20117
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
20091
20118
  }
20092
20119
  applyBrandChrome(content);
20120
+ initSectionInstancesFromContent(content, window.location.pathname);
20093
20121
  let sectionsJson = null;
20094
20122
  for (const [key, val] of Object.entries(content)) {
20095
20123
  if (key === "__ohw_sections") {
@@ -20131,7 +20159,6 @@ function OhhwellsBridge() {
20131
20159
  sectionsLoadedRef.current = true;
20132
20160
  pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
20133
20161
  }
20134
- initSectionInstancesFromContent(content, window.location.pathname);
20135
20162
  editContentRef.current = { ...editContentRef.current, ...content };
20136
20163
  reconcileNavbarItemsFromContent(editContentRef.current);
20137
20164
  reconcileFooterOrderFromContent(editContentRef.current);
@@ -20353,6 +20380,34 @@ function OhhwellsBridge() {
20353
20380
  });
20354
20381
  };
20355
20382
  window.addEventListener("message", handleDeleteSection);
20383
+ const handleDuplicateSection = (e) => {
20384
+ if (e.data?.type !== "ow:duplicate-section") return;
20385
+ const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
20386
+ if (!instanceId) return;
20387
+ const newId = newInstanceId();
20388
+ const currentEntries = getPageSectionOrderEntries(editContentRef.current[SECTION_ORDER_KEY], window.location.pathname);
20389
+ const result = duplicateSectionInstance(instanceId, newId, window.location.pathname, currentEntries);
20390
+ if (!result) return;
20391
+ const { entries, keyRekeys } = result;
20392
+ const orderJson = JSON.stringify(entries);
20393
+ const nodes = [{ key: SECTION_ORDER_KEY, text: orderJson }];
20394
+ for (const { from, to } of keyRekeys) {
20395
+ const inherited = editContentRef.current[from];
20396
+ if (inherited !== void 0) nodes.push({ key: to, text: inherited });
20397
+ }
20398
+ editContentRef.current = {
20399
+ ...editContentRef.current,
20400
+ ...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
20401
+ };
20402
+ setAiSectionOrder(orderJson, window.location.pathname);
20403
+ postToParentRef.current({ type: "ow:change", nodes });
20404
+ window.dispatchEvent(new Event("resize"));
20405
+ const duplicateHeight = document.body.scrollHeight;
20406
+ if (duplicateHeight > 50) postToParentRef.current({ type: "ow:height", height: duplicateHeight });
20407
+ const clone = document.querySelector(`[data-ohw-instance="${CSS.escape(newId)}"]`);
20408
+ if (clone) aiSectionApiRef.current?.selectFromElement(clone);
20409
+ };
20410
+ window.addEventListener("message", handleDuplicateSection);
20356
20411
  const handleDeactivate = (e) => {
20357
20412
  if (e.data?.type !== "ow:deactivate") return;
20358
20413
  if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
@@ -21039,6 +21094,7 @@ function OhhwellsBridge() {
21039
21094
  window.removeEventListener("message", handleMoveSection);
21040
21095
  window.removeEventListener("message", handlePanelDragging);
21041
21096
  window.removeEventListener("message", handleDeleteSection);
21097
+ window.removeEventListener("message", handleDuplicateSection);
21042
21098
  window.removeEventListener("message", handleDeactivate);
21043
21099
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
21044
21100
  window.removeEventListener("message", handleToastAction);
@@ -21246,7 +21302,7 @@ function OhhwellsBridge() {
21246
21302
  postToParent2({
21247
21303
  type: "ow:ready",
21248
21304
  version: "1",
21249
- bridgeVersion: "0.1.86",
21305
+ bridgeVersion: "0.1.87",
21250
21306
  path: pathname,
21251
21307
  nodes: collectEditableNodes(editContentRef.current),
21252
21308
  sections