@vdegenne/highlight-manager 0.1.7 → 0.1.9

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/lib/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { IsInViewportPartCheck } from './utils.js';
1
2
  interface Info {
2
3
  elements: HTMLElement[];
3
4
  highlightIndexStart: number;
@@ -9,7 +10,20 @@ interface Info {
9
10
  highlightElement: HTMLElement | undefined;
10
11
  highlightContent: string | undefined;
11
12
  }
12
- type ScrollWhenOffscreenOption = 'never' | 'bounding-rect' | 'top';
13
+ interface ScrollStrategy {
14
+ /**
15
+ * @default 'center'
16
+ */
17
+ whenWhatPartIsHidden: IsInViewportPartCheck;
18
+ /**
19
+ * @default 'smooth'
20
+ */
21
+ behavior: ScrollBehavior;
22
+ /**
23
+ * @default 'start'
24
+ */
25
+ logicalPosition: ScrollLogicalPosition;
26
+ }
13
27
  interface Options {
14
28
  css: string;
15
29
  highlightTextColor: string;
@@ -33,9 +47,9 @@ interface Options {
33
47
  */
34
48
  applyStyleSheetTo: Document | HTMLElement | ShadowRoot;
35
49
  /**
36
- * @default 'none'
50
+ * @default undefined
37
51
  */
38
- scrollWhenOffscreen: ScrollWhenOffscreenOption;
52
+ scrollStrategy: Partial<ScrollStrategy> | undefined;
39
53
  /**
40
54
  * If true, will select the next visible candidate if the highlight is offscreen.
41
55
  *
@@ -45,7 +59,7 @@ interface Options {
45
59
  }
46
60
  export declare function setGlobalBeforeHighlight(fct: () => void): void;
47
61
  interface HighlightOptions {
48
- scrollWhenOffscreen: ScrollWhenOffscreenOption;
62
+ scrollStrategy: Partial<ScrollStrategy> | undefined;
49
63
  }
50
64
  export declare class HighLightManager {
51
65
  #private;
@@ -64,7 +78,7 @@ export declare class HighLightManager {
64
78
  /**
65
79
  * @returns {boolean} true if the highlight succeeded, false otherwise.
66
80
  */
67
- highlight(start: number, end?: number, unhighlightAll?: boolean, cache?: boolean, options?: HighlightOptions): boolean;
81
+ highlight(start: number, end?: number, unhighlightAll?: boolean, cache?: boolean, options?: Partial<HighlightOptions>): boolean;
68
82
  previous(step?: number, cache?: boolean): void;
69
83
  next(step?: number, cache?: boolean): void;
70
84
  extendLeftHighlight(step?: number, cache?: boolean): void;
package/lib/index.js CHANGED
@@ -1,5 +1,10 @@
1
1
  import { querySelectorAll } from 'html-vision';
2
2
  import { isInViewport, sleep } from './utils.js';
3
+ const scrollStrategyDefaults = {
4
+ whenWhatPartIsHidden: 'center',
5
+ behavior: 'smooth',
6
+ logicalPosition: 'start',
7
+ };
3
8
  const defaults = {
4
9
  atomicSelection(_element) {
5
10
  return true;
@@ -14,7 +19,7 @@ const defaults = {
14
19
  beforeHighlight: undefined,
15
20
  onSelectionChange: undefined,
16
21
  applyStyleSheetTo: document,
17
- scrollWhenOffscreen: 'never',
22
+ scrollStrategy: undefined,
18
23
  fastTravel: false,
19
24
  };
20
25
  // Local array of all declared highlighters for id control.
@@ -75,9 +80,7 @@ export class HighLightManager {
75
80
  const els = querySelectorAll(this.selector);
76
81
  const el = els[index];
77
82
  if (el) {
78
- this.highlight(index, index, true, false, {
79
- scrollWhenOffscreen: 'never',
80
- });
83
+ this.highlight(index, index, true, false);
81
84
  wr.resolve(el);
82
85
  this.#highlightWhenAvailablePromiseWR = undefined;
83
86
  return;
@@ -152,7 +155,7 @@ export class HighLightManager {
152
155
  /**
153
156
  * @returns {boolean} true if the highlight succeeded, false otherwise.
154
157
  */
155
- highlight(start, end, unhighlightAll = true, cache = false, options) {
158
+ highlight(start, end, unhighlightAll = true, cache = false, options = {}) {
156
159
  if (end === undefined) {
157
160
  end = start;
158
161
  }
@@ -169,7 +172,13 @@ export class HighLightManager {
169
172
  }
170
173
  // console.log(highlightIndexStart, highlightIndexEnd, start, end)
171
174
  const _options = {
172
- scrollWhenOffscreen: options?.scrollWhenOffscreen ?? this.#options.scrollWhenOffscreen,
175
+ scrollStrategy: options?.scrollStrategy || this.#options.scrollStrategy
176
+ ? {
177
+ ...scrollStrategyDefaults,
178
+ ...this.#options.scrollStrategy,
179
+ ...options?.scrollStrategy,
180
+ }
181
+ : undefined,
173
182
  };
174
183
  globalBeforeHighlight?.();
175
184
  this.#options.beforeHighlight?.();
@@ -181,12 +190,12 @@ export class HighLightManager {
181
190
  if (elementsToHighlight.length === 0) {
182
191
  return false;
183
192
  }
184
- if (_options.scrollWhenOffscreen !== 'never' &&
185
- !isInViewport(elementsToHighlight[0], _options.scrollWhenOffscreen === 'top')) {
193
+ if (_options.scrollStrategy &&
194
+ !isInViewport(elementsToHighlight[0], _options.scrollStrategy.whenWhatPartIsHidden)) {
186
195
  elementsToHighlight[0]?.scrollIntoView({
187
- behavior: 'smooth',
188
- block: _options.scrollWhenOffscreen === 'top' ? 'start' : 'center',
189
- inline: _options.scrollWhenOffscreen === 'top' ? 'start' : 'center',
196
+ behavior: _options.scrollStrategy.behavior,
197
+ block: _options.scrollStrategy.logicalPosition,
198
+ inline: _options.scrollStrategy.logicalPosition,
190
199
  });
191
200
  }
192
201
  elementsToHighlight.forEach((el) => el.setAttribute(`highlight${this.#id}`, ''));
package/lib/utils.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function sleep(milli?: number): Promise<unknown>;
2
- export declare function isInViewport(el: HTMLElement, onlyTop?: boolean): boolean;
2
+ export type IsInViewportPartCheck = 'top' | 'center' | 'bounding-rect' | 'bottom';
3
+ export declare function isInViewport(el: HTMLElement, partCheck?: IsInViewportPartCheck): boolean;
3
4
  //# sourceMappingURL=utils.d.ts.map
package/lib/utils.js CHANGED
@@ -1,22 +1,29 @@
1
1
  export function sleep(milli = 1000) {
2
2
  return new Promise((r) => setTimeout(r, milli));
3
3
  }
4
- // export function isInViewport(el: Element) {
5
- // return (
6
- // el.getBoundingClientRect().top >= 0 &&
7
- // el.getBoundingClientRect().bottom <= window.innerHeight
8
- // )
9
- // }
10
- export function isInViewport(el, onlyTop = false) {
4
+ export function isInViewport(el, partCheck = 'center') {
11
5
  const rect = el.getBoundingClientRect();
12
6
  const viewHeight = window.innerHeight || document.documentElement.clientHeight;
13
7
  const viewWidth = window.innerWidth || document.documentElement.clientWidth;
14
- if (onlyTop) {
15
- return rect.top >= 0 && rect.top <= viewHeight;
8
+ switch (partCheck) {
9
+ case 'top':
10
+ return rect.top >= 0 && rect.top <= viewHeight;
11
+ case 'bottom':
12
+ return rect.bottom >= 0 && rect.bottom <= viewHeight;
13
+ case 'center': {
14
+ const centerY = rect.top + rect.height / 2;
15
+ const centerX = rect.left + rect.width / 2;
16
+ return (centerY >= 0 &&
17
+ centerY <= viewHeight &&
18
+ centerX >= 0 &&
19
+ centerX <= viewWidth);
20
+ }
21
+ case 'bounding-rect':
22
+ default:
23
+ return (rect.bottom > 0 &&
24
+ rect.right > 0 &&
25
+ rect.top < viewHeight &&
26
+ rect.left < viewWidth);
16
27
  }
17
- return (rect.bottom > 0 &&
18
- rect.right > 0 &&
19
- rect.top < viewHeight &&
20
- rect.left < viewWidth);
21
28
  }
22
29
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vdegenne/highlight-manager",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "helper to navigate/highlight elements in a page based on a css selector",
5
5
  "type": "module",
6
6
  "exports": {