UNPKG

@thalesrc/resize-manager

Version:

Improved Resize Events of Window & Dom Elements

157 lines 5.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GTResizeObserver = void 0; var rxjs_1 = require("rxjs"); var operators_1 = require("rxjs/operators"); var js_utils_1 = require("@thalesrc/js-utils"); /** * Resize Event provider of all registered elements */ var RESIZE_EVENTS_SUBJECT = new rxjs_1.Subject(); /** * Observable instance of RESIZE_EVENTS_SUBJECT * @see RESIZE_EVENTS_SUBJECT */ var RESIZE_EVENTS = RESIZE_EVENTS_SUBJECT.pipe(operators_1.share()); /** * Html Elements' Resize Observer */ var RESIZE_OBSERVER = new ResizeObserver(function (entries) { entries.forEach(function (entry) { return RESIZE_EVENTS_SUBJECT.next(entry); }); }); /** * Mutation Event provider of all registered elements */ var MUTATION_EVENTS_SUBJECT = new rxjs_1.Subject(); /** * Observable instance of MUTATION_EVENTS_SUBJECT * @see MUTATION_EVENTS_SUBJECT */ var MUTATION_EVENTS = MUTATION_EVENTS_SUBJECT.pipe(operators_1.share()); /** * Html Elements' Mutation Observer */ var MUTATION_OBSERVER = new MutationObserver(function (records) { records.forEach(function (record) { return MUTATION_EVENTS_SUBJECT.next(record); }); }); /** * Cache observed elements and observables */ var OBSERVER_CACHE = new WeakMap(); /** * Creates and registers resize observers for the target with factory given * @param target Target to provide resize events * @param factory Resize Event Observable Factory */ function resizeEventProvider(target, factory) { var cache = OBSERVER_CACHE.get(target); if (!cache) { cache = factory(target); OBSERVER_CACHE.set(target, cache); } return cache; } /** * Creates and registers resize observer for a window instance * @param target Target Window Object */ function windowResizeEventProvider(target) { return resizeEventProvider(target, function (target) { return rxjs_1.fromEvent(target, "resize").pipe(operators_1.map(function (e) { return ({ width: target.innerWidth, height: target.innerHeight }); }), operators_1.share()); }); } /** * Creates and registers resize observer for an HTMLElement instance * @param target Target Window Object */ function domElementResizeEventProvider(target) { return resizeEventProvider(target, function (target) { RESIZE_OBSERVER.observe(target); MUTATION_OBSERVER.observe(target, { attributes: true, characterData: true, subtree: true, childList: true }); return RESIZE_EVENTS.pipe(operators_1.filter(function (e) { return e.target === target; }), operators_1.map(function (entry) { return ({ width: entry.contentRect.width, height: entry.contentRect.height }); }), operators_1.merge(MUTATION_EVENTS.pipe(operators_1.filter(function (record) { return record.type !== "attributes"; }), operators_1.map(function () { return ({ width: target.offsetWidth, height: target.offsetHeight }); }))), operators_1.distinctUntilChanged(function (_a, next) { var width = _a.width, height = _a.height; return width === next.width && height === next.height; }), operators_1.share()); }); } function bothTruthy(val1, val2) { return js_utils_1.isTruthy(val1) && js_utils_1.isTruthy(val2); } /** * #### Resize Observer * Provides improved resize observables */ var GTResizeObserver = /** @class */ (function () { /** * @param target Target to listen its resize events * @param throttleTime Time interval to throttle resize events * > The throttle time under 90ms will not work well because of performance prospects. * > It will fire much less event than expected. * > Use in caution! */ function GTResizeObserver(target, throttleTime) { if (throttleTime === void 0) { throttleTime = 90; } this.target = target; this.throttleTime = throttleTime; /** * The buffer for the observables which are throttled by the same time */ this._buffer = {}; this._provider = target instanceof Window ? windowResizeEventProvider(target) : domElementResizeEventProvider(target); } Object.defineProperty(GTResizeObserver.prototype, "resize", { /** * Base Resize Observable * * Fires on every resize event * * _By default, throttles events for every [90ms]{@link ScrollObserver#throttleTime}, use [throttleBy]{@link ScrollObserver#throttled} if need something else_ */ get: function () { return this.throttleBy(this.throttleTime); }, enumerable: false, configurable: true }); Object.defineProperty(GTResizeObserver.prototype, "resizeStart", { /** * Emits only when resizing starts */ get: function () { return this._provider.pipe(operators_1.merge(this.resizeEnd.pipe(operators_1.mapTo(false))), operators_1.distinctUntilChanged(bothTruthy), operators_1.filter(js_utils_1.isTruthy)); }, enumerable: false, configurable: true }); Object.defineProperty(GTResizeObserver.prototype, "resizeEnd", { /** * Emits only when resizing ends */ get: function () { return this._provider.pipe(operators_1.debounceTime(this.throttleTime)); }, enumerable: false, configurable: true }); /** * Returns throttled resize events by given time * * Set `time` argument to `0` if want to catch all events * * @param time Time to throttle events */ GTResizeObserver.prototype.throttleBy = function (time) { if (time <= 0) { return this._provider; } if (!(time in this._buffer)) { this._buffer[time] = this._provider.pipe(operators_1.throttleTime(time)); } return this._buffer[time]; }; return GTResizeObserver; }()); exports.GTResizeObserver = GTResizeObserver; //# sourceMappingURL=resize-observer.js.map