| 62 | * The controller's `value` is usable during the host's update cycle. |
| 63 | */ |
| 64 | export class IntersectionController<T = unknown> implements ReactiveController { |
| 65 | private _host: ReactiveControllerHost; |
| 66 | private _targets = new Set<Element>(); |
| 67 | private _observer!: IntersectionObserver; |
| 68 | private _skipInitial = false; |
| 69 | /** |
| 70 | * Flag used to help manage calling the `callback` when observe is called |
| 71 | * and `skipInitial` is set to true. Note that unlike the other observers |
| 72 | * IntersectionObserver *does* report its initial state (e.g. whether or not |
| 73 | * there is an intersection). This flag is used to avoid handling this |
| 74 | * state if `skipInitial` is true. |
| 75 | */ |
| 76 | private _unobservedUpdate = false; |
| 77 | /** |
| 78 | * The result of processing the observer's changes via the `callback` |
| 79 | * function. |
| 80 | */ |
| 81 | value?: T; |
| 82 | /** |
| 83 | * Function that returns a value processed from the observer's changes. |
| 84 | * The result is stored in the `value` property. |
| 85 | */ |
| 86 | callback?: IntersectionValueCallback<T>; |
| 87 | constructor( |
| 88 | host: ReactiveControllerHost & Element, |
| 89 | {target, config, callback, skipInitial}: IntersectionControllerConfig<T> |
| 90 | ) { |
| 91 | this._host = host; |
| 92 | // Target defaults to `host` unless explicitly `null`. |
| 93 | if (target !== null) { |
| 94 | this._targets.add(target ?? host); |
| 95 | } |
| 96 | this._skipInitial = skipInitial ?? this._skipInitial; |
| 97 | this.callback = callback; |
| 98 | if (isServer) { |
| 99 | return; |
| 100 | } |
| 101 | // Check browser support. |
| 102 | if (!window.IntersectionObserver) { |
| 103 | console.warn( |
| 104 | `IntersectionController error: browser does not support IntersectionObserver.` |
| 105 | ); |
| 106 | return; |
| 107 | } |
| 108 | this._observer = new IntersectionObserver( |
| 109 | (entries: IntersectionObserverEntry[]) => { |
| 110 | const unobservedUpdate = this._unobservedUpdate; |
| 111 | this._unobservedUpdate = false; |
| 112 | if (this._skipInitial && unobservedUpdate) { |
| 113 | return; |
| 114 | } |
| 115 | this.handleChanges(entries); |
| 116 | this._host.requestUpdate(); |
| 117 | }, |
| 118 | config |
| 119 | ); |
| 120 | host.addController(this); |
| 121 | } |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…