@ohhwells/bridge 0.1.86 → 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) => {
@@ -11196,6 +11223,7 @@ function iconMarkupSizedFor(slot, markup) {
11196
11223
  holder.innerHTML = markup;
11197
11224
  const glyph = holder.querySelector(GLYPH_SELECTOR);
11198
11225
  if (!glyph) return markup;
11226
+ glyph.style.display = "block";
11199
11227
  if (!box) {
11200
11228
  glyph.style.width = "1.5em";
11201
11229
  glyph.style.height = "1.5em";
@@ -17968,6 +17996,7 @@ function OhhwellsBridge() {
17968
17996
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
17969
17997
  }
17970
17998
  applyBrandChrome(content);
17999
+ initSectionInstancesFromContent(content, window.location.pathname);
17971
18000
  for (const [key, val] of Object.entries(content)) {
17972
18001
  if (key === "__ohw_sections") continue;
17973
18002
  if (key === AI_SECTIONS_KEY) continue;
@@ -18023,7 +18052,6 @@ function OhhwellsBridge() {
18023
18052
  if (isEditModeRef.current) requestMissingSocialIconsRef.current();
18024
18053
  enforceLinkHrefs();
18025
18054
  initSectionsFromContent(content, true);
18026
- initSectionInstancesFromContent(content, window.location.pathname);
18027
18055
  sectionsLoadedRef.current = true;
18028
18056
  pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
18029
18057
  if (imageLoads.length === 0) return Promise.resolve();
@@ -20089,6 +20117,7 @@ function OhhwellsBridge() {
20089
20117
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
20090
20118
  }
20091
20119
  applyBrandChrome(content);
20120
+ initSectionInstancesFromContent(content, window.location.pathname);
20092
20121
  let sectionsJson = null;
20093
20122
  for (const [key, val] of Object.entries(content)) {
20094
20123
  if (key === "__ohw_sections") {
@@ -20130,7 +20159,6 @@ function OhhwellsBridge() {
20130
20159
  sectionsLoadedRef.current = true;
20131
20160
  pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
20132
20161
  }
20133
- initSectionInstancesFromContent(content, window.location.pathname);
20134
20162
  editContentRef.current = { ...editContentRef.current, ...content };
20135
20163
  reconcileNavbarItemsFromContent(editContentRef.current);
20136
20164
  reconcileFooterOrderFromContent(editContentRef.current);
@@ -20352,6 +20380,34 @@ function OhhwellsBridge() {
20352
20380
  });
20353
20381
  };
20354
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);
20355
20411
  const handleDeactivate = (e) => {
20356
20412
  if (e.data?.type !== "ow:deactivate") return;
20357
20413
  if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
@@ -21038,6 +21094,7 @@ function OhhwellsBridge() {
21038
21094
  window.removeEventListener("message", handleMoveSection);
21039
21095
  window.removeEventListener("message", handlePanelDragging);
21040
21096
  window.removeEventListener("message", handleDeleteSection);
21097
+ window.removeEventListener("message", handleDuplicateSection);
21041
21098
  window.removeEventListener("message", handleDeactivate);
21042
21099
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
21043
21100
  window.removeEventListener("message", handleToastAction);
@@ -21245,7 +21302,7 @@ function OhhwellsBridge() {
21245
21302
  postToParent2({
21246
21303
  type: "ow:ready",
21247
21304
  version: "1",
21248
- bridgeVersion: "0.1.85",
21305
+ bridgeVersion: "0.1.87",
21249
21306
  path: pathname,
21250
21307
  nodes: collectEditableNodes(editContentRef.current),
21251
21308
  sections