Skip to content

Commit 7761086

Browse files
Add options for controlling visibility of custom selection handles
1 parent 07afb48 commit 7761086

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ Options can be provided when Highlight Helper is initialized. They can also be s
101101
- **defaultStyle** – Key of the default highlight style. Default: `fill`.
102102
- **defaultWrapper** – Key of the default highlight wrapper. Default: `none`.
103103
- **highlightIdFunction** – Identifier of a function that provides unique IDs for new highlights. Default: `hhGetNewHighlightId`.
104+
- **showCustomSelectionHandlesForActiveHighlights** – Whether custom selection handles should show for active highlights. Default: `true`.
105+
- **showCustomSelectionHandlesForTextSelection** – Whether custom selection handles should show for text selection. Default: `false`.
106+
- **showCustomSelectionHandlesOnTouch** – Whether custom selection handles should show on touch devices. Default: `false`.
104107

105108

106109
### <a name="custom-events"></a>Custom events

demo.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ <h1 id="title1">Highlight Helper Demo</h1>
147147
<label><input type="radio" name="hh-drawing-mode" value="highlight-api"> Custom Highlight API</label><br>
148148
<label><input type="radio" name="hh-drawing-mode" value="mark-elements"> HTML mark elements</label><br>
149149
</p>
150+
<p>
151+
Show custom selection handles:<br>
152+
<label><input type="checkbox" id="hh-selection-handles-active-highlights" checked> For active highlights</label><br>
153+
<label><input type="checkbox" id="hh-selection-handles-text-selection"> For text selection</label><br>
154+
<label><input type="checkbox" id="hh-selection-handles-touch"> On touch devices</label><br>
155+
</p>
150156
<b>Active highlight:</b>
151157
<div id="snippet-container">
152158
<div id="snippet">N/A</div>
@@ -263,6 +269,12 @@ <h1>Select One</h1>
263269
}
264270
});
265271
}
272+
const selectionHandlesActiveHighlightsCheckbox = document.getElementById('hh-selection-handles-active-highlights');
273+
selectionHandlesActiveHighlightsCheckbox.addEventListener('change', (event) => { highlighter.setOption('showCustomSelectionHandlesForActiveHighlights', event.currentTarget.checked); });
274+
const selectionHandlesTextSelectionCheckbox = document.getElementById('hh-selection-handles-text-selection');
275+
selectionHandlesTextSelectionCheckbox.addEventListener('change', (event) => { highlighter.setOption('showCustomSelectionHandlesForTextSelection', event.currentTarget.checked); });
276+
const selectionHandlesOnTouchCheckbox = document.getElementById('hh-selection-handles-touch');
277+
selectionHandlesOnTouchCheckbox.addEventListener('change', (event) => { highlighter.setOption('showCustomSelectionHandlesOnTouch', event.currentTarget.checked); });
266278

267279
const container = document.querySelector(highlighter.getOptions().containerSelector);
268280
const snippetDiv = document.getElementById('snippet');

