@samuelbradshaw/highlight-helper-js 1.0.1 → 1.0.3
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/highlight-helper.js +24 -5
- package/package.json +1 -1
package/highlight-helper.js
CHANGED
|
@@ -272,6 +272,9 @@
|
|
|
272
272
|
this._dragAnchorOffset = this._activeHandle.dataset.hhPosition === 'start' ? selectionRange.endOffset : selectionRange.startOffset;
|
|
273
273
|
this._container.addEventListener('pointermove', respondToHandleDrag, { signal: this._controller.signal });
|
|
274
274
|
this._updateSelectionState();
|
|
275
|
+
|
|
276
|
+
// Check for tap targets so hh:tap can fire if the area around a handle is tapped without dragging (tap result will reset to null if the user starts dragging)
|
|
277
|
+
this._tapResult = this._checkForTapTargets(event);
|
|
275
278
|
}
|
|
276
279
|
// Prevent default drag interaction (which would show a thumbnail and drag selected text)
|
|
277
280
|
return event.preventDefault();
|
|
@@ -426,10 +429,12 @@
|
|
|
426
429
|
let previousDrawingMode = null;
|
|
427
430
|
globalThis.addEventListener('beforeprint', () => {
|
|
428
431
|
previousDrawingMode = this._options.drawingMode;
|
|
432
|
+
if (previousDrawingMode === 'mark-elements') return;
|
|
429
433
|
this.setOptions({ drawingMode: 'mark-elements' });
|
|
430
434
|
this.drawHighlights();
|
|
431
435
|
}, { signal: this._controller.signal });
|
|
432
436
|
globalThis.addEventListener('afterprint', () => {
|
|
437
|
+
if (previousDrawingMode === 'mark-elements') return;
|
|
433
438
|
this.setOptions({ drawingMode: previousDrawingMode });
|
|
434
439
|
this.drawHighlights();
|
|
435
440
|
}, { signal: this._controller.signal });
|
|
@@ -1713,6 +1718,22 @@
|
|
|
1713
1718
|
const paragraphFontSize = Number.parseFloat(paragraphStyle.fontSize);
|
|
1714
1719
|
const snapTolerance = Math.max(paragraphFontSize / 2, 4);
|
|
1715
1720
|
|
|
1721
|
+
const pseudoElemRects = _gatherPseudoElemRects(paragraph);
|
|
1722
|
+
|
|
1723
|
+
// Horizontal distance between a rect and a line's span so far, ignoring space taken up by pseudoelements (such as footnote markers) that contribute no text nodes. Zero or negative means the rect overlaps the span.
|
|
1724
|
+
const distanceToLine = (pos, rect) => {
|
|
1725
|
+
const gapLeft = Math.min(pos.maxRight, rect.right);
|
|
1726
|
+
const gapRight = Math.max(pos.minLeft, rect.left);
|
|
1727
|
+
let distance = gapRight - gapLeft;
|
|
1728
|
+
if (distance <= snapTolerance) return distance;
|
|
1729
|
+
for (const pseudoRect of pseudoElemRects) {
|
|
1730
|
+
if (pseudoRect.top >= rect.bottom || pseudoRect.bottom <= rect.top) continue;
|
|
1731
|
+
const overlap = Math.min(pseudoRect.right, gapRight) - Math.max(pseudoRect.left, gapLeft);
|
|
1732
|
+
if (overlap > 0) distance -= overlap;
|
|
1733
|
+
}
|
|
1734
|
+
return distance;
|
|
1735
|
+
};
|
|
1736
|
+
|
|
1716
1737
|
const linePositions = {};
|
|
1717
1738
|
const lineBottomKeys = [];
|
|
1718
1739
|
const textNodeRange = document.createRange();
|
|
@@ -1728,8 +1749,7 @@
|
|
|
1728
1749
|
for (const rect of textNodeRange.getClientRects()) {
|
|
1729
1750
|
const lineBottom = lineBottomKeys.find(b => {
|
|
1730
1751
|
if (Math.abs(b - rect.bottom) >= snapTolerance) return false;
|
|
1731
|
-
|
|
1732
|
-
return rect.left <= pos.maxRight + snapTolerance && rect.right >= pos.minLeft - snapTolerance;
|
|
1752
|
+
return distanceToLine(linePositions[b], rect) <= snapTolerance;
|
|
1733
1753
|
}) ?? rect.bottom;
|
|
1734
1754
|
if (!linePositions[lineBottom]) lineBottomKeys.push(lineBottom);
|
|
1735
1755
|
const pos = linePositions[lineBottom] ??= { minLeft: rect.left, maxRight: rect.right, maxFontSize: fontSize, maxLineHeight: lineHeight };
|
|
@@ -1741,7 +1761,6 @@
|
|
|
1741
1761
|
}
|
|
1742
1762
|
|
|
1743
1763
|
// Expand line rects to include pseudoelements, and snap to the paragraph's leading edge
|
|
1744
|
-
const pseudoElemRects = _gatherPseudoElemRects(paragraph);
|
|
1745
1764
|
lineBottomKeys.sort((a, b) => a - b);
|
|
1746
1765
|
const lines = lineBottomKeys.map((lineBottom) => {
|
|
1747
1766
|
const pos = linePositions[lineBottom];
|
|
@@ -1781,9 +1800,9 @@
|
|
|
1781
1800
|
paragraphLineRectsCache.set(paragraph.id, paragraphLineRects);
|
|
1782
1801
|
}
|
|
1783
1802
|
const { lines, snapTolerance, pseudoElemRects } = paragraphLineRects;
|
|
1784
|
-
// If the previous paragraph is below the current paragraph (such as in multi-column layouts), reset prevParagraphBottom
|
|
1785
1803
|
if (lines.length === 0) continue;
|
|
1786
|
-
|
|
1804
|
+
// The previous paragraph's bottom is only a valid boundary if it sits above this paragraph's first line — reset it if the paragraphs are side by side, or in a later column
|
|
1805
|
+
if (prevParagraphBottom > lines[0].top + snapTolerance) prevParagraphBottom = Number.NEGATIVE_INFINITY;
|
|
1787
1806
|
const lineStates = lines.map((lineRect, i) => ({
|
|
1788
1807
|
topY: i === 0 ? prevParagraphBottom : lines[i - 1].bottom,
|
|
1789
1808
|
left: Infinity, right: -Infinity,
|
package/package.json
CHANGED