|
|
@@ -0,0 +1,93 @@
|
|
|
+import {ElementRef} from '@angular/core';
|
|
|
+import {getSize} from './size';
|
|
|
+import extend from 'lodash/extend';
|
|
|
+import {IncrementalStackManager} from '@ex-helpers/stack';
|
|
|
+
|
|
|
+declare module '@angular/core' {
|
|
|
+ class ElementRef {
|
|
|
+ nativeElement: any;
|
|
|
+
|
|
|
+ constructor(nativeElement: any);
|
|
|
+
|
|
|
+ watchSize: (callback: (height: number, width: number) => void,
|
|
|
+ options?: { attributes: boolean, childList: boolean, characterData: boolean },
|
|
|
+ params?: { legacy: boolean, timeout?: number }) => () => void;
|
|
|
+
|
|
|
+ triggerSizeCheck: () => void;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+interface SizeCollectionItem {
|
|
|
+ triggerCheck: () => void;
|
|
|
+ startCountdown: () => void;
|
|
|
+ callback: (height: number, width: number) => void;
|
|
|
+ observer?: MutationObserver;
|
|
|
+ id?: number;
|
|
|
+ legacy?: boolean;
|
|
|
+}
|
|
|
+
|
|
|
+const DEFAULT_OPTIONS = {
|
|
|
+ attributes: true,
|
|
|
+ childList: true,
|
|
|
+ characterData: true
|
|
|
+};
|
|
|
+
|
|
|
+(ElementRef as any).prototype.watchSize = function
|
|
|
+(callback: (height: number, width: number) => void,
|
|
|
+ options?: { attributes?: boolean, childList?: boolean, characterData?: boolean },
|
|
|
+ params: { timeout?: number, legacy: boolean } = {legacy: false}) {
|
|
|
+ if (!this._watchSizeCollection) {
|
|
|
+ Object.defineProperty(this, '_watchSizeCollection', {
|
|
|
+ enumerable: false,
|
|
|
+ configurable: true,
|
|
|
+ writable: false,
|
|
|
+ value: new IncrementalStackManager<SizeCollectionItem>()
|
|
|
+ });
|
|
|
+ }
|
|
|
+ options = extend(DEFAULT_OPTIONS, options);
|
|
|
+ let timeout: any;
|
|
|
+ let lastHeight: number;
|
|
|
+ let lastWidth: number;
|
|
|
+ const triggerCheck = () => {
|
|
|
+ const sizes = getSize(this.nativeElement);
|
|
|
+ if (lastWidth === sizes.width && lastHeight === sizes.height) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ lastHeight = sizes.height;
|
|
|
+ lastWidth = sizes.width;
|
|
|
+ callback(sizes.height, sizes.width);
|
|
|
+ };
|
|
|
+ const startCountdown = () => {
|
|
|
+ clearTimeout(timeout);
|
|
|
+ timeout = setTimeout(() => {
|
|
|
+ triggerCheck();
|
|
|
+ }, params.timeout || 100);
|
|
|
+ };
|
|
|
+ const item = this._watchSizeCollection.add({
|
|
|
+ callback,
|
|
|
+ startCountdown
|
|
|
+ });
|
|
|
+ if (MutationObserver && params.legacy === false) {
|
|
|
+ const observer = new MutationObserver(mutations => {
|
|
|
+ startCountdown();
|
|
|
+ });
|
|
|
+ item.observer = observer;
|
|
|
+ item.legacy = false;
|
|
|
+ startCountdown();
|
|
|
+ observer.observe(this.nativeElement, options);
|
|
|
+ return () => observer.disconnect();
|
|
|
+ } else {
|
|
|
+ item.legacy = true;
|
|
|
+ const checkInterval = setInterval(() => {
|
|
|
+ triggerCheck();
|
|
|
+ }, 200);
|
|
|
+ startCountdown();
|
|
|
+ return () => clearInterval(checkInterval);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+(ElementRef as any).prototype.triggerSizeCheck = function () {
|
|
|
+ if (this._watchSizeCollection) {
|
|
|
+ this._watchSizeCollection.call('triggerCheck');
|
|
|
+ }
|
|
|
+};
|