@ohhwells/bridge 0.1.46 → 0.1.47
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 +192 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +192 -39
- package/dist/index.js.map +1 -1
- package/dist/styles.css +12 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6661,6 +6661,8 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6661
6661
|
if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
|
|
6662
6662
|
return;
|
|
6663
6663
|
}
|
|
6664
|
+
const lastCurrentLinkEl = current.length > 0 ? findCounterpartByHrefKey(current[current.length - 1], container) : null;
|
|
6665
|
+
const anchor = lastCurrentLinkEl?.parentElement === container ? lastCurrentLinkEl.nextElementSibling : null;
|
|
6664
6666
|
const seen = /* @__PURE__ */ new Set();
|
|
6665
6667
|
for (const hrefKey of desired) {
|
|
6666
6668
|
if (seen.has(hrefKey)) continue;
|
|
@@ -6675,7 +6677,9 @@ function applyNavOrderToContainer(container, order) {
|
|
|
6675
6677
|
orderedEls.push(el);
|
|
6676
6678
|
}
|
|
6677
6679
|
for (const el of orderedEls) {
|
|
6678
|
-
if (
|
|
6680
|
+
if (anchor) {
|
|
6681
|
+
if (el.nextSibling !== anchor) container.insertBefore(el, anchor);
|
|
6682
|
+
} else if (container.lastElementChild !== el) {
|
|
6679
6683
|
container.appendChild(el);
|
|
6680
6684
|
}
|
|
6681
6685
|
}
|
|
@@ -7017,6 +7021,11 @@ function reconcileFooterOrderFromContent(content) {
|
|
|
7017
7021
|
}
|
|
7018
7022
|
applyFooterOrder(order);
|
|
7019
7023
|
}
|
|
7024
|
+
function isRowLayoutColumn(links) {
|
|
7025
|
+
if (links.length < 2) return false;
|
|
7026
|
+
const firstTop = links[0].getBoundingClientRect().top;
|
|
7027
|
+
return links.every((link) => Math.abs(link.getBoundingClientRect().top - firstTop) < 4);
|
|
7028
|
+
}
|
|
7020
7029
|
function buildLinkDropSlots(column, columnIndex) {
|
|
7021
7030
|
const links = listFooterLinksInColumn(column);
|
|
7022
7031
|
const colRect = column.getBoundingClientRect();
|
|
@@ -7034,6 +7043,32 @@ function buildLinkDropSlots(column, columnIndex) {
|
|
|
7034
7043
|
});
|
|
7035
7044
|
return slots;
|
|
7036
7045
|
}
|
|
7046
|
+
if (isRowLayoutColumn(links)) {
|
|
7047
|
+
for (let i = 0; i <= links.length; i++) {
|
|
7048
|
+
let left;
|
|
7049
|
+
if (i === 0) {
|
|
7050
|
+
left = links[0].getBoundingClientRect().left - barThickness / 2;
|
|
7051
|
+
} else if (i === links.length) {
|
|
7052
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
7053
|
+
left = last.right - barThickness / 2;
|
|
7054
|
+
} else {
|
|
7055
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
7056
|
+
const next = links[i].getBoundingClientRect();
|
|
7057
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7058
|
+
}
|
|
7059
|
+
const heightRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
7060
|
+
slots.push({
|
|
7061
|
+
insertIndex: i,
|
|
7062
|
+
columnIndex,
|
|
7063
|
+
left,
|
|
7064
|
+
top: heightRef.top,
|
|
7065
|
+
width: barThickness,
|
|
7066
|
+
height: Math.max(heightRef.height, colRect.height * 0.8),
|
|
7067
|
+
direction: "vertical"
|
|
7068
|
+
});
|
|
7069
|
+
}
|
|
7070
|
+
return slots;
|
|
7071
|
+
}
|
|
7037
7072
|
for (let i = 0; i <= links.length; i++) {
|
|
7038
7073
|
let top;
|
|
7039
7074
|
if (i === 0) {
|
|
@@ -7117,8 +7152,7 @@ function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
|
7117
7152
|
return true;
|
|
7118
7153
|
});
|
|
7119
7154
|
for (const slot of slots) {
|
|
7120
|
-
const
|
|
7121
|
-
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
7155
|
+
const dist = slot.direction === "vertical" ? Math.abs(clientX - (slot.left + slot.width / 2)) : Math.abs(clientY - (slot.top + slot.height / 2));
|
|
7122
7156
|
if (!best || dist < best.dist) best = { slot, dist };
|
|
7123
7157
|
}
|
|
7124
7158
|
}
|
|
@@ -7162,9 +7196,10 @@ function lockItemDuringDrag() {
|
|
|
7162
7196
|
clearTextSelection();
|
|
7163
7197
|
}
|
|
7164
7198
|
function unlockItemDragInteraction() {
|
|
7199
|
+
const wasDragging = document.documentElement.hasAttribute("data-ohw-item-dragging");
|
|
7165
7200
|
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7166
7201
|
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7167
|
-
clearTextSelection();
|
|
7202
|
+
if (wasDragging) clearTextSelection();
|
|
7168
7203
|
}
|
|
7169
7204
|
var armFooterPressDrag = armItemPressDrag;
|
|
7170
7205
|
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
@@ -7541,7 +7576,6 @@ function useNavItemDrag({
|
|
|
7541
7576
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
7542
7577
|
if (!anchor || !isNavbarHrefKey(hrefKey)) return;
|
|
7543
7578
|
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
|
|
7544
|
-
armItemPressDrag();
|
|
7545
7579
|
navPointerDragRef.current = {
|
|
7546
7580
|
el: anchor,
|
|
7547
7581
|
startX: e.clientX,
|
|
@@ -7568,6 +7602,7 @@ function useNavItemDrag({
|
|
|
7568
7602
|
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
7569
7603
|
e.preventDefault();
|
|
7570
7604
|
pending.started = true;
|
|
7605
|
+
armItemPressDrag();
|
|
7571
7606
|
clearTextSelection();
|
|
7572
7607
|
try {
|
|
7573
7608
|
document.body.setPointerCapture(pending.pointerId);
|
|
@@ -7595,7 +7630,8 @@ function useNavItemDrag({
|
|
|
7595
7630
|
}
|
|
7596
7631
|
} catch {
|
|
7597
7632
|
}
|
|
7598
|
-
if (!pending
|
|
7633
|
+
if (!pending) return;
|
|
7634
|
+
if (!pending.started) {
|
|
7599
7635
|
unlockItemDragInteraction();
|
|
7600
7636
|
return;
|
|
7601
7637
|
}
|
|
@@ -7647,7 +7683,6 @@ function useNavItemDrag({
|
|
|
7647
7683
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7648
7684
|
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7649
7685
|
if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
|
|
7650
|
-
armItemPressDrag();
|
|
7651
7686
|
navPointerDragRef.current = {
|
|
7652
7687
|
el: selected,
|
|
7653
7688
|
startX: clientX,
|
|
@@ -8492,9 +8527,16 @@ function sanitizeHtml(html) {
|
|
|
8492
8527
|
if (!SAFE_TAGS.has(el.tagName)) {
|
|
8493
8528
|
parent.replaceChild(document.createTextNode(el.textContent ?? ""), el);
|
|
8494
8529
|
} else {
|
|
8495
|
-
const
|
|
8530
|
+
const htmlEl = el;
|
|
8531
|
+
const textAlign = htmlEl.style?.textAlign || el.getAttribute("align") || "";
|
|
8532
|
+
const fontWeight = htmlEl.style?.fontWeight || "";
|
|
8533
|
+
const fontStyle = htmlEl.style?.fontStyle || "";
|
|
8534
|
+
const textDecorationLine = htmlEl.style?.textDecorationLine || htmlEl.style?.textDecoration || "";
|
|
8496
8535
|
for (const attr of Array.from(el.attributes)) el.removeAttribute(attr.name);
|
|
8497
|
-
if (textAlign)
|
|
8536
|
+
if (textAlign) htmlEl.style.textAlign = textAlign;
|
|
8537
|
+
if (fontWeight) htmlEl.style.fontWeight = fontWeight;
|
|
8538
|
+
if (fontStyle) htmlEl.style.fontStyle = fontStyle;
|
|
8539
|
+
if (textDecorationLine) htmlEl.style.textDecorationLine = textDecorationLine;
|
|
8498
8540
|
walk(el);
|
|
8499
8541
|
}
|
|
8500
8542
|
}
|
|
@@ -8682,6 +8724,79 @@ function resolveItemInteractionState(rect, parentScroll) {
|
|
|
8682
8724
|
const { transform } = calcToolbarPos(rect, parentScroll, 120);
|
|
8683
8725
|
return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
|
|
8684
8726
|
}
|
|
8727
|
+
function resolveSelectionStartElement(sel) {
|
|
8728
|
+
if (!sel || sel.rangeCount === 0) return null;
|
|
8729
|
+
const range = sel.getRangeAt(0);
|
|
8730
|
+
let startNode = range.startContainer;
|
|
8731
|
+
if (startNode.nodeType === Node.ELEMENT_NODE) {
|
|
8732
|
+
const el = startNode;
|
|
8733
|
+
startNode = el.childNodes[range.startOffset] ?? el.childNodes[range.startOffset - 1] ?? el;
|
|
8734
|
+
}
|
|
8735
|
+
return startNode.nodeType === Node.TEXT_NODE ? startNode.parentElement : startNode;
|
|
8736
|
+
}
|
|
8737
|
+
function detectActiveFormats(startEl, activeRoot) {
|
|
8738
|
+
const formats = /* @__PURE__ */ new Set();
|
|
8739
|
+
const cs = getComputedStyle(startEl);
|
|
8740
|
+
const weight = parseInt(cs.fontWeight, 10);
|
|
8741
|
+
let hasBold = cs.fontWeight === "bold" || !Number.isNaN(weight) && weight >= 600;
|
|
8742
|
+
let hasItalic = cs.fontStyle === "italic" || cs.fontStyle === "oblique";
|
|
8743
|
+
let hasUnderline = false;
|
|
8744
|
+
let hasStrike = false;
|
|
8745
|
+
let hasUl = false;
|
|
8746
|
+
let hasOl = false;
|
|
8747
|
+
for (let el = startEl; el; el = el.parentElement) {
|
|
8748
|
+
if (el.tagName === "B" || el.tagName === "STRONG") hasBold = true;
|
|
8749
|
+
if (el.tagName === "I" || el.tagName === "EM") hasItalic = true;
|
|
8750
|
+
const decoration = getComputedStyle(el).textDecorationLine;
|
|
8751
|
+
if (decoration.includes("underline") || el.tagName === "U" || el.tagName === "INS") hasUnderline = true;
|
|
8752
|
+
if (decoration.includes("line-through") || el.tagName === "S" || el.tagName === "STRIKE" || el.tagName === "DEL") hasStrike = true;
|
|
8753
|
+
if (el.tagName === "UL") hasUl = true;
|
|
8754
|
+
if (el.tagName === "OL") hasOl = true;
|
|
8755
|
+
if (el === activeRoot) break;
|
|
8756
|
+
}
|
|
8757
|
+
if (hasBold) formats.add("bold");
|
|
8758
|
+
if (hasItalic) formats.add("italic");
|
|
8759
|
+
if (hasUnderline) formats.add("underline");
|
|
8760
|
+
if (hasStrike) formats.add("strikeThrough");
|
|
8761
|
+
if (hasUl) formats.add("insertUnorderedList");
|
|
8762
|
+
if (hasOl) formats.add("insertOrderedList");
|
|
8763
|
+
const block = startEl.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? startEl;
|
|
8764
|
+
const align = getComputedStyle(block).textAlign;
|
|
8765
|
+
if (align === "center") formats.add("justifyCenter");
|
|
8766
|
+
else if (align === "right" || align === "end") formats.add("justifyRight");
|
|
8767
|
+
else formats.add("justifyLeft");
|
|
8768
|
+
return formats;
|
|
8769
|
+
}
|
|
8770
|
+
function setsEqual(a, b) {
|
|
8771
|
+
if (a.size !== b.size) return false;
|
|
8772
|
+
for (const item of a) {
|
|
8773
|
+
if (!b.has(item)) return false;
|
|
8774
|
+
}
|
|
8775
|
+
return true;
|
|
8776
|
+
}
|
|
8777
|
+
function textOffsetInRoot(root, node, offset) {
|
|
8778
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
8779
|
+
let total = 0;
|
|
8780
|
+
let current;
|
|
8781
|
+
while (current = walker.nextNode()) {
|
|
8782
|
+
if (current === node) return total + offset;
|
|
8783
|
+
total += (current.textContent ?? "").length;
|
|
8784
|
+
}
|
|
8785
|
+
return total;
|
|
8786
|
+
}
|
|
8787
|
+
function pointAtTextOffset(root, targetOffset) {
|
|
8788
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
|
|
8789
|
+
let total = 0;
|
|
8790
|
+
let current;
|
|
8791
|
+
let last = null;
|
|
8792
|
+
while (current = walker.nextNode()) {
|
|
8793
|
+
const len = (current.textContent ?? "").length;
|
|
8794
|
+
if (total + len >= targetOffset) return { node: current, offset: targetOffset - total };
|
|
8795
|
+
total += len;
|
|
8796
|
+
last = current;
|
|
8797
|
+
}
|
|
8798
|
+
return last ? { node: last, offset: (last.textContent ?? "").length } : null;
|
|
8799
|
+
}
|
|
8685
8800
|
function FloatingToolbar({
|
|
8686
8801
|
rect,
|
|
8687
8802
|
parentScroll,
|
|
@@ -8874,6 +8989,7 @@ function OhhwellsBridge() {
|
|
|
8874
8989
|
const [fetchState, setFetchState] = (0, import_react9.useState)("idle");
|
|
8875
8990
|
const autoSaveTimers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
8876
8991
|
const activeElRef = (0, import_react9.useRef)(null);
|
|
8992
|
+
const pointerHeldRef = (0, import_react9.useRef)(false);
|
|
8877
8993
|
const selectedElRef = (0, import_react9.useRef)(null);
|
|
8878
8994
|
const selectedHrefKeyRef = (0, import_react9.useRef)(null);
|
|
8879
8995
|
const selectedFooterColAttrRef = (0, import_react9.useRef)(null);
|
|
@@ -9560,7 +9676,6 @@ function OhhwellsBridge() {
|
|
|
9560
9676
|
if (e.button !== 0) return;
|
|
9561
9677
|
const selected = selectedElRef.current;
|
|
9562
9678
|
if (!selected) return;
|
|
9563
|
-
armFooterPressDrag();
|
|
9564
9679
|
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
9565
9680
|
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
9566
9681
|
footerPointerDragRef.current = {
|
|
@@ -9672,6 +9787,8 @@ function OhhwellsBridge() {
|
|
|
9672
9787
|
setSiblingHintRect(null);
|
|
9673
9788
|
setSiblingHintRects([]);
|
|
9674
9789
|
setIsItemDragging(false);
|
|
9790
|
+
const preActivationSelection = window.getSelection();
|
|
9791
|
+
const preservedRange = preActivationSelection && preActivationSelection.rangeCount > 0 && !preActivationSelection.isCollapsed && el.contains(preActivationSelection.getRangeAt(0).commonAncestorContainer) ? preActivationSelection.getRangeAt(0).cloneRange() : null;
|
|
9675
9792
|
el.setAttribute("contenteditable", "true");
|
|
9676
9793
|
el.setAttribute("data-ohw-editing", "");
|
|
9677
9794
|
el.removeAttribute("data-ohw-hovered");
|
|
@@ -9679,7 +9796,11 @@ function OhhwellsBridge() {
|
|
|
9679
9796
|
activeElRef.current = el;
|
|
9680
9797
|
originalContentRef.current = el.innerHTML;
|
|
9681
9798
|
el.focus({ preventScroll: true });
|
|
9682
|
-
if (
|
|
9799
|
+
if (preservedRange) {
|
|
9800
|
+
const selection = window.getSelection();
|
|
9801
|
+
selection?.removeAllRanges();
|
|
9802
|
+
selection?.addRange(preservedRange);
|
|
9803
|
+
} else if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
9683
9804
|
const { caretX, caretY } = options;
|
|
9684
9805
|
placeCaretAtPoint(el, caretX, caretY);
|
|
9685
9806
|
requestAnimationFrame(() => {
|
|
@@ -10135,7 +10256,9 @@ function OhhwellsBridge() {
|
|
|
10135
10256
|
if (inActive || inActiveNav) {
|
|
10136
10257
|
e.preventDefault();
|
|
10137
10258
|
e.stopPropagation();
|
|
10138
|
-
|
|
10259
|
+
const selection = window.getSelection();
|
|
10260
|
+
const hasRangeSelection = Boolean(selection && !selection.isCollapsed);
|
|
10261
|
+
if (e.detail < 2 && !hasRangeSelection) {
|
|
10139
10262
|
placeCaretAtPoint(active, e.clientX, e.clientY);
|
|
10140
10263
|
refreshActiveCommandsRef.current();
|
|
10141
10264
|
}
|
|
@@ -11288,30 +11411,30 @@ function OhhwellsBridge() {
|
|
|
11288
11411
|
const h = document.documentElement.scrollHeight;
|
|
11289
11412
|
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
11290
11413
|
};
|
|
11414
|
+
let selectionChangeRaf = null;
|
|
11415
|
+
const runSelectionChange = () => {
|
|
11416
|
+
selectionChangeRaf = null;
|
|
11417
|
+
const activeRoot = activeElRef.current;
|
|
11418
|
+
if (!activeRoot) return;
|
|
11419
|
+
const startEl = resolveSelectionStartElement(window.getSelection());
|
|
11420
|
+
const next = startEl ? detectActiveFormats(startEl, activeRoot) : /* @__PURE__ */ new Set();
|
|
11421
|
+
setActiveCommands((prev) => setsEqual(prev, next) ? prev : next);
|
|
11422
|
+
};
|
|
11291
11423
|
const handleSelectionChange = () => {
|
|
11292
|
-
if (
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
|
|
11299
|
-
}
|
|
11300
|
-
const sel = window.getSelection();
|
|
11301
|
-
const anchor = sel?.anchorNode;
|
|
11302
|
-
if (anchor) {
|
|
11303
|
-
const el = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor;
|
|
11304
|
-
const block = el?.closest("div, p, h1, h2, h3, h4, h5, h6, li, td, th") ?? el;
|
|
11305
|
-
if (block) {
|
|
11306
|
-
const align = getComputedStyle(block).textAlign;
|
|
11307
|
-
if (align === "center") next.add("justifyCenter");
|
|
11308
|
-
else if (align === "right" || align === "end") next.add("justifyRight");
|
|
11309
|
-
else next.add("justifyLeft");
|
|
11310
|
-
}
|
|
11311
|
-
}
|
|
11312
|
-
setActiveCommands(next);
|
|
11424
|
+
if (pointerHeldRef.current) return;
|
|
11425
|
+
if (selectionChangeRaf !== null) return;
|
|
11426
|
+
selectionChangeRaf = requestAnimationFrame(runSelectionChange);
|
|
11427
|
+
};
|
|
11428
|
+
const markPointerHeld = (e) => {
|
|
11429
|
+
if (e.button !== 0) return;
|
|
11430
|
+
pointerHeldRef.current = true;
|
|
11313
11431
|
};
|
|
11314
|
-
|
|
11432
|
+
const markPointerReleased = () => {
|
|
11433
|
+
if (!pointerHeldRef.current) return;
|
|
11434
|
+
pointerHeldRef.current = false;
|
|
11435
|
+
handleSelectionChange();
|
|
11436
|
+
};
|
|
11437
|
+
refreshActiveCommandsRef.current = runSelectionChange;
|
|
11315
11438
|
const handleDocMouseLeave = () => {
|
|
11316
11439
|
hoveredImageRef.current = null;
|
|
11317
11440
|
setMediaHover(null);
|
|
@@ -11551,7 +11674,6 @@ function OhhwellsBridge() {
|
|
|
11551
11674
|
const anchor = getNavigationItemAnchor(target);
|
|
11552
11675
|
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
11553
11676
|
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
11554
|
-
armFooterPressDrag();
|
|
11555
11677
|
footerPointerDragRef.current = {
|
|
11556
11678
|
el: anchor,
|
|
11557
11679
|
kind: "link",
|
|
@@ -11565,7 +11687,6 @@ function OhhwellsBridge() {
|
|
|
11565
11687
|
}
|
|
11566
11688
|
const col = target.closest("[data-ohw-footer-col]");
|
|
11567
11689
|
if (col && !getNavigationItemAnchor(target)) {
|
|
11568
|
-
armFooterPressDrag();
|
|
11569
11690
|
footerPointerDragRef.current = {
|
|
11570
11691
|
el: col,
|
|
11571
11692
|
kind: "column",
|
|
@@ -11594,6 +11715,7 @@ function OhhwellsBridge() {
|
|
|
11594
11715
|
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
11595
11716
|
e.preventDefault();
|
|
11596
11717
|
pending.started = true;
|
|
11718
|
+
armFooterPressDrag();
|
|
11597
11719
|
clearTextSelection();
|
|
11598
11720
|
try {
|
|
11599
11721
|
document.body.setPointerCapture(pending.pointerId);
|
|
@@ -11647,7 +11769,8 @@ function OhhwellsBridge() {
|
|
|
11647
11769
|
}
|
|
11648
11770
|
} catch {
|
|
11649
11771
|
}
|
|
11650
|
-
if (!pending
|
|
11772
|
+
if (!pending) return;
|
|
11773
|
+
if (!pending.started) {
|
|
11651
11774
|
unlockFooterDragInteraction();
|
|
11652
11775
|
return;
|
|
11653
11776
|
}
|
|
@@ -11740,9 +11863,39 @@ function OhhwellsBridge() {
|
|
|
11740
11863
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
11741
11864
|
}, [pathname]);
|
|
11742
11865
|
const handleCommand = (0, import_react9.useCallback)((cmd) => {
|
|
11866
|
+
const el = activeElRef.current;
|
|
11867
|
+
const selBefore = window.getSelection();
|
|
11868
|
+
let savedOffsets = null;
|
|
11869
|
+
if (el && selBefore && selBefore.rangeCount > 0 && !selBefore.isCollapsed) {
|
|
11870
|
+
const r2 = selBefore.getRangeAt(0);
|
|
11871
|
+
if (el.contains(r2.commonAncestorContainer)) {
|
|
11872
|
+
savedOffsets = {
|
|
11873
|
+
start: textOffsetInRoot(el, r2.startContainer, r2.startOffset),
|
|
11874
|
+
end: textOffsetInRoot(el, r2.endContainer, r2.endOffset)
|
|
11875
|
+
};
|
|
11876
|
+
}
|
|
11877
|
+
}
|
|
11878
|
+
document.execCommand("styleWithCSS", false, true);
|
|
11743
11879
|
document.execCommand(cmd, false);
|
|
11744
|
-
|
|
11745
|
-
|
|
11880
|
+
if (el && document.activeElement !== el) {
|
|
11881
|
+
el.focus();
|
|
11882
|
+
}
|
|
11883
|
+
const selAfter = window.getSelection();
|
|
11884
|
+
if (el && savedOffsets && selAfter?.isCollapsed) {
|
|
11885
|
+
const start = pointAtTextOffset(el, savedOffsets.start);
|
|
11886
|
+
const end = pointAtTextOffset(el, savedOffsets.end);
|
|
11887
|
+
if (start && end) {
|
|
11888
|
+
try {
|
|
11889
|
+
const range = document.createRange();
|
|
11890
|
+
range.setStart(start.node, start.offset);
|
|
11891
|
+
range.setEnd(end.node, end.offset);
|
|
11892
|
+
selAfter.removeAllRanges();
|
|
11893
|
+
selAfter.addRange(range);
|
|
11894
|
+
} catch {
|
|
11895
|
+
}
|
|
11896
|
+
}
|
|
11897
|
+
}
|
|
11898
|
+
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
11746
11899
|
refreshActiveCommandsRef.current();
|
|
11747
11900
|
}, []);
|
|
11748
11901
|
const handleStateChange = (0, import_react9.useCallback)((state) => {
|