diff options
| author | rxliuli <rxliuli@gmail.com> | 2025-11-04 05:03:50 +0800 |
|---|---|---|
| committer | rxliuli <rxliuli@gmail.com> | 2025-11-04 05:03:50 +0800 |
| commit | bce557cc2dc767628bed6aac87301a1be7c5431b (patch) | |
| tree | b51a051228d01fe3306cd7626d4a96768aadb944 /shared/components/node_modules/intersection-observer-admin/dist | |
init commit
Diffstat (limited to 'shared/components/node_modules/intersection-observer-admin/dist')
| -rw-r--r-- | shared/components/node_modules/intersection-observer-admin/dist/intersection-observer-admin.es5.js | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/shared/components/node_modules/intersection-observer-admin/dist/intersection-observer-admin.es5.js b/shared/components/node_modules/intersection-observer-admin/dist/intersection-observer-admin.es5.js new file mode 100644 index 0000000..c6051f1 --- /dev/null +++ b/shared/components/node_modules/intersection-observer-admin/dist/intersection-observer-admin.es5.js @@ -0,0 +1,428 @@ +var Registry = /** @class */ (function () { + function Registry() { + this.registry = new WeakMap(); + } + Registry.prototype.elementExists = function (elem) { + return this.registry.has(elem); + }; + Registry.prototype.getElement = function (elem) { + return this.registry.get(elem); + }; + /** + * administrator for lookup in the future + * + * @method add + * @param {HTMLElement | Window} element - the item to add to root element registry + * @param {IOption} options + * @param {IOption.root} [root] - contains optional root e.g. window, container div, etc + * @param {IOption.watcher} [observer] - optional + * @public + */ + Registry.prototype.addElement = function (element, options) { + if (!element) { + return; + } + this.registry.set(element, options || {}); + }; + /** + * @method remove + * @param {HTMLElement|Window} target + * @public + */ + Registry.prototype.removeElement = function (target) { + this.registry.delete(target); + }; + /** + * reset weak map + * + * @method destroy + * @public + */ + Registry.prototype.destroyRegistry = function () { + this.registry = new WeakMap(); + }; + return Registry; +}()); + +var noop = function () { }; +var CallbackType; +(function (CallbackType) { + CallbackType["enter"] = "enter"; + CallbackType["exit"] = "exit"; +})(CallbackType || (CallbackType = {})); +var Notifications = /** @class */ (function () { + function Notifications() { + this.registry = new Registry(); + } + /** + * Adds an EventListener as a callback for an event key. + * @param type 'enter' or 'exit' + * @param key The key of the event + * @param callback The callback function to invoke when the event occurs + */ + Notifications.prototype.addCallback = function (type, element, callback) { + var _a, _b; + var entry; + if (type === CallbackType.enter) { + entry = (_a = {}, _a[CallbackType.enter] = callback, _a); + } + else { + entry = (_b = {}, _b[CallbackType.exit] = callback, _b); + } + this.registry.addElement(element, Object.assign({}, this.registry.getElement(element), entry)); + }; + /** + * @hidden + * Executes registered callbacks for key. + * @param type + * @param element + * @param data + */ + Notifications.prototype.dispatchCallback = function (type, element, data) { + if (type === CallbackType.enter) { + var _a = this.registry.getElement(element).enter, enter = _a === void 0 ? noop : _a; + enter(data); + } + else { + // no element in WeakMap possible because element may be removed from DOM by the time we get here + var found = this.registry.getElement(element); + if (found && found.exit) { + found.exit(data); + } + } + }; + return Notifications; +}()); + +var __extends = (undefined && undefined.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (undefined && undefined.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var IntersectionObserverAdmin = /** @class */ (function (_super) { + __extends(IntersectionObserverAdmin, _super); + function IntersectionObserverAdmin() { + var _this = _super.call(this) || this; + _this.elementRegistry = new Registry(); + return _this; + } + /** + * Adds element to observe via IntersectionObserver and stores element + relevant callbacks and observer options in static + * administrator for lookup in the future + * + * @method observe + * @param {HTMLElement | Window} element + * @param {Object} options + * @public + */ + IntersectionObserverAdmin.prototype.observe = function (element, options) { + if (options === void 0) { options = {}; } + if (!element) { + return; + } + this.elementRegistry.addElement(element, __assign({}, options)); + this.setupObserver(element, __assign({}, options)); + }; + /** + * Unobserve target element and remove element from static admin + * + * @method unobserve + * @param {HTMLElement|Window} target + * @param {Object} options + * @public + */ + IntersectionObserverAdmin.prototype.unobserve = function (target, options) { + var matchingRootEntry = this.findMatchingRootEntry(options); + if (matchingRootEntry) { + var intersectionObserver = matchingRootEntry.intersectionObserver; + intersectionObserver.unobserve(target); + } + }; + /** + * register event to handle when intersection observer detects enter + * + * @method addEnterCallback + * @public + */ + IntersectionObserverAdmin.prototype.addEnterCallback = function (element, callback) { + this.addCallback(CallbackType.enter, element, callback); + }; + /** + * register event to handle when intersection observer detects exit + * + * @method addExitCallback + * @public + */ + IntersectionObserverAdmin.prototype.addExitCallback = function (element, callback) { + this.addCallback(CallbackType.exit, element, callback); + }; + /** + * retrieve registered callback and call with data + * + * @method dispatchEnterCallback + * @public + */ + IntersectionObserverAdmin.prototype.dispatchEnterCallback = function (element, entry) { + this.dispatchCallback(CallbackType.enter, element, entry); + }; + /** + * retrieve registered callback and call with data on exit + * + * @method dispatchExitCallback + * @public + */ + IntersectionObserverAdmin.prototype.dispatchExitCallback = function (element, entry) { + this.dispatchCallback(CallbackType.exit, element, entry); + }; + /** + * cleanup data structures and unobserve elements + * + * @method destroy + * @public + */ + IntersectionObserverAdmin.prototype.destroy = function () { + this.elementRegistry.destroyRegistry(); + }; + /** + * use function composition to curry options + * + * @method setupOnIntersection + * @param {Object} options + */ + IntersectionObserverAdmin.prototype.setupOnIntersection = function (options) { + var _this = this; + return function (ioEntries) { + return _this.onIntersection(options, ioEntries); + }; + }; + IntersectionObserverAdmin.prototype.setupObserver = function (element, options) { + var _a; + var _b = options.root, root = _b === void 0 ? window : _b; + // First - find shared root element (window or target HTMLElement) + // this root is responsible for coordinating it's set of elements + var potentialRootMatch = this.findRootFromRegistry(root); + // Second - if there is a matching root, see if an existing entry with the same options + // regardless of sort order. This is a bit of work + var matchingEntryForRoot; + if (potentialRootMatch) { + matchingEntryForRoot = this.determineMatchingElements(options, potentialRootMatch); + } + // next add found entry to elements and call observer if applicable + if (matchingEntryForRoot) { + var elements = matchingEntryForRoot.elements, intersectionObserver = matchingEntryForRoot.intersectionObserver; + elements.push(element); + if (intersectionObserver) { + intersectionObserver.observe(element); + } + } + else { + // otherwise start observing this element if applicable + // watcher is an instance that has an observe method + var intersectionObserver = this.newObserver(element, options); + var observerEntry = { + elements: [element], + intersectionObserver: intersectionObserver, + options: options + }; + // and add entry to WeakMap under a root element + // with watcher so we can use it later on + var stringifiedOptions = this.stringifyOptions(options); + if (potentialRootMatch) { + // if share same root and need to add new entry to root match + // not functional but :shrug + potentialRootMatch[stringifiedOptions] = observerEntry; + } + else { + // no root exists, so add to WeakMap + this.elementRegistry.addElement(root, (_a = {}, + _a[stringifiedOptions] = observerEntry, + _a)); + } + } + }; + IntersectionObserverAdmin.prototype.newObserver = function (element, options) { + // No matching entry for root in static admin, thus create new IntersectionObserver instance + var root = options.root, rootMargin = options.rootMargin, threshold = options.threshold; + var newIO = new IntersectionObserver(this.setupOnIntersection(options).bind(this), { root: root, rootMargin: rootMargin, threshold: threshold }); + newIO.observe(element); + return newIO; + }; + /** + * IntersectionObserver callback when element is intersecting viewport + * either when `isIntersecting` changes or `intersectionRadio` crosses on of the + * configured `threshold`s. + * Exit callback occurs eagerly (when element is initially out of scope) + * See https://stackoverflow.com/questions/53214116/intersectionobserver-callback-firing-immediately-on-page-load/53385264#53385264 + * + * @method onIntersection + * @param {Object} options + * @param {Array} ioEntries + * @private + */ + IntersectionObserverAdmin.prototype.onIntersection = function (options, ioEntries) { + var _this = this; + ioEntries.forEach(function (entry) { + var isIntersecting = entry.isIntersecting, intersectionRatio = entry.intersectionRatio; + var threshold = options.threshold || 0; + if (Array.isArray(threshold)) { + threshold = threshold[threshold.length - 1]; + } + // then find entry's callback in static administration + var matchingRootEntry = _this.findMatchingRootEntry(options); + // first determine if entry intersecting + if (isIntersecting || intersectionRatio > threshold) { + if (matchingRootEntry) { + matchingRootEntry.elements.some(function (element) { + if (element && element === entry.target) { + _this.dispatchEnterCallback(element, entry); + return true; + } + return false; + }); + } + } + else { + if (matchingRootEntry) { + matchingRootEntry.elements.some(function (element) { + if (element && element === entry.target) { + _this.dispatchExitCallback(element, entry); + return true; + } + return false; + }); + } + } + }); + }; + /** + * { root: { stringifiedOptions: { observer, elements: []...] } } + * @method findRootFromRegistry + * @param {HTMLElement|Window} root + * @private + * @return {Object} of elements that share same root + */ + IntersectionObserverAdmin.prototype.findRootFromRegistry = function (root) { + if (this.elementRegistry) { + return this.elementRegistry.getElement(root); + } + }; + /** + * We don't care about options key order because we already added + * to the static administrator + * + * @method findMatchingRootEntry + * @param {Object} options + * @return {Object} entry with elements and other options + */ + IntersectionObserverAdmin.prototype.findMatchingRootEntry = function (options) { + var _a = options.root, root = _a === void 0 ? window : _a; + var matchingRoot = this.findRootFromRegistry(root); + if (matchingRoot) { + var stringifiedOptions = this.stringifyOptions(options); + return matchingRoot[stringifiedOptions]; + } + }; + /** + * Determine if existing elements for a given root based on passed in options + * regardless of sort order of keys + * + * @method determineMatchingElements + * @param {Object} options + * @param {Object} potentialRootMatch e.g. { stringifiedOptions: { elements: [], ... }, stringifiedOptions: { elements: [], ... }} + * @private + * @return {Object} containing array of elements and other meta + */ + IntersectionObserverAdmin.prototype.determineMatchingElements = function (options, potentialRootMatch) { + var _this = this; + var matchingStringifiedOptions = Object.keys(potentialRootMatch).filter(function (key) { + var comparableOptions = potentialRootMatch[key].options; + return _this.areOptionsSame(options, comparableOptions); + })[0]; + return potentialRootMatch[matchingStringifiedOptions]; + }; + /** + * recursive method to test primitive string, number, null, etc and complex + * object equality. + * + * @method areOptionsSame + * @param {any} a + * @param {any} b + * @private + * @return {boolean} + */ + IntersectionObserverAdmin.prototype.areOptionsSame = function (a, b) { + if (a === b) { + return true; + } + // simple comparison + var type1 = Object.prototype.toString.call(a); + var type2 = Object.prototype.toString.call(b); + if (type1 !== type2) { + return false; + } + else if (type1 !== '[object Object]' && type2 !== '[object Object]') { + return a === b; + } + if (a && b && typeof a === 'object' && typeof b === 'object') { + // complex comparison for only type of [object Object] + for (var key in a) { + if (Object.prototype.hasOwnProperty.call(a, key)) { + // recursion to check nested + if (this.areOptionsSame(a[key], b[key]) === false) { + return false; + } + } + } + } + // if nothing failed + return true; + }; + /** + * Stringify options for use as a key. + * Excludes options.root so that the resulting key is stable + * + * @param {Object} options + * @private + * @return {String} + */ + IntersectionObserverAdmin.prototype.stringifyOptions = function (options) { + var root = options.root; + var replacer = function (key, value) { + if (key === 'root' && root) { + var classList = Array.prototype.slice.call(root.classList); + var classToken = classList.reduce(function (acc, item) { + return (acc += item); + }, ''); + var id = root.id; + return "".concat(id, "-").concat(classToken); + } + return value; + }; + return JSON.stringify(options, replacer); + }; + return IntersectionObserverAdmin; +}(Notifications)); + +export default IntersectionObserverAdmin; +//# sourceMappingURL=intersection-observer-admin.es5.js.map |
