@ohhwells/bridge 0.1.92 → 0.1.94

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
@@ -2188,6 +2188,22 @@ function applyAiSectionsToDom(state, options) {
2188
2188
  syncRemovedSections(state);
2189
2189
  syncTemplateHidden(state, pageSections.length > 0);
2190
2190
  }
2191
+ function unmountAllAiSections() {
2192
+ for (const [, section] of mounted) {
2193
+ section.root.unmount();
2194
+ section.container.remove();
2195
+ }
2196
+ mounted.clear();
2197
+ if (typeof document === "undefined") return;
2198
+ for (const el of document.querySelectorAll(`[${REPLACED_ATTR}]`)) {
2199
+ el.style.removeProperty("display");
2200
+ el.removeAttribute(REPLACED_ATTR);
2201
+ }
2202
+ for (const el of document.querySelectorAll(`[${REMOVED_ATTR}]`)) {
2203
+ el.style.removeProperty("display");
2204
+ el.removeAttribute(REMOVED_ATTR);
2205
+ }
2206
+ }
2191
2207
 
2192
2208
  // src/useLinkHrefGuardian.ts
2193
2209
  import { useLayoutEffect } from "react";
@@ -8185,17 +8201,40 @@ var REMOVED_ATTR2 = "data-ohw-section-removed";
8185
8201
  function isRemovedSection(el) {
8186
8202
  return el.hasAttribute(REMOVED_ATTR2);
8187
8203
  }
8204
+ function movableUnit(el) {
8205
+ return el.closest("[data-ohw-section-container]") ?? el;
8206
+ }
8207
+ function sectionTypeOf(el) {
8208
+ return el.getAttribute("data-ohw-section") ?? el.querySelector("[data-ohw-section]")?.getAttribute("data-ohw-section") ?? "";
8209
+ }
8210
+ function sectionElementOf(el) {
8211
+ return el.hasAttribute("data-ohw-section") ? el : el.querySelector("[data-ohw-section]") ?? el;
8212
+ }
8213
+ function collectTopLevelUnits(predicate) {
8214
+ const seen = /* @__PURE__ */ new Set();
8215
+ const result = [];
8216
+ document.querySelectorAll("[data-ohw-section]").forEach((el) => {
8217
+ if (!predicate(el)) return;
8218
+ const unit = movableUnit(el);
8219
+ if (unit.parentElement?.closest("[data-ohw-section],[data-ohw-section-container]")) return;
8220
+ if (seen.has(unit)) return;
8221
+ seen.add(unit);
8222
+ result.push(unit);
8223
+ });
8224
+ return result;
8225
+ }
8188
8226
  function topLevelSections() {
8189
- return Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
8190
- (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el) && !isRemovedSection(el)
8191
- );
8227
+ return collectTopLevelUnits((el) => !isChromeSection(el) && !isRemovedSection(movableUnit(el)));
8192
8228
  }
8193
8229
  function instanceIdOf(el) {
8194
8230
  return el.dataset.ohwInstance ?? el.dataset.ohwSection ?? "";
8195
8231
  }
8196
8232
  function findByInstanceId(instanceId) {
8197
8233
  const escapedId = CSS.escape(instanceId);
8198
- return document.querySelector(`[data-ohw-instance="${escapedId}"]`) ?? document.querySelector(`[data-ohw-section="${escapedId}"]:not([data-ohw-instance])`);
8234
+ const direct = document.querySelector(`[data-ohw-instance="${escapedId}"]`);
8235
+ if (direct) return movableUnit(direct);
8236
+ const bare = document.querySelector(`[data-ohw-section="${escapedId}"]:not([data-ohw-instance])`);
8237
+ return bare ? movableUnit(bare) : null;
8199
8238
  }