highlight-helper.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ function Highlighter(options = hhDefaultOptions) {
7070
width: 0px;
7171
visibility: hidden;
7272
}
73+
[data-hh-pointer-down="true"] .hh-selection-handle {
74+
visibility: hidden !important;
75+
}
7376
.hh-selection-handle-content {
7477
position: absolute;
7578
height: 100%;
@@ -642,13 +645,13 @@ function Highlighter(options = hhDefaultOptions) {
642645
this.annotatableContainer.addEventListener('pointerdown', (event) => respondToPointerDown(event), { signal: controller.signal });
643646
const respondToPointerDown = (event) => {
644647
const isSecondaryClick = (event.button !== 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey);
648+
if (!isSecondaryClick) this.annotatableContainer.dataset.hhPointerDown = 'true';
645649
pointerType = event.pointerType;
646650

647651
// Pointer down on a selection handle
648652
if (event.target?.closest('.hh-selection-handle')) {
649653
if (!isSecondaryClick) {
650654
activeSelectionHandle = event.target.parentElement.closest('.hh-selection-handle');
651-
this.annotatableContainer.dataset.hhDragging = 'true';
652655
const selectionHandleClientRect = activeSelectionHandle.getBoundingClientRect();
653656
const lineHeight = selectionHandleClientRect.bottom - selectionHandleClientRect.top;
654657
activeSelectionHandle.dataset.dragYOffset = Math.max(0, event.clientY - selectionHandleClientRect.bottom + (lineHeight / 6));
@@ -748,10 +751,10 @@ function Highlighter(options = hhDefaultOptions) {
748751
}
749752
tapResult = null;
750753
longPressTimeoutId = clearTimeout(longPressTimeoutId);
754+
this.annotatableContainer.dataset.hhPointerDown = 'false';
751755
if (activeSelectionHandle) {
752756
activeSelectionHandle = null;
753757
updateSelectionUi('bounds');
754-
this.annotatableContainer.dataset.hhDragging = 'false';
755758
this.annotatableContainer.removeEventListener('pointermove', respondToSelectionHandleDrag);
756759
}
757760
}
@@ -898,7 +901,7 @@ function Highlighter(options = hhDefaultOptions) {
898901
const highlightInfo = highlightsById[activeHighlightId] ?? null;
899902
const color = highlightInfo?.color ?? null;
900903
const style = highlightInfo?.style ?? null;
901-
const colorString = options.colors[color] ?? 'AccentColor';
904+
const colorString = options.colors[color] ?? (CSS.supports('color', 'AccentColor') ? 'AccentColor' : 'dodgerblue');
902905

903906
// Draw SVG selection rects (SVG drawing mode only)
904907
svgActiveOverlay.innerHTML = '';
@@ -953,16 +956,22 @@ function Highlighter(options = hhDefaultOptions) {
953956

954957
} else if (changeType === 'bounds') {
955958
// Update selection handle location and visibility
956-
if (selection.type === 'Range' && activeHighlightId && pointerType === 'mouse' && !activeSelectionHandle) {
959+
if (selection.type === 'Range') {
957960
const selectionRangeRects = selectionRange.getClientRects();
958961
const startRect = selectionRangeRects[0];
959962
const endRect = selectionRangeRects[selectionRangeRects.length-1];
960963
const relativeAncestorClientRect = this.relativeAncestorElement.getBoundingClientRect();
961964
const startNodeIsRtl = window.getComputedStyle(selectionRange.startContainer.parentElement).direction === 'rtl';
962965
const endNodeIsRtl = window.getComputedStyle(selectionRange.endContainer.parentElement).direction === 'rtl';
963966

967+
if (
968+
(options.showCustomSelectionHandlesOnTouch || pointerType === 'mouse')
969+
&& ((options.showCustomSelectionHandlesForActiveHighlights && activeHighlightId)
970+
|| (options.showCustomSelectionHandlesForTextSelection && !activeHighlightId))
971+
) {
972+
setCustomSelectionHandleVisibility(true);
973+
}
964974
for (const selectionHandle of selectionHandles) {
965-
selectionHandle.style.visibility = 'visible';
966975
let side;
967976
if (selectionHandle.dataset.position === 'start') {
968977
side = startNodeIsRtl ? 'right' : 'left';
@@ -981,12 +990,17 @@ function Highlighter(options = hhDefaultOptions) {
981990
}
982991
}
983992
} else {
984-
selectionHandles[0].style.visibility = 'hidden';
985-
selectionHandles[1].style.visibility = 'hidden';
993+
setCustomSelectionHandleVisibility(false);
986994
}
987995
}
988996
}
989997

998+
const setCustomSelectionHandleVisibility = (visible = selectionHandles[0].style.visibility === 'hidden') => {
999+
for (const selectionHandle of selectionHandles) {
1000+
selectionHandle.style.visibility = visible ? 'visible' : 'hidden';
1001+
}
1002+
}
1003+
9901004
// Update the selection or highlight range to stay within the annotatable container
9911005
const snapRangeToBoundaries = (range, anchorNode = null) => {
9921006
let startNode = range.startContainer;
@@ -1450,6 +1464,9 @@ let hhDefaultOptions = {
14501464
defaultStyle: 'fill',
14511465
defaultWrapper: 'none',
14521466
highlightIdFunction: hhGetNewHighlightId,
1467+
showCustomSelectionHandlesForActiveHighlights: true,
1468+
showCustomSelectionHandlesForTextSelection: false,
1469+
showCustomSelectionHandlesOnTouch: false,
14531470
}
14541471

14551472
console.info('Highlighter loaded');

0 commit comments

Comments
 (0)