@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.
@@ -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
- const pos = linePositions[b];
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
- if (prevParagraphBottom > lines[0].bottom) prevParagraphBottom = Number.NEGATIVE_INFINITY;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samuelbradshaw/highlight-helper-js",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "JavaScript tool that enables highlighting or underlining text in an HTML page.",
5
5
  "type": "module",
6
6
  "main": "highlight-helper.mjs",