8200
8239
  function planSectionMove(instanceId, targetIndex, currentPath) {
8201
8240
  const sections = topLevelSections();
@@ -8207,7 +8246,7 @@ function planSectionMove(instanceId, targetIndex, currentPath) {
8207
8246
  const reordered = [...others.slice(0, clamped), dragged, ...others.slice(clamped)];
8208
8247
  return reordered.map((el, order) => ({
8209
8248
  instanceId: instanceIdOf(el),
8210
- type: el.getAttribute("data-ohw-section") ?? "",
8249
+ type: sectionTypeOf(el),
8211
8250
  order,
8212
8251
  pagePath: currentPath
8213
8252
  }));
@@ -8262,13 +8301,11 @@ function applyPersistedOrder(entries) {
8262
8301
  function setSectionRemoved(instanceId, currentPath, existingEntries, removed) {
8263
8302
  if (!findByInstanceId(instanceId)) return null;
8264
8303
  const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
8265
- const allSections = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
8266
- (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
8267
- );
8304
+ const allSections = collectTopLevelUnits((el) => !isChromeSection(el));
8268
8305
  allSections.forEach((el, order) => {
8269
8306
  const id = instanceIdOf(el);
8270
8307
  if (!byId.has(id)) {
8271
- byId.set(id, { instanceId: id, type: el.getAttribute("data-ohw-section") ?? "", order, pagePath: currentPath });
8308
+ byId.set(id, { instanceId: id, type: sectionTypeOf(el), order, pagePath: currentPath });
8272
8309
  }
8273
8310
  });
8274
8311
  const target = byId.get(instanceId);
@@ -8296,7 +8333,7 @@ function duplicateSectionInstance(instanceId, newId, currentPath, existingEntrie
8296
8333
  const id = instanceIdOf(el);
8297
8334
  return {
8298
8335
  instanceId: id,
8299
- type: el.getAttribute("data-ohw-section") ?? "",
8336
+ type: sectionTypeOf(el),
8300
8337
  order,
8301
8338
  pagePath: currentPath,
8302
8339
  ...byId.get(id)?.removed ? { removed: true } : {}
@@ -8338,6 +8375,10 @@ function initSectionInstancesFromContent(content, currentPath) {
8338
8375
  document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
8339
8376
  el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
8340
8377
  });
8378
+ document.querySelectorAll("[data-ohw-section-container]:not([data-ohw-instance])").forEach((el) => {
8379
+ const type = sectionTypeOf(el);
8380
+ if (type) el.setAttribute("data-ohw-instance", type);
8381
+ });
8341
8382
  const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
8342
8383
  for (const entry of entries) {
8343
8384
  if (entry.instanceId === entry.type) continue;
@@ -8356,10 +8397,7 @@ function initSectionInstancesFromContent(content, currentPath) {
8356
8397
 
8357
8398
  // src/ui/ai-section/AiSectionOverlay.tsx
8358
8399
  import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
8359
- function findSectionElement(instanceId) {
8360
- const escaped = CSS.escape(instanceId);
8361
- return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
8362
- }
8400
+ var findSectionElement = findByInstanceId;
8363
8401
  function readRect(instanceId) {
8364
8402
  const el = findSectionElement(instanceId);
8365
8403
  if (!el) return null;
@@ -8399,7 +8437,7 @@ function useLiveSectionRect(sectionId) {
8399
8437
  }
8400
8438
  function computeSectionBoundaryFlags(instanceId) {
8401
8439
  const topLevel = topLevelSections();
8402
- const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
8440
+ const index = topLevel.findIndex((el) => instanceIdOf(el) === instanceId);
8403
8441
  if (index === -1) return { isFirst: true, isLast: true };
8404
8442
  return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
8405
8443
  }
@@ -8483,18 +8521,20 @@ function AiSectionOverlay({
8483
8521
  selectedIdRef.current = selectedId;
8484
8522
  const report = useCallback2(
8485
8523
  (el) => {
8524
+ const labelSrc = el ? sectionElementOf(el) : null;
8486
8525
  postToParent2({
8487
8526
  type: "ow:section-selected",
8488
- sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
8489
- sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
8527
+ sectionId: el ? instanceIdOf(el) || null : null,
8528
+ sectionLabel: labelSrc ? labelSrc.dataset.ohwSectionLabel ?? titleCaseSectionId(labelSrc.dataset.ohwSection ?? "") : null
8490
8529
  });
8491
8530
  },
8492
8531
  [postToParent2]
8493
8532
  );
8494
8533
  const selectFromElement = useCallback2(
8495
8534
  (el, options) => {
8496
- const sectionEl = el?.closest("[data-ohw-section]") ?? null;
8497
- const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
8535
+ const inner = el?.closest("[data-ohw-section]") ?? null;
8536
+ const sectionEl = inner ? movableUnit(inner) : null;
8537
+ const id = sectionEl ? instanceIdOf(sectionEl) || null : null;
8498
8538
  if (id === selectedIdRef.current) return;
8499
8539
  setSelectedId(id);
8500
8540
  if (options?.report !== false) report(sectionEl);
@@ -8560,7 +8600,8 @@ function AiSectionOverlay({
8560
8600
  return;
8561
8601
  }
8562
8602
  const sec = t.closest("[data-ohw-section]");
8563
- setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
8603
+ const unit = sec ? movableUnit(sec) : null;
8604
+ setHoveredId(unit ? instanceIdOf(unit) || null : null);
8564
8605
  };
8565
8606
  const onLeave = () => setHoveredId(null);
8566
8607
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -14184,8 +14225,9 @@ function useSectionDrag({
14184
14225
  const target = e.target;
14185
14226
  if (!(target instanceof HTMLElement)) return;
14186
14227
  if (target.closest(SECTION_DRAG_EXCLUDED_SELECTOR)) return;
14187
- const sectionEl = target.closest("[data-ohw-section]");
14188
- if (!sectionEl || isChromeSection(sectionEl) || sectionEl.dataset.ohwSection === "footer") return;
14228
+ const inner = target.closest("[data-ohw-section]");
14229
+ if (!inner || isChromeSection(inner) || inner.dataset.ohwSection === "footer") return;
14230
+ const sectionEl = movableUnit(inner);
14189
14231
  if (!topLevelSections().includes(sectionEl)) return;
14190
14232
  startSectionPressDrag(sectionEl, e.clientX, e.clientY, e.pointerId);
14191
14233
  };
@@ -15092,7 +15134,6 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
15092
15134
  if (!mountPoint) return false;
15093
15135
  const container = document.createElement("div");
15094
15136
  container.dataset.ohwSectionContainer = "scheduling";
15095
- container.dataset.ohwSection = sectionId;
15096
15137
  container.dataset.ohwInstance = sectionId;
15097
15138
  if (insertBefore) {
15098
15139
  const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
@@ -18249,10 +18290,10 @@ function OhhwellsBridge() {
18249
18290
  const applyFromCache = () => {
18250
18291
  const content = contentCache.get(subdomain);
18251
18292
  if (!content) return;
18252
- retryMissingSchedulingMounts(getPageSchedulingEntries(content["__ohw_sections"]), false);
18253
- initSectionInstancesFromContent(content, window.location.pathname);
18254
18293
  observer?.disconnect();
18255
18294
  try {
18295
+ retryMissingSchedulingMounts(getPageSchedulingEntries(content["__ohw_sections"]), false);
18296
+ initSectionInstancesFromContent(content, window.location.pathname);
18256
18297
  applyBrandChrome(content);
18257
18298
  if (typeof content[BRAND_KIT_KEY] === "string") {
18258
18299
  applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
@@ -18335,6 +18376,22 @@ function OhhwellsBridge() {
18335
18376
  useEffect13(() => {
18336
18377
  postToParent2({ type: "ow:navigation", path: pathname });
18337
18378
  }, [pathname, postToParent2]);
18379
+ useEffect13(() => {
18380
+ if (!subdomain || isEditMode) return;
18381
+ const content = contentCache.get(subdomain);
18382
+ if (!content) return;
18383
+ unmountAllAiSections();
18384
+ initSectionsFromContent(
18385
+ content,
18386
+ /*removeExisting*/
18387
+ true,
18388
+ pathname
18389
+ );
18390
+ if (typeof content[AI_SECTIONS_KEY] === "string") {
18391
+ setAiSectionOrder(content[SECTION_ORDER_KEY], pathname);
18392
+ applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
18393
+ }
18394
+ }, [pathname, subdomain, isEditMode]);
18338
18395
  useEffect13(() => {
18339
18396
  if (!isEditMode) return;
18340
18397
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
@@ -18343,6 +18400,10 @@ function OhhwellsBridge() {
18343
18400
  deselectRef.current();
18344
18401
  deactivateRef.current();
18345
18402
  }, [pathname, isEditMode]);
18403
+ useEffect13(() => {
18404
+ if (!isEditMode) return;
18405
+ initSectionInstancesFromContent(editContentRef.current, pathname);
18406
+ }, [pathname, isEditMode]);
18346
18407
  useEffect13(() => {
18347
18408
  const contentForNav = () => {
18348
18409
  if (isEditMode) return editContentRef.current;
@@ -21412,7 +21473,7 @@ function OhhwellsBridge() {
21412
21473
  postToParent2({
21413
21474
  type: "ow:ready",
21414
21475
  version: "1",
21415
- bridgeVersion: "0.1.91",
21476
+ bridgeVersion: "0.1.93",
21416
21477
  path: pathname,
21417
21478
  nodes: collectEditableNodes(editContentRef.current),
21418
21479
  sections