@ohhwells/bridge 0.1.54-next.151 → 0.1.54-next.153
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 +588 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +588 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -236,13 +236,17 @@ function MediaBox({
|
|
|
236
236
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
237
237
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
238
238
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
239
|
-
const editAttrs = ctx.keyFor && editPath
|
|
239
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
240
|
+
"data-ohw-key": ctx.keyFor(editPath),
|
|
241
|
+
"data-ohw-editable": isIcon ? "icon" : "image"
|
|
242
|
+
} : {};
|
|
240
243
|
if (isIcon) {
|
|
241
244
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
242
245
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
243
246
|
"span",
|
|
244
247
|
{
|
|
245
248
|
"data-ai-icon": refValue,
|
|
249
|
+
...editAttrs,
|
|
246
250
|
style: {
|
|
247
251
|
display: "inline-flex",
|
|
248
252
|
width: 48,
|
|
@@ -9528,6 +9532,358 @@ function deleteNavbarItem(sourceAnchor) {
|
|
|
9528
9532
|
};
|
|
9529
9533
|
}
|
|
9530
9534
|
|
|
9535
|
+
// src/lib/icon-markup.ts
|
|
9536
|
+
var GLYPH_SELECTOR = "svg, img";
|
|
9537
|
+
function referenceBox(slot) {
|
|
9538
|
+
const row = slot.closest("[data-ohw-socials-row]") ?? slot.closest("a")?.parentElement ?? null;
|
|
9539
|
+
const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find((el) => el !== slot) : null;
|
|
9540
|
+
const source = (neighbour ?? slot).querySelector(GLYPH_SELECTOR);
|
|
9541
|
+
const box = source?.getBoundingClientRect() ?? null;
|
|
9542
|
+
return box?.width && box.height ? box : null;
|
|
9543
|
+
}
|
|
9544
|
+
function iconMarkupSizedFor(slot, markup) {
|
|
9545
|
+
const box = referenceBox(slot);
|
|
9546
|
+
if (!box) return markup;
|
|
9547
|
+
const holder = document.createElement("div");
|
|
9548
|
+
holder.innerHTML = markup;
|
|
9549
|
+
const glyph = holder.querySelector(GLYPH_SELECTOR);
|
|
9550
|
+
if (!glyph) return markup;
|
|
9551
|
+
glyph.style.width = `${Math.round(box.width)}px`;
|
|
9552
|
+
glyph.style.height = `${Math.round(box.height)}px`;
|
|
9553
|
+
return holder.innerHTML;
|
|
9554
|
+
}
|
|
9555
|
+
function applyIconMarkup(slot, markup) {
|
|
9556
|
+
if (!markup) return;
|
|
9557
|
+
const coloured = iconMarkupInheritingColour(markup);
|
|
9558
|
+
const sized = iconMarkupSizedFor(slot, coloured);
|
|
9559
|
+
if (slot.innerHTML !== sized) slot.innerHTML = sized;
|
|
9560
|
+
if (sized === coloured) {
|
|
9561
|
+
requestAnimationFrame(() => {
|
|
9562
|
+
if (!slot.isConnected) return;
|
|
9563
|
+
const resized = iconMarkupSizedFor(slot, coloured);
|
|
9564
|
+
if (resized !== coloured && slot.innerHTML !== resized) slot.innerHTML = resized;
|
|
9565
|
+
});
|
|
9566
|
+
}
|
|
9567
|
+
}
|
|
9568
|
+
function detectIconStyle(el) {
|
|
9569
|
+
const row = el.closest("[data-ohw-socials-row]");
|
|
9570
|
+
const glyphs = Array.from((row ?? el).querySelectorAll("svg"));
|
|
9571
|
+
const outlined = glyphs.some((svg) => {
|
|
9572
|
+
return Array.from(svg.querySelectorAll("*")).some((node) => {
|
|
9573
|
+
return node.getAttribute("stroke") !== null && node.getAttribute("stroke") !== "none";
|
|
9574
|
+
});
|
|
9575
|
+
});
|
|
9576
|
+
return outlined ? "outline" : "fill";
|
|
9577
|
+
}
|
|
9578
|
+
function iconMarkupInheritingColour(markup) {
|
|
9579
|
+
const holder = document.createElement("div");
|
|
9580
|
+
holder.innerHTML = markup;
|
|
9581
|
+
holder.querySelectorAll("svg *").forEach((node) => {
|
|
9582
|
+
if (node.getAttribute("fill") && node.getAttribute("fill") !== "none") {
|
|
9583
|
+
node.setAttribute("fill", "currentColor");
|
|
9584
|
+
}
|
|
9585
|
+
if (node.getAttribute("stroke") && node.getAttribute("stroke") !== "none") {
|
|
9586
|
+
node.setAttribute("stroke", "currentColor");
|
|
9587
|
+
}
|
|
9588
|
+
});
|
|
9589
|
+
return holder.innerHTML;
|
|
9590
|
+
}
|
|
9591
|
+
|
|
9592
|
+
// src/lib/socials-items.ts
|
|
9593
|
+
var ICON_SELECTOR = '[data-ohw-editable="icon"]';
|
|
9594
|
+
var SOCIALS_ROW_ATTR = "data-ohw-socials-row";
|
|
9595
|
+
var SOCIALS_ITEM_ATTR = "data-ohw-social-item";
|
|
9596
|
+
function isSocialItem(el) {
|
|
9597
|
+
if (!el) return false;
|
|
9598
|
+
const anchor = el instanceof HTMLAnchorElement ? el : el.closest("a");
|
|
9599
|
+
if (!anchor) return false;
|
|
9600
|
+
return anchor.querySelectorAll(ICON_SELECTOR).length === 1;
|
|
9601
|
+
}
|
|
9602
|
+
function getSocialItem(el) {
|
|
9603
|
+
const anchor = el.closest("a");
|
|
9604
|
+
return isSocialItem(anchor) ? anchor : null;
|
|
9605
|
+
}
|
|
9606
|
+
function findSocialsRow(el) {
|
|
9607
|
+
const item = getSocialItem(el);
|
|
9608
|
+
if (!item) return null;
|
|
9609
|
+
const row = item.parentElement;
|
|
9610
|
+
if (!row) return null;
|
|
9611
|
+
const anchors = Array.from(row.querySelectorAll("a"));
|
|
9612
|
+
if (!anchors.length || !anchors.every((anchor) => isSocialItem(anchor))) return null;
|
|
9613
|
+
return row;
|
|
9614
|
+
}
|
|
9615
|
+
function isSocialsRow(el) {
|
|
9616
|
+
const anchors = Array.from(el.querySelectorAll("a"));
|
|
9617
|
+
return anchors.length > 0 && anchors.every((anchor) => isSocialItem(anchor));
|
|
9618
|
+
}
|
|
9619
|
+
function listSocialItems(row) {
|
|
9620
|
+
return Array.from(row.children).filter((child) => {
|
|
9621
|
+
return child instanceof HTMLElement && isSocialItem(child);
|
|
9622
|
+
});
|
|
9623
|
+
}
|
|
9624
|
+
function listSocialsRows(root = document) {
|
|
9625
|
+
const rows = /* @__PURE__ */ new Set();
|
|
9626
|
+
root.querySelectorAll(ICON_SELECTOR).forEach((icon) => {
|
|
9627
|
+
const row = findSocialsRow(icon);
|
|
9628
|
+
if (row) rows.add(row);
|
|
9629
|
+
});
|
|
9630
|
+
root.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`).forEach((row) => rows.add(row));
|
|
9631
|
+
return Array.from(rows);
|
|
9632
|
+
}
|
|
9633
|
+
var rowTemplates = /* @__PURE__ */ new Map();
|
|
9634
|
+
function markSocialsRows(root = document) {
|
|
9635
|
+
root.querySelectorAll(`[${SOCIALS_ITEM_ATTR}]`).forEach((item) => {
|
|
9636
|
+
item.removeAttribute(SOCIALS_ITEM_ATTR);
|
|
9637
|
+
});
|
|
9638
|
+
listSocialsRows(root).forEach((row) => {
|
|
9639
|
+
row.setAttribute(SOCIALS_ROW_ATTR, "");
|
|
9640
|
+
const items = listSocialItems(row);
|
|
9641
|
+
if (items[0]) rowTemplates.set(rowKeyOf(row), items[0].outerHTML);
|
|
9642
|
+
items.forEach((item, index) => {
|
|
9643
|
+
item.setAttribute(SOCIALS_ITEM_ATTR, String(index));
|
|
9644
|
+
const iconKey = socialIconKey(item);
|
|
9645
|
+
if (iconKey) ensureLabelSlot(item, iconKey);
|
|
9646
|
+
});
|
|
9647
|
+
});
|
|
9648
|
+
}
|
|
9649
|
+
var SOCIALS_LABEL_ATTR = "data-ohw-social-label";
|
|
9650
|
+
function ensureLabelSlot(item, iconKey) {
|
|
9651
|
+
if (item.querySelector(`[${SOCIALS_LABEL_ATTR}]`)) return;
|
|
9652
|
+
const label = document.createElement("span");
|
|
9653
|
+
label.setAttribute("data-ohw-key", `${iconKey}-label`);
|
|
9654
|
+
label.setAttribute("data-ohw-editable", "text");
|
|
9655
|
+
label.setAttribute(SOCIALS_LABEL_ATTR, "");
|
|
9656
|
+
label.style.display = "none";
|
|
9657
|
+
label.textContent = item.getAttribute("aria-label") ?? "";
|
|
9658
|
+
item.appendChild(label);
|
|
9659
|
+
}
|
|
9660
|
+
function socialLabelKey(iconKey) {
|
|
9661
|
+
return `${iconKey}-label`;
|
|
9662
|
+
}
|
|
9663
|
+
function applyStoredValues(item, content) {
|
|
9664
|
+
const hrefKey = socialHrefKey(item);
|
|
9665
|
+
const iconKey = socialIconKey(item);
|
|
9666
|
+
if (hrefKey && content[hrefKey] !== void 0) item.setAttribute("href", content[hrefKey]);
|
|
9667
|
+
if (iconKey) {
|
|
9668
|
+
const glyph = item.querySelector(ICON_SELECTOR);
|
|
9669
|
+
if (glyph && content[iconKey]) applyIconMarkup(glyph, content[iconKey]);
|
|
9670
|
+
const label = item.querySelector(`[${SOCIALS_LABEL_ATTR}]`);
|
|
9671
|
+
label?.setAttribute("data-ohw-key", socialLabelKey(iconKey));
|
|
9672
|
+
const stored = content[socialLabelKey(iconKey)];
|
|
9673
|
+
if (label && stored) label.textContent = stored;
|
|
9674
|
+
}
|
|
9675
|
+
}
|
|
9676
|
+
function socialPlatformKey(iconKey) {
|
|
9677
|
+
return `${iconKey}-platform`;
|
|
9678
|
+
}
|
|
9679
|
+
function socialHrefKey(item) {
|
|
9680
|
+
return item.getAttribute("data-ohw-href-key");
|
|
9681
|
+
}
|
|
9682
|
+
function socialIconKey(item) {
|
|
9683
|
+
return item.querySelector(ICON_SELECTOR)?.dataset.ohwKey ?? null;
|
|
9684
|
+
}
|
|
9685
|
+
var SOCIALS_ORDER_KEY = "__ohw_socials_order";
|
|
9686
|
+
function fromMarkup(markup) {
|
|
9687
|
+
const holder = document.createElement("div");
|
|
9688
|
+
holder.innerHTML = markup;
|
|
9689
|
+
return holder.firstElementChild instanceof HTMLElement ? holder.firstElementChild : null;
|
|
9690
|
+
}
|
|
9691
|
+
var rowKeys = /* @__PURE__ */ new WeakMap();
|
|
9692
|
+
function rowKeyOf(row) {
|
|
9693
|
+
const first = listSocialItems(row)[0];
|
|
9694
|
+
const derived = first ? socialIconKey(first)?.replace(/-\d+$/, "") : null;
|
|
9695
|
+
if (derived) rowKeys.set(row, derived);
|
|
9696
|
+
return derived ?? rowKeys.get(row) ?? "social";
|
|
9697
|
+
}
|
|
9698
|
+
function getSocialsOrderFromDom(root = document) {
|
|
9699
|
+
const order = {};
|
|
9700
|
+
listSocialsRows(root).forEach((row) => {
|
|
9701
|
+
order[rowKeyOf(row)] = listSocialItems(row).map((item) => socialHrefKey(item)).filter((key) => Boolean(key));
|
|
9702
|
+
});
|
|
9703
|
+
return order;
|
|
9704
|
+
}
|
|
9705
|
+
function hasStoredValue(content, hrefKey) {
|
|
9706
|
+
const iconKey = hrefKey.replace(/-href$/, "");
|
|
9707
|
+
return Boolean(content[hrefKey]) || Boolean(content[iconKey]);
|
|
9708
|
+
}
|
|
9709
|
+
function parseSocialsOrder(raw) {
|
|
9710
|
+
if (!raw) return null;
|
|
9711
|
+
try {
|
|
9712
|
+
const parsed = JSON.parse(raw);
|
|
9713
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
9714
|
+
} catch {
|
|
9715
|
+
return null;
|
|
9716
|
+
}
|
|
9717
|
+
}
|
|
9718
|
+
function nextSocialIndex(row, rowKey, content) {
|
|
9719
|
+
const used = listSocialItems(row).map((item) => socialHrefKey(item)).concat(Object.keys(content)).map((key) => key?.match(new RegExp(`^${rowKey}-(\\d+)`))?.[1]).map((digits) => digits === void 0 ? -1 : Number(digits));
|
|
9720
|
+
return Math.max(-1, ...used) + 1;
|
|
9721
|
+
}
|
|
9722
|
+
function insertSocialItem(row, after, content = {}) {
|
|
9723
|
+
const rowKey = rowKeyOf(row);
|
|
9724
|
+
const template = listSocialItems(row)[0];
|
|
9725
|
+
const remembered = rowTemplates.get(rowKey);
|
|
9726
|
+
if (!template && !remembered) return null;
|
|
9727
|
+
const index = nextSocialIndex(row, rowKey, content);
|
|
9728
|
+
const iconKey = `${rowKey}-${index}`;
|
|
9729
|
+
const hrefKey = `${iconKey}-href`;
|
|
9730
|
+
const item = template ? template.cloneNode(true) : fromMarkup(remembered);
|
|
9731
|
+
if (!item) return null;
|
|
9732
|
+
item.setAttribute("data-ohw-href-key", hrefKey);
|
|
9733
|
+
item.setAttribute("href", "");
|
|
9734
|
+
item.removeAttribute("aria-label");
|
|
9735
|
+
item.querySelectorAll("[data-ohw-hovered], [data-ohw-selected]").forEach((el) => {
|
|
9736
|
+
el.removeAttribute("data-ohw-hovered");
|
|
9737
|
+
el.removeAttribute("data-ohw-selected");
|
|
9738
|
+
});
|
|
9739
|
+
const icon = item.querySelector(ICON_SELECTOR);
|
|
9740
|
+
icon?.setAttribute("data-ohw-key", iconKey);
|
|
9741
|
+
item.querySelector(`[${SOCIALS_LABEL_ATTR}]`)?.remove();
|
|
9742
|
+
if (after && after.parentElement === row) after.insertAdjacentElement("afterend", item);
|
|
9743
|
+
else row.appendChild(item);
|
|
9744
|
+
markSocialsRows(row.ownerDocument);
|
|
9745
|
+
return { item, hrefKey, iconKey, order: getSocialsOrderFromDom(row.ownerDocument) };
|
|
9746
|
+
}
|
|
9747
|
+
function duplicateSocialItem(item, content) {
|
|
9748
|
+
const row = findSocialsRow(item);
|
|
9749
|
+
const created = row ? insertSocialItem(row, item, content) : null;
|
|
9750
|
+
if (!created) return null;
|
|
9751
|
+
const sourceHref = socialHrefKey(item);
|
|
9752
|
+
const sourceIcon = socialIconKey(item);
|
|
9753
|
+
const link = created.item;
|
|
9754
|
+
if (sourceHref) link.setAttribute("href", item.getAttribute("href") ?? "");
|
|
9755
|
+
const glyph = item.querySelector(ICON_SELECTOR)?.innerHTML;
|
|
9756
|
+
if (glyph) {
|
|
9757
|
+
const slot = link.querySelector(ICON_SELECTOR);
|
|
9758
|
+
if (slot) slot.innerHTML = glyph;
|
|
9759
|
+
}
|
|
9760
|
+
return {
|
|
9761
|
+
...created,
|
|
9762
|
+
copiedFrom: { href: sourceHref, icon: sourceIcon }
|
|
9763
|
+
};
|
|
9764
|
+
}
|
|
9765
|
+
function removeSocialItem(item, content) {
|
|
9766
|
+
const row = findSocialsRow(item);
|
|
9767
|
+
if (!row) return null;
|
|
9768
|
+
const hrefKey = socialHrefKey(item);
|
|
9769
|
+
const iconKey = socialIconKey(item);
|
|
9770
|
+
const removedKeys = [hrefKey, iconKey].filter((key) => Boolean(key));
|
|
9771
|
+
if (!removedKeys.length) return null;
|
|
9772
|
+
const previousOrder = getSocialsOrderFromDom(row.ownerDocument);
|
|
9773
|
+
const previousContent = Object.fromEntries(
|
|
9774
|
+
removedKeys.filter((key) => key in content).map((key) => [key, content[key]])
|
|
9775
|
+
);
|
|
9776
|
+
const nextSibling = item.nextElementSibling;
|
|
9777
|
+
item.remove();
|
|
9778
|
+
markSocialsRows(row.ownerDocument);
|
|
9779
|
+
return {
|
|
9780
|
+
removedKeys,
|
|
9781
|
+
previousContent,
|
|
9782
|
+
order: getSocialsOrderFromDom(row.ownerDocument),
|
|
9783
|
+
previousOrder,
|
|
9784
|
+
undo: () => {
|
|
9785
|
+
if (nextSibling) nextSibling.before(item);
|
|
9786
|
+
else row.appendChild(item);
|
|
9787
|
+
markSocialsRows(row.ownerDocument);
|
|
9788
|
+
}
|
|
9789
|
+
};
|
|
9790
|
+
}
|
|
9791
|
+
function applySocialsOrder(order, root = document) {
|
|
9792
|
+
listSocialsRows(root).forEach((row) => {
|
|
9793
|
+
const wanted = order[rowKeyOf(row)];
|
|
9794
|
+
if (!wanted) return;
|
|
9795
|
+
const byKey = new Map(listSocialItems(row).map((item) => [socialHrefKey(item), item]));
|
|
9796
|
+
wanted.forEach((key) => {
|
|
9797
|
+
const item = byKey.get(key);
|
|
9798
|
+
if (item) row.appendChild(item);
|
|
9799
|
+
});
|
|
9800
|
+
});
|
|
9801
|
+
markSocialsRows(root);
|
|
9802
|
+
}
|
|
9803
|
+
function reconcileSocialsFromContent(content, root = document) {
|
|
9804
|
+
markSocialsRows(root);
|
|
9805
|
+
const stored = parseSocialsOrder(content[SOCIALS_ORDER_KEY]);
|
|
9806
|
+
if (!stored) return;
|
|
9807
|
+
listSocialsRows(root).forEach((row) => {
|
|
9808
|
+
const wanted = stored[rowKeyOf(row)];
|
|
9809
|
+
if (!wanted) return;
|
|
9810
|
+
if (!wanted.length) return;
|
|
9811
|
+
wanted.forEach((key) => {
|
|
9812
|
+
if (listSocialItems(row).some((item) => socialHrefKey(item) === key)) return;
|
|
9813
|
+
if (!hasStoredValue(content, key)) return;
|
|
9814
|
+
const created = insertSocialItem(row, null, content);
|
|
9815
|
+
if (created) {
|
|
9816
|
+
created.item.setAttribute("data-ohw-href-key", key);
|
|
9817
|
+
created.item.querySelector(ICON_SELECTOR)?.setAttribute("data-ohw-key", key.replace(/-href$/, ""));
|
|
9818
|
+
applyStoredValues(created.item, content);
|
|
9819
|
+
}
|
|
9820
|
+
});
|
|
9821
|
+
const present = listSocialItems(row);
|
|
9822
|
+
const surviving = present.filter((item) => {
|
|
9823
|
+
const key = socialHrefKey(item);
|
|
9824
|
+
return !key || wanted.includes(key);
|
|
9825
|
+
});
|
|
9826
|
+
if (surviving.length) {
|
|
9827
|
+
present.forEach((item) => {
|
|
9828
|
+
if (!surviving.includes(item)) item.remove();
|
|
9829
|
+
});
|
|
9830
|
+
}
|
|
9831
|
+
});
|
|
9832
|
+
applySocialsOrder(stored, root);
|
|
9833
|
+
}
|
|
9834
|
+
var DROP_BAR_THICKNESS = 3;
|
|
9835
|
+
function buildSocialDropSlots(row) {
|
|
9836
|
+
const items = listSocialItems(row);
|
|
9837
|
+
if (!items.length) return [];
|
|
9838
|
+
return items.concat(items[items.length - 1]).map((item, index) => {
|
|
9839
|
+
const rect = item.getBoundingClientRect();
|
|
9840
|
+
const left = (index === items.length ? rect.right : rect.left) - DROP_BAR_THICKNESS / 2;
|
|
9841
|
+
return {
|
|
9842
|
+
insertIndex: index,
|
|
9843
|
+
columnIndex: -1,
|
|
9844
|
+
left,
|
|
9845
|
+
top: rect.top,
|
|
9846
|
+
width: DROP_BAR_THICKNESS,
|
|
9847
|
+
height: rect.height,
|
|
9848
|
+
direction: "vertical"
|
|
9849
|
+
};
|
|
9850
|
+
});
|
|
9851
|
+
}
|
|
9852
|
+
function findSocialByHrefKey(hrefKey, root = document) {
|
|
9853
|
+
const el = root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
9854
|
+
return el ? getSocialItem(el) : null;
|
|
9855
|
+
}
|
|
9856
|
+
function buildSocialDropSlotsForKey(hrefKey, root = document) {
|
|
9857
|
+
const item = findSocialByHrefKey(hrefKey, root);
|
|
9858
|
+
const row = item ? findSocialsRow(item) : null;
|
|
9859
|
+
return row ? buildSocialDropSlots(row) : [];
|
|
9860
|
+
}
|
|
9861
|
+
function hitTestSocialDropSlot(clientX, clientY, draggedHrefKey, root = document) {
|
|
9862
|
+
const distanceTo = (slot) => {
|
|
9863
|
+
const dx = clientX - (slot.left + slot.width / 2);
|
|
9864
|
+
const dy = clientY < slot.top ? slot.top - clientY : Math.max(0, clientY - (slot.top + slot.height));
|
|
9865
|
+
return Math.hypot(dx, dy);
|
|
9866
|
+
};
|
|
9867
|
+
const slots = buildSocialDropSlotsForKey(draggedHrefKey, root);
|
|
9868
|
+
return slots.reduce((best, slot) => {
|
|
9869
|
+
return !best || distanceTo(slot) < distanceTo(best) ? slot : best;
|
|
9870
|
+
}, null);
|
|
9871
|
+
}
|
|
9872
|
+
function planSocialMove(hrefKey, insertIndex, root = document) {
|
|
9873
|
+
const item = findSocialByHrefKey(hrefKey, root);
|
|
9874
|
+
const row = item ? findSocialsRow(item) : null;
|
|
9875
|
+
if (!row) return null;
|
|
9876
|
+
const order = getSocialsOrderFromDom(root);
|
|
9877
|
+
const key = rowKeyOf(row);
|
|
9878
|
+
const current = order[key];
|
|
9879
|
+
if (!current) return null;
|
|
9880
|
+
const from = current.indexOf(hrefKey);
|
|
9881
|
+
if (from < 0) return null;
|
|
9882
|
+
const next = current.filter((_, index) => index !== from);
|
|
9883
|
+
next.splice(insertIndex > from ? insertIndex - 1 : insertIndex, 0, hrefKey);
|
|
9884
|
+
return { ...order, [key]: next };
|
|
9885
|
+
}
|
|
9886
|
+
|
|
9531
9887
|
// src/lib/footer-items.ts
|
|
9532
9888
|
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
9533
9889
|
var MAX_FOOTER_COLUMNS = 18;
|
|
@@ -11903,7 +12259,7 @@ function isNavbarLinksContainer(el) {
|
|
|
11903
12259
|
function isNavigationItem(el) {
|
|
11904
12260
|
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
11905
12261
|
if (!anchor) return false;
|
|
11906
|
-
return Boolean(anchor.querySelector('[data-ohw-editable="text"]'));
|
|
12262
|
+
return Boolean(anchor.querySelector('[data-ohw-editable="text"]')) || Boolean(getSocialItem(anchor));
|
|
11907
12263
|
}
|
|
11908
12264
|
function findFooterItemGroup(item) {
|
|
11909
12265
|
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
@@ -11924,8 +12280,9 @@ function isInferredFooterGroup(el) {
|
|
|
11924
12280
|
const footer = el.closest("footer");
|
|
11925
12281
|
if (!footer || el === footer) return false;
|
|
11926
12282
|
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
12283
|
+
if (isSocialsRow(el)) return false;
|
|
11927
12284
|
const count = Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(
|
|
11928
|
-
isNavigationItem
|
|
12285
|
+
(item) => isNavigationItem(item) && !getSocialItem(item)
|
|
11929
12286
|
).length;
|
|
11930
12287
|
return count >= 2;
|
|
11931
12288
|
}
|
|
@@ -11969,7 +12326,8 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
11969
12326
|
if (key.endsWith("-href")) applyLinkByKey2(key, text);
|
|
11970
12327
|
else {
|
|
11971
12328
|
document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`).forEach((el) => {
|
|
11972
|
-
el.
|
|
12329
|
+
if (el.getAttribute("data-ohw-editable") === "icon") applyIconMarkup(el, text);
|
|
12330
|
+
else el.textContent = text;
|
|
11973
12331
|
});
|
|
11974
12332
|
}
|
|
11975
12333
|
}
|
|
@@ -12031,6 +12389,21 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
12031
12389
|
});
|
|
12032
12390
|
return true;
|
|
12033
12391
|
}
|
|
12392
|
+
const social = getSocialItem(selected);
|
|
12393
|
+
if (social) {
|
|
12394
|
+
const result = removeSocialItem(social, getEditContent());
|
|
12395
|
+
if (!result) return false;
|
|
12396
|
+
finishDelete({
|
|
12397
|
+
toastTitle: "Social deleted",
|
|
12398
|
+
removedKeys: result.removedKeys,
|
|
12399
|
+
previousContent: result.previousContent,
|
|
12400
|
+
orderKey: SOCIALS_ORDER_KEY,
|
|
12401
|
+
orderJson: JSON.stringify(result.order),
|
|
12402
|
+
previousOrderJson: JSON.stringify(result.previousOrder),
|
|
12403
|
+
undoDom: result.undo
|
|
12404
|
+
});
|
|
12405
|
+
return true;
|
|
12406
|
+
}
|
|
12034
12407
|
if (isFooterHrefKey(hrefKey)) {
|
|
12035
12408
|
const result = deleteFooterItem(selected);
|
|
12036
12409
|
if (!result) return false;
|
|
@@ -12567,13 +12940,29 @@ function isNavItemPointerTarget(el) {
|
|
|
12567
12940
|
function getNavigationItemAnchor(el) {
|
|
12568
12941
|
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
12569
12942
|
if (!anchor) return null;
|
|
12570
|
-
if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
|
|
12943
|
+
if (!anchor.querySelector('[data-ohw-editable="text"]') && !getSocialItem(anchor)) return null;
|
|
12571
12944
|
if (!isNavItemPointerTarget(anchor)) return null;
|
|
12572
12945
|
return anchor;
|
|
12573
12946
|
}
|
|
12574
12947
|
function isNavigationItem2(el) {
|
|
12575
12948
|
return getNavigationItemAnchor(el) !== null;
|
|
12576
12949
|
}
|
|
12950
|
+
function requestSocialDialog(anchor, post, content) {
|
|
12951
|
+
const item = getSocialItem(anchor);
|
|
12952
|
+
if (!item) return false;
|
|
12953
|
+
const iconKey = item.querySelector('[data-ohw-editable="icon"]')?.dataset.ohwKey ?? "";
|
|
12954
|
+
post({
|
|
12955
|
+
type: "ow:social-pick",
|
|
12956
|
+
hrefKey: item.getAttribute("data-ohw-href-key") ?? "",
|
|
12957
|
+
iconKey,
|
|
12958
|
+
url: getLinkHref4(item),
|
|
12959
|
+
iconStyle: detectIconStyle(item),
|
|
12960
|
+
// What was chosen last time. Guessing from the address instead reads as "Website" for anything
|
|
12961
|
+
// unrecognised, and for an item with no address at all — so a deliberate choice looked lost.
|
|
12962
|
+
platformId: content[socialPlatformKey(iconKey)] ?? ""
|
|
12963
|
+
});
|
|
12964
|
+
return true;
|
|
12965
|
+
}
|
|
12577
12966
|
function listNavigationItems() {
|
|
12578
12967
|
return Array.from(
|
|
12579
12968
|
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
@@ -12608,7 +12997,7 @@ function getNavigationRoot(el) {
|
|
|
12608
12997
|
return el.closest("nav, footer, aside");
|
|
12609
12998
|
}
|
|
12610
12999
|
function countFooterNavItems(el) {
|
|
12611
|
-
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem2).length;
|
|
13000
|
+
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter((item) => isNavigationItem2(item) && !getSocialItem(item)).length;
|
|
12612
13001
|
}
|
|
12613
13002
|
function findFooterItemGroup2(item) {
|
|
12614
13003
|
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
@@ -12629,10 +13018,11 @@ function isInferredFooterGroup2(el) {
|
|
|
12629
13018
|
const footer = el.closest("footer");
|
|
12630
13019
|
if (!footer || el === footer) return false;
|
|
12631
13020
|
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
13021
|
+
if (isSocialsRow(el)) return false;
|
|
12632
13022
|
return countFooterNavItems(el) >= 2;
|
|
12633
13023
|
}
|
|
12634
13024
|
function isNavigationContainer(el) {
|
|
12635
|
-
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup2(el);
|
|
13025
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el) || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isSocialsRow(el) || isInferredFooterGroup2(el);
|
|
12636
13026
|
}
|
|
12637
13027
|
function isNavbarLinksContainer2(el) {
|
|
12638
13028
|
return el.hasAttribute("data-ohw-nav-container");
|
|
@@ -12715,6 +13105,8 @@ function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
|
12715
13105
|
return null;
|
|
12716
13106
|
}
|
|
12717
13107
|
function getNavigationSelectionParent(el) {
|
|
13108
|
+
const socialsRow = findSocialsRow(el);
|
|
13109
|
+
if (socialsRow) return socialsRow;
|
|
12718
13110
|
if (isNavigationItem2(el)) {
|
|
12719
13111
|
const childrenRoot = el.closest("[data-ohw-nav-children]");
|
|
12720
13112
|
if (childrenRoot) {
|
|
@@ -12740,6 +13132,10 @@ function getNavigationSelectionParent(el) {
|
|
|
12740
13132
|
}
|
|
12741
13133
|
function collectNavigationItemSiblingHintRects(selected) {
|
|
12742
13134
|
if (!isNavigationItem2(selected)) return [];
|
|
13135
|
+
const socialsRow = findSocialsRow(selected);
|
|
13136
|
+
if (socialsRow) {
|
|
13137
|
+
return listSocialItems(socialsRow).filter((item) => item !== selected).map((item) => item.getBoundingClientRect());
|
|
13138
|
+
}
|
|
12743
13139
|
const footerColumn = getFooterColumn(selected);
|
|
12744
13140
|
if (footerColumn) {
|
|
12745
13141
|
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
@@ -13441,6 +13837,8 @@ function OhhwellsBridge() {
|
|
|
13441
13837
|
const toolbarVariantRef = (0, import_react16.useRef)("none");
|
|
13442
13838
|
toolbarVariantRef.current = toolbarVariant;
|
|
13443
13839
|
const [selectedIsCta, setSelectedIsCta] = (0, import_react16.useState)(false);
|
|
13840
|
+
const [selectedIsSocial, setSelectedIsSocial] = (0, import_react16.useState)(false);
|
|
13841
|
+
const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react16.useState)(false);
|
|
13444
13842
|
const [reorderHrefKey, setReorderHrefKey] = (0, import_react16.useState)(null);
|
|
13445
13843
|
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react16.useState)(false);
|
|
13446
13844
|
const [toggleState, setToggleState] = (0, import_react16.useState)(null);
|
|
@@ -13709,6 +14107,8 @@ function OhhwellsBridge() {
|
|
|
13709
14107
|
selectedHrefKeyRef.current = null;
|
|
13710
14108
|
selectedFooterColAttrRef.current = null;
|
|
13711
14109
|
setSelectedIsCta(false);
|
|
14110
|
+
setSelectedIsSocial(false);
|
|
14111
|
+
setSelectedIsSocialsRow(false);
|
|
13712
14112
|
setReorderHrefKey(null);
|
|
13713
14113
|
setReorderDragDisabled(false);
|
|
13714
14114
|
setIsFooterFrameSelection(false);
|
|
@@ -13793,6 +14193,8 @@ function OhhwellsBridge() {
|
|
|
13793
14193
|
selectedFooterColAttrRef.current = null;
|
|
13794
14194
|
markSelected(navAnchor);
|
|
13795
14195
|
setSelectedIsCta(isCtaButton(navAnchor));
|
|
14196
|
+
setSelectedIsSocial(Boolean(getSocialItem(navAnchor)));
|
|
14197
|
+
setSelectedIsSocialsRow(false);
|
|
13796
14198
|
const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
|
|
13797
14199
|
if (isNestedNavChild(navAnchor)) {
|
|
13798
14200
|
setNavGroupForceOpen(navAnchor, true);
|
|
@@ -13916,6 +14318,27 @@ function OhhwellsBridge() {
|
|
|
13916
14318
|
const handleAddChildItem = (0, import_react16.useCallback)(() => {
|
|
13917
14319
|
const selected = selectedElRef.current;
|
|
13918
14320
|
if (!selected) return;
|
|
14321
|
+
const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
|
|
14322
|
+
if (socialsRow) {
|
|
14323
|
+
const after = getSocialItem(selected);
|
|
14324
|
+
const result2 = insertSocialItem(socialsRow, after, editContentRef.current);
|
|
14325
|
+
if (!result2) return;
|
|
14326
|
+
const orderJson = JSON.stringify(result2.order);
|
|
14327
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
14328
|
+
postToParent2({ type: "ow:change", nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }] });
|
|
14329
|
+
postToParentRef.current({
|
|
14330
|
+
type: "ow:social-pick",
|
|
14331
|
+
hrefKey: result2.hrefKey,
|
|
14332
|
+
iconKey: result2.iconKey,
|
|
14333
|
+
url: "",
|
|
14334
|
+
iconStyle: detectIconStyle(result2.item),
|
|
14335
|
+
platformId: "",
|
|
14336
|
+
// Lets the editor undo the insert if the dialog is dismissed: an item that was never given
|
|
14337
|
+
// an address should not survive a Cancel.
|
|
14338
|
+
isNew: true
|
|
14339
|
+
});
|
|
14340
|
+
return;
|
|
14341
|
+
}
|
|
13919
14342
|
if (toolbarVariantRef.current === "select-frame" && isFooterFrameSelection) {
|
|
13920
14343
|
if (!selected.hasAttribute("data-ohw-footer-col") && !selected.closest("[data-ohw-footer-col]")) {
|
|
13921
14344
|
}
|
|
@@ -14028,6 +14451,13 @@ function OhhwellsBridge() {
|
|
|
14028
14451
|
}
|
|
14029
14452
|
session.activeSlot = activeSlot;
|
|
14030
14453
|
setSiblingHintRects([]);
|
|
14454
|
+
if (session.kind === "social") {
|
|
14455
|
+
const slots2 = session.hrefKey ? buildSocialDropSlotsForKey(session.hrefKey) : [];
|
|
14456
|
+
setFooterDropSlots(slots2);
|
|
14457
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
14458
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
14459
|
+
return;
|
|
14460
|
+
}
|
|
14031
14461
|
if (session.kind === "link") {
|
|
14032
14462
|
const columns = listFooterColumns();
|
|
14033
14463
|
const slots2 = [];
|
|
@@ -14064,7 +14494,7 @@ function OhhwellsBridge() {
|
|
|
14064
14494
|
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
14065
14495
|
setToolbarRect(rect);
|
|
14066
14496
|
}
|
|
14067
|
-
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
14497
|
+
const initialSlot = session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
14068
14498
|
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
14069
14499
|
},
|
|
14070
14500
|
[refreshFooterDragVisuals]
|
|
@@ -14080,8 +14510,11 @@ function OhhwellsBridge() {
|
|
|
14080
14510
|
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
14081
14511
|
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
14082
14512
|
let nextOrder = null;
|
|
14083
|
-
|
|
14084
|
-
|
|
14513
|
+
let nextSocialsOrder = null;
|
|
14514
|
+
const slot = session.activeSlot ?? (session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(x, y, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
14515
|
+
if (session.kind === "social" && session.hrefKey && slot) {
|
|
14516
|
+
nextSocialsOrder = planSocialMove(session.hrefKey, slot.insertIndex);
|
|
14517
|
+
} else if (session.kind === "link" && session.hrefKey && slot) {
|
|
14085
14518
|
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
14086
14519
|
} else if (session.kind === "column" && slot) {
|
|
14087
14520
|
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
@@ -14139,6 +14572,27 @@ function OhhwellsBridge() {
|
|
|
14139
14572
|
}
|
|
14140
14573
|
deselectRef.current();
|
|
14141
14574
|
};
|
|
14575
|
+
if (nextSocialsOrder) {
|
|
14576
|
+
const orderJson = JSON.stringify(nextSocialsOrder);
|
|
14577
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
14578
|
+
applySocialsOrder(nextSocialsOrder);
|
|
14579
|
+
postToParentRef.current({
|
|
14580
|
+
type: "ow:change",
|
|
14581
|
+
nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }]
|
|
14582
|
+
});
|
|
14583
|
+
applySelectionAfterDrop();
|
|
14584
|
+
clearFooterDragVisuals();
|
|
14585
|
+
const reapply = nextSocialsOrder;
|
|
14586
|
+
requestAnimationFrame(() => {
|
|
14587
|
+
if (editContentRef.current[SOCIALS_ORDER_KEY] === orderJson) applySocialsOrder(reapply);
|
|
14588
|
+
applySelectionAfterDrop();
|
|
14589
|
+
requestAnimationFrame(() => {
|
|
14590
|
+
if (editContentRef.current[SOCIALS_ORDER_KEY] === orderJson) applySocialsOrder(reapply);
|
|
14591
|
+
resyncSelectedNavigationItem();
|
|
14592
|
+
});
|
|
14593
|
+
});
|
|
14594
|
+
return;
|
|
14595
|
+
}
|
|
14142
14596
|
if (nextOrder) {
|
|
14143
14597
|
const orderJson = JSON.stringify(nextOrder);
|
|
14144
14598
|
editContentRef.current = {
|
|
@@ -14177,7 +14631,22 @@ function OhhwellsBridge() {
|
|
|
14177
14631
|
const startFooterLinkDrag = (0, import_react16.useCallback)(
|
|
14178
14632
|
(anchor, clientX, clientY, wasSelected) => {
|
|
14179
14633
|
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
14180
|
-
if (!hrefKey
|
|
14634
|
+
if (!hrefKey) return false;
|
|
14635
|
+
if (getSocialItem(anchor)) {
|
|
14636
|
+
beginFooterDrag({
|
|
14637
|
+
kind: "social",
|
|
14638
|
+
hrefKey,
|
|
14639
|
+
columnEl: null,
|
|
14640
|
+
sourceColumnIndex: 0,
|
|
14641
|
+
wasSelected,
|
|
14642
|
+
draggedEl: anchor,
|
|
14643
|
+
lastClientX: clientX,
|
|
14644
|
+
lastClientY: clientY,
|
|
14645
|
+
activeSlot: null
|
|
14646
|
+
});
|
|
14647
|
+
return true;
|
|
14648
|
+
}
|
|
14649
|
+
if (!isFooterHrefKey(hrefKey)) return false;
|
|
14181
14650
|
const column = findFooterColumnForLink(anchor);
|
|
14182
14651
|
const columns = listFooterColumns();
|
|
14183
14652
|
beginFooterDrag({
|
|
@@ -14314,6 +14783,8 @@ function OhhwellsBridge() {
|
|
|
14314
14783
|
selectedFooterColAttrRef.current = null;
|
|
14315
14784
|
markSelected(anchor);
|
|
14316
14785
|
setSelectedIsCta(isCtaButton(anchor));
|
|
14786
|
+
setSelectedIsSocial(Boolean(getSocialItem(anchor)));
|
|
14787
|
+
setSelectedIsSocialsRow(false);
|
|
14317
14788
|
clearHrefKeyHover(anchor);
|
|
14318
14789
|
const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
|
|
14319
14790
|
if (isNestedNavChild(anchor)) {
|
|
@@ -14356,6 +14827,8 @@ function OhhwellsBridge() {
|
|
|
14356
14827
|
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
14357
14828
|
markSelected(el);
|
|
14358
14829
|
setSelectedIsCta(false);
|
|
14830
|
+
setSelectedIsSocial(false);
|
|
14831
|
+
setSelectedIsSocialsRow(isSocialsRow(el));
|
|
14359
14832
|
clearHrefKeyHover(el);
|
|
14360
14833
|
setNavGroupForceOpen(null, false);
|
|
14361
14834
|
hoveredNavContainerRef.current = null;
|
|
@@ -14403,6 +14876,9 @@ function OhhwellsBridge() {
|
|
|
14403
14876
|
selectedFooterColAttrRef.current = null;
|
|
14404
14877
|
markSelected(logoEl);
|
|
14405
14878
|
setSelectedIsCta(false);
|
|
14879
|
+
setSelectedIsSocial(false);
|
|
14880
|
+
setSelectedIsSocialsRow(false);
|
|
14881
|
+
setSelectedIsSocialsRow(false);
|
|
14406
14882
|
clearHrefKeyHover(logoEl);
|
|
14407
14883
|
hoveredNavContainerRef.current = null;
|
|
14408
14884
|
setHoveredNavContainerRect(null);
|
|
@@ -14486,11 +14962,15 @@ function OhhwellsBridge() {
|
|
|
14486
14962
|
);
|
|
14487
14963
|
const activate = (0, import_react16.useCallback)((el, options) => {
|
|
14488
14964
|
if (activeElRef.current === el) return;
|
|
14965
|
+
if (isIconEditable(el)) return;
|
|
14966
|
+
if (el.hasAttribute("data-ohw-social-label")) return;
|
|
14489
14967
|
clearSelectedAttr();
|
|
14490
14968
|
selectedElRef.current = null;
|
|
14491
14969
|
selectedHrefKeyRef.current = null;
|
|
14492
14970
|
selectedFooterColAttrRef.current = null;
|
|
14493
14971
|
setSelectedIsCta(false);
|
|
14972
|
+
setSelectedIsSocial(false);
|
|
14973
|
+
setSelectedIsSocialsRow(false);
|
|
14494
14974
|
deactivate();
|
|
14495
14975
|
if (hoveredImageRef.current) {
|
|
14496
14976
|
hoveredImageRef.current = null;
|
|
@@ -14634,7 +15114,7 @@ function OhhwellsBridge() {
|
|
|
14634
15114
|
} else if (el.dataset.ohwEditable === "link") {
|
|
14635
15115
|
applyLinkHref(el, val);
|
|
14636
15116
|
} else if (el.dataset.ohwEditable === "icon") {
|
|
14637
|
-
|
|
15117
|
+
applyIconMarkup(el, val);
|
|
14638
15118
|
} else if (el.innerHTML !== val) {
|
|
14639
15119
|
el.innerHTML = val;
|
|
14640
15120
|
}
|
|
@@ -14645,6 +15125,7 @@ function OhhwellsBridge() {
|
|
|
14645
15125
|
applyLogoSizes(content);
|
|
14646
15126
|
reconcileNavbarItemsFromContent(content);
|
|
14647
15127
|
reconcileFooterOrderFromContent(content);
|
|
15128
|
+
reconcileSocialsFromContent(content);
|
|
14648
15129
|
enforceLinkHrefs();
|
|
14649
15130
|
initSectionsFromContent(content, true);
|
|
14650
15131
|
sectionsLoadedRef.current = true;
|
|
@@ -14712,6 +15193,7 @@ function OhhwellsBridge() {
|
|
|
14712
15193
|
applyLogoFromContent(content);
|
|
14713
15194
|
reconcileNavbarItemsFromContent(content);
|
|
14714
15195
|
reconcileFooterOrderFromContent(content);
|
|
15196
|
+
reconcileSocialsFromContent(content);
|
|
14715
15197
|
} finally {
|
|
14716
15198
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
14717
15199
|
}
|
|
@@ -14789,6 +15271,7 @@ function OhhwellsBridge() {
|
|
|
14789
15271
|
const content = contentForNav();
|
|
14790
15272
|
reconcileNavbarItemsFromContent(content);
|
|
14791
15273
|
reconcileFooterOrderFromContent(content);
|
|
15274
|
+
reconcileSocialsFromContent(content);
|
|
14792
15275
|
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
14793
15276
|
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
14794
15277
|
disableNativeHrefDrag(el);
|
|
@@ -15086,7 +15569,7 @@ function OhhwellsBridge() {
|
|
|
15086
15569
|
});
|
|
15087
15570
|
return;
|
|
15088
15571
|
}
|
|
15089
|
-
if (isIconEditable(editable)) {
|
|
15572
|
+
if (isIconEditable(editable) && !getSocialItem(editable)) {
|
|
15090
15573
|
e.preventDefault();
|
|
15091
15574
|
e.stopPropagation();
|
|
15092
15575
|
aiSectionApiRef.current?.selectFromElement(editable);
|
|
@@ -15111,6 +15594,7 @@ function OhhwellsBridge() {
|
|
|
15111
15594
|
e.stopPropagation();
|
|
15112
15595
|
if (selectedElRef.current === navAnchor) {
|
|
15113
15596
|
if (e.detail >= 2) return;
|
|
15597
|
+
if (requestSocialDialog(navAnchor, postToParentRef.current, editContentRef.current)) return;
|
|
15114
15598
|
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
15115
15599
|
return;
|
|
15116
15600
|
}
|
|
@@ -15127,6 +15611,7 @@ function OhhwellsBridge() {
|
|
|
15127
15611
|
e.preventDefault();
|
|
15128
15612
|
e.stopPropagation();
|
|
15129
15613
|
if (selectedElRef.current === hrefAnchor) {
|
|
15614
|
+
if (requestSocialDialog(hrefAnchor, postToParentRef.current, editContentRef.current)) return;
|
|
15130
15615
|
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
15131
15616
|
if (textEditable) {
|
|
15132
15617
|
activateRef.current(textEditable, {
|
|
@@ -15165,6 +15650,13 @@ function OhhwellsBridge() {
|
|
|
15165
15650
|
selectFrameRef.current(navContainerToSelect);
|
|
15166
15651
|
return;
|
|
15167
15652
|
}
|
|
15653
|
+
const socialsRowToSelect = isSocialsRow(target) ? target : null;
|
|
15654
|
+
if (socialsRowToSelect && !getSocialItem(target)) {
|
|
15655
|
+
e.preventDefault();
|
|
15656
|
+
e.stopPropagation();
|
|
15657
|
+
selectFrameRef.current(socialsRowToSelect);
|
|
15658
|
+
return;
|
|
15659
|
+
}
|
|
15168
15660
|
const footerColumnToSelect = resolveFooterColumnSelectionTarget(target, e.clientX, e.clientY);
|
|
15169
15661
|
if (footerColumnToSelect) {
|
|
15170
15662
|
e.preventDefault();
|
|
@@ -15217,6 +15709,7 @@ function OhhwellsBridge() {
|
|
|
15217
15709
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15218
15710
|
return;
|
|
15219
15711
|
}
|
|
15712
|
+
if (getSocialItem(target)) return;
|
|
15220
15713
|
const navLabel = getNavigationLabelEditable(target);
|
|
15221
15714
|
const editable = navLabel?.editable ?? target.closest('[data-ohw-editable="text"], [data-ohw-editable="plain"]');
|
|
15222
15715
|
if (!editable || isMediaEditable(editable) || editable.dataset.ohwEditable === "link") return;
|
|
@@ -15990,7 +16483,7 @@ function OhhwellsBridge() {
|
|
|
15990
16483
|
if (footerSession) {
|
|
15991
16484
|
e.preventDefault();
|
|
15992
16485
|
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
15993
|
-
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
16486
|
+
const slot = footerSession.kind === "social" && footerSession.hrefKey ? hitTestSocialDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
15994
16487
|
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
15995
16488
|
return;
|
|
15996
16489
|
}
|
|
@@ -16042,6 +16535,47 @@ function OhhwellsBridge() {
|
|
|
16042
16535
|
resumeAnimTracks();
|
|
16043
16536
|
clearImageHover();
|
|
16044
16537
|
};
|
|
16538
|
+
const handleSocialCancel = (e) => {
|
|
16539
|
+
if (e.data?.type !== "ow:social-cancel") return;
|
|
16540
|
+
const { hrefKey } = e.data;
|
|
16541
|
+
const item = hrefKey ? findSocialByHrefKey(hrefKey) : null;
|
|
16542
|
+
if (!item) return;
|
|
16543
|
+
const removed = removeSocialItem(item, editContentRef.current);
|
|
16544
|
+
if (!removed) return;
|
|
16545
|
+
const orderJson = JSON.stringify(removed.order);
|
|
16546
|
+
editContentRef.current = { ...editContentRef.current, [SOCIALS_ORDER_KEY]: orderJson };
|
|
16547
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: SOCIALS_ORDER_KEY, text: orderJson }] });
|
|
16548
|
+
deselectRef.current();
|
|
16549
|
+
};
|
|
16550
|
+
const handleSocialUpdate = (e) => {
|
|
16551
|
+
if (e.data?.type !== "ow:social-update") return;
|
|
16552
|
+
const { hrefKey, iconKey, url, iconMarkup, platformId, label } = e.data;
|
|
16553
|
+
const nodes = [];
|
|
16554
|
+
if (hrefKey) {
|
|
16555
|
+
document.querySelectorAll(`[data-ohw-href-key="${hrefKey}"]`).forEach((el) => applyLinkHref(el, url));
|
|
16556
|
+
nodes.push({ key: hrefKey, text: url });
|
|
16557
|
+
}
|
|
16558
|
+
if (iconKey && typeof iconMarkup === "string" && iconMarkup) {
|
|
16559
|
+
document.querySelectorAll(`[data-ohw-key="${iconKey}"][data-ohw-editable="icon"]`).forEach((el) => {
|
|
16560
|
+
applyIconMarkup(el, iconMarkup);
|
|
16561
|
+
});
|
|
16562
|
+
nodes.push({ key: iconKey, text: iconMarkup });
|
|
16563
|
+
}
|
|
16564
|
+
if (iconKey && platformId) nodes.push({ key: socialPlatformKey(iconKey), text: platformId });
|
|
16565
|
+
if (iconKey && label) {
|
|
16566
|
+
const labelKey = socialLabelKey(iconKey);
|
|
16567
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
16568
|
+
el.textContent = label;
|
|
16569
|
+
});
|
|
16570
|
+
nodes.push({ key: labelKey, text: label });
|
|
16571
|
+
}
|
|
16572
|
+
if (!nodes.length) return;
|
|
16573
|
+
editContentRef.current = {
|
|
16574
|
+
...editContentRef.current,
|
|
16575
|
+
...Object.fromEntries(nodes.map((node) => [node.key, node.text]))
|
|
16576
|
+
};
|
|
16577
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
16578
|
+
};
|
|
16045
16579
|
const handleIconMarkup = (e) => {
|
|
16046
16580
|
if (e.data?.type !== "ow:icon-markup") return;
|
|
16047
16581
|
const { key, markup } = e.data;
|
|
@@ -16051,7 +16585,7 @@ function OhhwellsBridge() {
|
|
|
16051
16585
|
);
|
|
16052
16586
|
if (!targets.length) return;
|
|
16053
16587
|
targets.forEach((el) => {
|
|
16054
|
-
el
|
|
16588
|
+
applyIconMarkup(el, markup);
|
|
16055
16589
|
});
|
|
16056
16590
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: markup }] });
|
|
16057
16591
|
};
|
|
@@ -16563,7 +17097,7 @@ function OhhwellsBridge() {
|
|
|
16563
17097
|
}
|
|
16564
17098
|
if (footerDragRef.current) {
|
|
16565
17099
|
const session = footerDragRef.current;
|
|
16566
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
17100
|
+
const slot = session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
16567
17101
|
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
16568
17102
|
}
|
|
16569
17103
|
if (navDragRef.current) {
|
|
@@ -16910,6 +17444,8 @@ function OhhwellsBridge() {
|
|
|
16910
17444
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
16911
17445
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
16912
17446
|
window.addEventListener("message", handleCollectSection);
|
|
17447
|
+
window.addEventListener("message", handleSocialCancel);
|
|
17448
|
+
window.addEventListener("message", handleSocialUpdate);
|
|
16913
17449
|
window.addEventListener("message", handleIconMarkup);
|
|
16914
17450
|
window.addEventListener("message", handleImageUrl);
|
|
16915
17451
|
window.addEventListener("message", handleImageUploading);
|
|
@@ -16970,6 +17506,8 @@ function OhhwellsBridge() {
|
|
|
16970
17506
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
16971
17507
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
16972
17508
|
window.removeEventListener("message", handleCollectSection);
|
|
17509
|
+
window.removeEventListener("message", handleSocialCancel);
|
|
17510
|
+
window.removeEventListener("message", handleSocialUpdate);
|
|
16973
17511
|
window.removeEventListener("message", handleIconMarkup);
|
|
16974
17512
|
window.removeEventListener("message", handleImageUrl);
|
|
16975
17513
|
window.removeEventListener("message", handleImageUploading);
|
|
@@ -17049,7 +17587,7 @@ function OhhwellsBridge() {
|
|
|
17049
17587
|
clearTextSelection();
|
|
17050
17588
|
const session = footerDragRef.current;
|
|
17051
17589
|
if (!session) return;
|
|
17052
|
-
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
17590
|
+
const slot = session.kind === "social" && session.hrefKey ? hitTestSocialDropSlot(e.clientX, e.clientY, session.hrefKey) : session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
17053
17591
|
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
17054
17592
|
return;
|
|
17055
17593
|
}
|
|
@@ -17290,6 +17828,10 @@ function OhhwellsBridge() {
|
|
|
17290
17828
|
if (!anchor) return;
|
|
17291
17829
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
17292
17830
|
if (!key) return;
|
|
17831
|
+
if (requestSocialDialog(anchor, postToParentRef.current, editContentRef.current)) {
|
|
17832
|
+
deselect();
|
|
17833
|
+
return;
|
|
17834
|
+
}
|
|
17293
17835
|
bumpLinkPopoverGrace();
|
|
17294
17836
|
setLinkPopover({
|
|
17295
17837
|
key,
|
|
@@ -17330,6 +17872,30 @@ function OhhwellsBridge() {
|
|
|
17330
17872
|
if (!selected || !isNavigationItem2(selected)) return;
|
|
17331
17873
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
17332
17874
|
if (!hrefKey) return;
|
|
17875
|
+
const social = getSocialItem(selected);
|
|
17876
|
+
if (social) {
|
|
17877
|
+
const result = duplicateSocialItem(social, editContentRef.current);
|
|
17878
|
+
if (!result) return;
|
|
17879
|
+
const orderJson = JSON.stringify(result.order);
|
|
17880
|
+
const carried = [
|
|
17881
|
+
{ from: result.copiedFrom?.href, to: result.hrefKey },
|
|
17882
|
+
{ from: result.copiedFrom?.icon, to: result.iconKey },
|
|
17883
|
+
{ from: result.copiedFrom?.icon ? socialPlatformKey(result.copiedFrom.icon) : null, to: socialPlatformKey(result.iconKey) }
|
|
17884
|
+
];
|
|
17885
|
+
const nodes = [{ key: SOCIALS_ORDER_KEY, text: orderJson }];
|
|
17886
|
+
for (const { from, to } of carried) {
|
|
17887
|
+
const value = from ? editContentRef.current[from] : void 0;
|
|
17888
|
+
if (value) nodes.push({ key: to, text: value });
|
|
17889
|
+
}
|
|
17890
|
+
editContentRef.current = {
|
|
17891
|
+
...editContentRef.current,
|
|
17892
|
+
...Object.fromEntries(nodes.map((node) => [node.key, node.text]))
|
|
17893
|
+
};
|
|
17894
|
+
postToParent2({ type: "ow:change", nodes });
|
|
17895
|
+
enforceLinkHrefs();
|
|
17896
|
+
requestAnimationFrame(() => selectRef.current(result.item));
|
|
17897
|
+
return;
|
|
17898
|
+
}
|
|
17333
17899
|
if (isNavbarHrefKey(hrefKey)) {
|
|
17334
17900
|
const result = duplicateNavbarItem(selected);
|
|
17335
17901
|
if (!result) return;
|
|
@@ -17648,7 +18214,7 @@ function OhhwellsBridge() {
|
|
|
17648
18214
|
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
17649
18215
|
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
17650
18216
|
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
17651
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && isFooterFrameSelection && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
18217
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
17652
18218
|
ItemActionToolbar,
|
|
17653
18219
|
{
|
|
17654
18220
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -17659,12 +18225,12 @@ function OhhwellsBridge() {
|
|
|
17659
18225
|
addItemDisabled: false,
|
|
17660
18226
|
editLinkDisabled: false,
|
|
17661
18227
|
moreDisabled: false,
|
|
17662
|
-
duplicateDisabled: isFooterFrameSelection,
|
|
17663
|
-
showEditLink: !isFooterFrameSelection && navDropdownPreviewOpen === null,
|
|
17664
|
-
showAddItem: isFooterFrameSelection || !selectedIsCta && Boolean(
|
|
18228
|
+
duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow,
|
|
18229
|
+
showEditLink: !isFooterFrameSelection && !selectedIsSocialsRow && navDropdownPreviewOpen === null,
|
|
18230
|
+
showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
|
|
17665
18231
|
selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
|
|
17666
18232
|
),
|
|
17667
|
-
showMore: !selectedIsCta || isFooterFrameSelection,
|
|
18233
|
+
showMore: (!selectedIsCta || isFooterFrameSelection) && !selectedIsSocialsRow,
|
|
17668
18234
|
dropdownOpen: navDropdownPreviewOpen,
|
|
17669
18235
|
onDropdownOpenChange: handleNavDropdownOpenChange,
|
|
17670
18236
|
headingVisible: footerHeadingVisible,
|