@thalesrc/resize-manager
Version:
Improved Resize Events of Window & Dom Elements
157 lines • 5.99 kB
JavaScript
;
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