UNPKG

77.2 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('perfect-scrollbar'), require('rxjs'), require('rxjs/operators'), require('@angular/common')) :
3 typeof define === 'function' && define.amd ? define(['exports', '@angular/core', 'perfect-scrollbar', 'rxjs', 'rxjs/operators', '@angular/common'], factory) :
4 (factory((global.zef = global.zef || {}, global.zef.ngxPerfectScrollbar = {}),global.ng.core,global.PerfectScrollbar,global.Rx,global.Rx.Observable.prototype,global.ng.common));
5}(this, (function (exports,core,PerfectScrollbar,rxjs,operators,common) { 'use strict';
6
7 PerfectScrollbar = PerfectScrollbar && PerfectScrollbar.hasOwnProperty('default') ? PerfectScrollbar['default'] : PerfectScrollbar;
8
9 /**
10 * A collection of shims that provide minimal functionality of the ES6 collections.
11 *
12 * These implementations are not meant to be used outside of the ResizeObserver
13 * modules as they cover only a limited range of use cases.
14 */
15 /* eslint-disable require-jsdoc, valid-jsdoc */
16 var MapShim = (function () {
17 if (typeof Map !== 'undefined') {
18 return Map;
19 }
20
21 /**
22 * Returns index in provided array that matches the specified key.
23 *
24 * @param {Array<Array>} arr
25 * @param {*} key
26 * @returns {number}
27 */
28 function getIndex(arr, key) {
29 var result = -1;
30
31 arr.some(function (entry, index) {
32 if (entry[0] === key) {
33 result = index;
34
35 return true;
36 }
37
38 return false;
39 });
40
41 return result;
42 }
43
44 return (function () {
45 function anonymous() {
46 this.__entries__ = [];
47 }
48
49 var prototypeAccessors = { size: { configurable: true } };
50
51 /**
52 * @returns {boolean}
53 */
54 prototypeAccessors.size.get = function () {
55 return this.__entries__.length;
56 };
57
58 /**
59 * @param {*} key
60 * @returns {*}
61 */
62 anonymous.prototype.get = function (key) {
63 var index = getIndex(this.__entries__, key);
64 var entry = this.__entries__[index];
65
66 return entry && entry[1];
67 };
68
69 /**
70 * @param {*} key
71 * @param {*} value
72 * @returns {void}
73 */
74 anonymous.prototype.set = function (key, value) {
75 var index = getIndex(this.__entries__, key);
76
77 if (~index) {
78 this.__entries__[index][1] = value;
79 } else {
80 this.__entries__.push([key, value]);
81 }
82 };
83
84 /**
85 * @param {*} key
86 * @returns {void}
87 */
88 anonymous.prototype.delete = function (key) {
89 var entries = this.__entries__;
90 var index = getIndex(entries, key);
91
92 if (~index) {
93 entries.splice(index, 1);
94 }
95 };
96
97 /**
98 * @param {*} key
99 * @returns {void}
100 */
101 anonymous.prototype.has = function (key) {
102 return !!~getIndex(this.__entries__, key);
103 };
104
105 /**
106 * @returns {void}
107 */
108 anonymous.prototype.clear = function () {
109 this.__entries__.splice(0);
110 };
111
112 /**
113 * @param {Function} callback
114 * @param {*} [ctx=null]
115 * @returns {void}
116 */
117 anonymous.prototype.forEach = function (callback, ctx) {
118 var this$1 = this;
119 if ( ctx === void 0 ) ctx = null;
120
121 for (var i = 0, list = this$1.__entries__; i < list.length; i += 1) {
122 var entry = list[i];
123
124 callback.call(ctx, entry[1], entry[0]);
125 }
126 };
127
128 Object.defineProperties( anonymous.prototype, prototypeAccessors );
129
130 return anonymous;
131 }());
132 })();
133
134 /**
135 * Detects whether window and document objects are available in current environment.
136 */
137 var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;
138
139 // Returns global object of a current environment.
140 var global$1 = (function () {
141 if (typeof global !== 'undefined' && global.Math === Math) {
142 return global;
143 }
144
145 if (typeof self !== 'undefined' && self.Math === Math) {
146 return self;
147 }
148
149 if (typeof window !== 'undefined' && window.Math === Math) {
150 return window;
151 }
152
153 // eslint-disable-next-line no-new-func
154 return Function('return this')();
155 })();
156
157 /**
158 * A shim for the requestAnimationFrame which falls back to the setTimeout if
159 * first one is not supported.
160 *
161 * @returns {number} Requests' identifier.
162 */
163 var requestAnimationFrame$1 = (function () {
164 if (typeof requestAnimationFrame === 'function') {
165 // It's required to use a bounded function because IE sometimes throws
166 // an "Invalid calling object" error if rAF is invoked without the global
167 // object on the left hand side.
168 return requestAnimationFrame.bind(global$1);
169 }
170
171 return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
172 })();
173
174 // Defines minimum timeout before adding a trailing call.
175 var trailingTimeout = 2;
176
177 /**
178 * Creates a wrapper function which ensures that provided callback will be
179 * invoked only once during the specified delay period.
180 *
181 * @param {Function} callback - Function to be invoked after the delay period.
182 * @param {number} delay - Delay after which to invoke callback.
183 * @returns {Function}
184 */
185 var throttle = function (callback, delay) {
186 var leadingCall = false,
187 trailingCall = false,
188 lastCallTime = 0;
189
190 /**
191 * Invokes the original callback function and schedules new invocation if
192 * the "proxy" was called during current request.
193 *
194 * @returns {void}
195 */
196 function resolvePending() {
197 if (leadingCall) {
198 leadingCall = false;
199
200 callback();
201 }
202
203 if (trailingCall) {
204 proxy();
205 }
206 }
207
208 /**
209 * Callback invoked after the specified delay. It will further postpone
210 * invocation of the original function delegating it to the
211 * requestAnimationFrame.
212 *
213 * @returns {void}
214 */
215 function timeoutCallback() {
216 requestAnimationFrame$1(resolvePending);
217 }
218
219 /**
220 * Schedules invocation of the original function.
221 *
222 * @returns {void}
223 */
224 function proxy() {
225 var timeStamp = Date.now();
226
227 if (leadingCall) {
228 // Reject immediately following calls.
229 if (timeStamp - lastCallTime < trailingTimeout) {
230 return;
231 }
232
233 // Schedule new call to be in invoked when the pending one is resolved.
234 // This is important for "transitions" which never actually start
235 // immediately so there is a chance that we might miss one if change
236 // happens amids the pending invocation.
237 trailingCall = true;
238 } else {
239 leadingCall = true;
240 trailingCall = false;
241
242 setTimeout(timeoutCallback, delay);
243 }
244
245 lastCallTime = timeStamp;
246 }
247
248 return proxy;
249 };
250
251 // Minimum delay before invoking the update of observers.
252 var REFRESH_DELAY = 20;
253
254 // A list of substrings of CSS properties used to find transition events that
255 // might affect dimensions of observed elements.
256 var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
257
258 // Check if MutationObserver is available.
259 var mutationObserverSupported = typeof MutationObserver !== 'undefined';
260
261 /**
262 * Singleton controller class which handles updates of ResizeObserver instances.
263 */
264 var ResizeObserverController = function() {
265 this.connected_ = false;
266 this.mutationEventsAdded_ = false;
267 this.mutationsObserver_ = null;
268 this.observers_ = [];
269
270 this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
271 this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);
272 };
273
274 /**
275 * Adds observer to observers list.
276 *
277 * @param {ResizeObserverSPI} observer - Observer to be added.
278 * @returns {void}
279 */
280
281
282 /**
283 * Holds reference to the controller's instance.
284 *
285 * @private {ResizeObserverController}
286 */
287
288
289 /**
290 * Keeps reference to the instance of MutationObserver.
291 *
292 * @private {MutationObserver}
293 */
294
295 /**
296 * Indicates whether DOM listeners have been added.
297 *
298 * @private {boolean}
299 */
300 ResizeObserverController.prototype.addObserver = function (observer) {
301 if (!~this.observers_.indexOf(observer)) {
302 this.observers_.push(observer);
303 }
304
305 // Add listeners if they haven't been added yet.
306 if (!this.connected_) {
307 this.connect_();
308 }
309 };
310
311 /**
312 * Removes observer from observers list.
313 *
314 * @param {ResizeObserverSPI} observer - Observer to be removed.
315 * @returns {void}
316 */
317 ResizeObserverController.prototype.removeObserver = function (observer) {
318 var observers = this.observers_;
319 var index = observers.indexOf(observer);
320
321 // Remove observer if it's present in registry.
322 if (~index) {
323 observers.splice(index, 1);
324 }
325
326 // Remove listeners if controller has no connected observers.
327 if (!observers.length && this.connected_) {
328 this.disconnect_();
329 }
330 };
331
332 /**
333 * Invokes the update of observers. It will continue running updates insofar
334 * it detects changes.
335 *
336 * @returns {void}
337 */
338 ResizeObserverController.prototype.refresh = function () {
339 var changesDetected = this.updateObservers_();
340
341 // Continue running updates if changes have been detected as there might
342 // be future ones caused by CSS transitions.
343 if (changesDetected) {
344 this.refresh();
345 }
346 };
347
348 /**
349 * Updates every observer from observers list and notifies them of queued
350 * entries.
351 *
352 * @private
353 * @returns {boolean} Returns "true" if any observer has detected changes in
354 * dimensions of it's elements.
355 */
356 ResizeObserverController.prototype.updateObservers_ = function () {
357 // Collect observers that have active observations.
358 var activeObservers = this.observers_.filter(function (observer) {
359 return observer.gatherActive(), observer.hasActive();
360 });
361
362 // Deliver notifications in a separate cycle in order to avoid any
363 // collisions between observers, e.g. when multiple instances of
364 // ResizeObserver are tracking the same element and the callback of one
365 // of them changes content dimensions of the observed target. Sometimes
366 // this may result in notifications being blocked for the rest of observers.
367 activeObservers.forEach(function (observer) { return observer.broadcastActive(); });
368
369 return activeObservers.length > 0;
370 };
371
372 /**
373 * Initializes DOM listeners.
374 *
375 * @private
376 * @returns {void}
377 */
378 ResizeObserverController.prototype.connect_ = function () {
379 // Do nothing if running in a non-browser environment or if listeners
380 // have been already added.
381 if (!isBrowser || this.connected_) {
382 return;
383 }
384
385 // Subscription to the "Transitionend" event is used as a workaround for
386 // delayed transitions. This way it's possible to capture at least the
387 // final state of an element.
388 document.addEventListener('transitionend', this.onTransitionEnd_);
389
390 window.addEventListener('resize', this.refresh);
391
392 if (mutationObserverSupported) {
393 this.mutationsObserver_ = new MutationObserver(this.refresh);
394
395 this.mutationsObserver_.observe(document, {
396 attributes: true,
397 childList: true,
398 characterData: true,
399 subtree: true
400 });
401 } else {
402 document.addEventListener('DOMSubtreeModified', this.refresh);
403
404 this.mutationEventsAdded_ = true;
405 }
406
407 this.connected_ = true;
408 };
409
410 /**
411 * Removes DOM listeners.
412 *
413 * @private
414 * @returns {void}
415 */
416 ResizeObserverController.prototype.disconnect_ = function () {
417 // Do nothing if running in a non-browser environment or if listeners
418 // have been already removed.
419 if (!isBrowser || !this.connected_) {
420 return;
421 }
422
423 document.removeEventListener('transitionend', this.onTransitionEnd_);
424 window.removeEventListener('resize', this.refresh);
425
426 if (this.mutationsObserver_) {
427 this.mutationsObserver_.disconnect();
428 }
429
430 if (this.mutationEventsAdded_) {
431 document.removeEventListener('DOMSubtreeModified', this.refresh);
432 }
433
434 this.mutationsObserver_ = null;
435 this.mutationEventsAdded_ = false;
436 this.connected_ = false;
437 };
438
439 /**
440 * "Transitionend" event handler.
441 *
442 * @private
443 * @param {TransitionEvent} event
444 * @returns {void}
445 */
446 ResizeObserverController.prototype.onTransitionEnd_ = function (ref) {
447 var propertyName = ref.propertyName; if ( propertyName === void 0 ) propertyName = '';
448
449 // Detect whether transition may affect dimensions of an element.
450 var isReflowProperty = transitionKeys.some(function (key) {
451 return !!~propertyName.indexOf(key);
452 });
453
454 if (isReflowProperty) {
455 this.refresh();
456 }
457 };
458
459 /**
460 * Returns instance of the ResizeObserverController.
461 *
462 * @returns {ResizeObserverController}
463 */
464 ResizeObserverController.getInstance = function () {
465 if (!this.instance_) {
466 this.instance_ = new ResizeObserverController();
467 }
468
469 return this.instance_;
470 };
471
472 ResizeObserverController.instance_ = null;
473
474 /**
475 * Defines non-writable/enumerable properties of the provided target object.
476 *
477 * @param {Object} target - Object for which to define properties.
478 * @param {Object} props - Properties to be defined.
479 * @returns {Object} Target object.
480 */
481 var defineConfigurable = (function (target, props) {
482 for (var i = 0, list = Object.keys(props); i < list.length; i += 1) {
483 var key = list[i];
484
485 Object.defineProperty(target, key, {
486 value: props[key],
487 enumerable: false,
488 writable: false,
489 configurable: true
490 });
491 }
492
493 return target;
494 });
495
496 /**
497 * Returns the global object associated with provided element.
498 *
499 * @param {Object} target
500 * @returns {Object}
501 */
502 var getWindowOf = (function (target) {
503 // Assume that the element is an instance of Node, which means that it
504 // has the "ownerDocument" property from which we can retrieve a
505 // corresponding global object.
506 var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
507
508 // Return the local global object if it's not possible extract one from
509 // provided element.
510 return ownerGlobal || global$1;
511 });
512
513 // Placeholder of an empty content rectangle.
514 var emptyRect = createRectInit(0, 0, 0, 0);
515
516 /**
517 * Converts provided string to a number.
518 *
519 * @param {number|string} value
520 * @returns {number}
521 */
522 function toFloat(value) {
523 return parseFloat(value) || 0;
524 }
525
526 /**
527 * Extracts borders size from provided styles.
528 *
529 * @param {CSSStyleDeclaration} styles
530 * @param {...string} positions - Borders positions (top, right, ...)
531 * @returns {number}
532 */
533 function getBordersSize(styles) {
534 var positions = [], len = arguments.length - 1;
535 while ( len-- > 0 ) positions[ len ] = arguments[ len + 1 ];
536
537 return positions.reduce(function (size, position) {
538 var value = styles['border-' + position + '-width'];
539
540 return size + toFloat(value);
541 }, 0);
542 }
543
544 /**
545 * Extracts paddings sizes from provided styles.
546 *
547 * @param {CSSStyleDeclaration} styles
548 * @returns {Object} Paddings box.
549 */
550 function getPaddings(styles) {
551 var positions = ['top', 'right', 'bottom', 'left'];
552 var paddings = {};
553
554 for (var i = 0, list = positions; i < list.length; i += 1) {
555 var position = list[i];
556
557 var value = styles['padding-' + position];
558
559 paddings[position] = toFloat(value);
560 }
561
562 return paddings;
563 }
564
565 /**
566 * Calculates content rectangle of provided SVG element.
567 *
568 * @param {SVGGraphicsElement} target - Element content rectangle of which needs
569 * to be calculated.
570 * @returns {DOMRectInit}
571 */
572 function getSVGContentRect(target) {
573 var bbox = target.getBBox();
574
575 return createRectInit(0, 0, bbox.width, bbox.height);
576 }
577
578 /**
579 * Calculates content rectangle of provided HTMLElement.
580 *
581 * @param {HTMLElement} target - Element for which to calculate the content rectangle.
582 * @returns {DOMRectInit}
583 */
584 function getHTMLElementContentRect(target) {
585 // Client width & height properties can't be
586 // used exclusively as they provide rounded values.
587 var clientWidth = target.clientWidth;
588 var clientHeight = target.clientHeight;
589
590 // By this condition we can catch all non-replaced inline, hidden and
591 // detached elements. Though elements with width & height properties less
592 // than 0.5 will be discarded as well.
593 //
594 // Without it we would need to implement separate methods for each of
595 // those cases and it's not possible to perform a precise and performance
596 // effective test for hidden elements. E.g. even jQuery's ':visible' filter
597 // gives wrong results for elements with width & height less than 0.5.
598 if (!clientWidth && !clientHeight) {
599 return emptyRect;
600 }
601
602 var styles = getWindowOf(target).getComputedStyle(target);
603 var paddings = getPaddings(styles);
604 var horizPad = paddings.left + paddings.right;
605 var vertPad = paddings.top + paddings.bottom;
606
607 // Computed styles of width & height are being used because they are the
608 // only dimensions available to JS that contain non-rounded values. It could
609 // be possible to utilize the getBoundingClientRect if only it's data wasn't
610 // affected by CSS transformations let alone paddings, borders and scroll bars.
611 var width = toFloat(styles.width),
612 height = toFloat(styles.height);
613
614 // Width & height include paddings and borders when the 'border-box' box
615 // model is applied (except for IE).
616 if (styles.boxSizing === 'border-box') {
617 // Following conditions are required to handle Internet Explorer which
618 // doesn't include paddings and borders to computed CSS dimensions.
619 //
620 // We can say that if CSS dimensions + paddings are equal to the "client"
621 // properties then it's either IE, and thus we don't need to subtract
622 // anything, or an element merely doesn't have paddings/borders styles.
623 if (Math.round(width + horizPad) !== clientWidth) {
624 width -= getBordersSize(styles, 'left', 'right') + horizPad;
625 }
626
627 if (Math.round(height + vertPad) !== clientHeight) {
628 height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
629 }
630 }
631
632 // Following steps can't be applied to the document's root element as its
633 // client[Width/Height] properties represent viewport area of the window.
634 // Besides, it's as well not necessary as the <html> itself neither has
635 // rendered scroll bars nor it can be clipped.
636 if (!isDocumentElement(target)) {
637 // In some browsers (only in Firefox, actually) CSS width & height
638 // include scroll bars size which can be removed at this step as scroll
639 // bars are the only difference between rounded dimensions + paddings
640 // and "client" properties, though that is not always true in Chrome.
641 var vertScrollbar = Math.round(width + horizPad) - clientWidth;
642 var horizScrollbar = Math.round(height + vertPad) - clientHeight;
643
644 // Chrome has a rather weird rounding of "client" properties.
645 // E.g. for an element with content width of 314.2px it sometimes gives
646 // the client width of 315px and for the width of 314.7px it may give
647 // 314px. And it doesn't happen all the time. So just ignore this delta
648 // as a non-relevant.
649 if (Math.abs(vertScrollbar) !== 1) {
650 width -= vertScrollbar;
651 }
652
653 if (Math.abs(horizScrollbar) !== 1) {
654 height -= horizScrollbar;
655 }
656 }
657
658 return createRectInit(paddings.left, paddings.top, width, height);
659 }
660
661 /**
662 * Checks whether provided element is an instance of the SVGGraphicsElement.
663 *
664 * @param {Element} target - Element to be checked.
665 * @returns {boolean}
666 */
667 var isSVGGraphicsElement = (function () {
668 // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
669 // interface.
670 if (typeof SVGGraphicsElement !== 'undefined') {
671 return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
672 }
673
674 // If it's so, then check that element is at least an instance of the
675 // SVGElement and that it has the "getBBox" method.
676 // eslint-disable-next-line no-extra-parens
677 return function (target) { return target instanceof getWindowOf(target).SVGElement && typeof target.getBBox === 'function'; };
678 })();
679
680 /**
681 * Checks whether provided element is a document element (<html>).
682 *
683 * @param {Element} target - Element to be checked.
684 * @returns {boolean}
685 */
686 function isDocumentElement(target) {
687 return target === getWindowOf(target).document.documentElement;
688 }
689
690 /**
691 * Calculates an appropriate content rectangle for provided html or svg element.
692 *
693 * @param {Element} target - Element content rectangle of which needs to be calculated.
694 * @returns {DOMRectInit}
695 */
696 function getContentRect(target) {
697 if (!isBrowser) {
698 return emptyRect;
699 }
700
701 if (isSVGGraphicsElement(target)) {
702 return getSVGContentRect(target);
703 }
704
705 return getHTMLElementContentRect(target);
706 }
707
708 /**
709 * Creates rectangle with an interface of the DOMRectReadOnly.
710 * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
711 *
712 * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
713 * @returns {DOMRectReadOnly}
714 */
715 function createReadOnlyRect(ref) {
716 var x = ref.x;
717 var y = ref.y;
718 var width = ref.width;
719 var height = ref.height;
720
721 // If DOMRectReadOnly is available use it as a prototype for the rectangle.
722 var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
723 var rect = Object.create(Constr.prototype);
724
725 // Rectangle's properties are not writable and non-enumerable.
726 defineConfigurable(rect, {
727 x: x, y: y, width: width, height: height,
728 top: y,
729 right: x + width,
730 bottom: height + y,
731 left: x
732 });
733
734 return rect;
735 }
736
737 /**
738 * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
739 * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
740 *
741 * @param {number} x - X coordinate.
742 * @param {number} y - Y coordinate.
743 * @param {number} width - Rectangle's width.
744 * @param {number} height - Rectangle's height.
745 * @returns {DOMRectInit}
746 */
747 function createRectInit(x, y, width, height) {
748 return { x: x, y: y, width: width, height: height };
749 }
750
751 /**
752 * Class that is responsible for computations of the content rectangle of
753 * provided DOM element and for keeping track of it's changes.
754 */
755 var ResizeObservation = function(target) {
756 this.broadcastWidth = 0;
757 this.broadcastHeight = 0;
758 this.contentRect_ = createRectInit(0, 0, 0, 0);
759
760 this.target = target;
761 };
762
763 /**
764 * Updates content rectangle and tells whether it's width or height properties
765 * have changed since the last broadcast.
766 *
767 * @returns {boolean}
768 */
769
770
771 /**
772 * Reference to the last observed content rectangle.
773 *
774 * @private {DOMRectInit}
775 */
776
777
778 /**
779 * Broadcasted width of content rectangle.
780 *
781 * @type {number}
782 */
783 ResizeObservation.prototype.isActive = function () {
784 var rect = getContentRect(this.target);
785
786 this.contentRect_ = rect;
787
788 return rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight;
789 };
790
791 /**
792 * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
793 * from the corresponding properties of the last observed content rectangle.
794 *
795 * @returns {DOMRectInit} Last observed content rectangle.
796 */
797 ResizeObservation.prototype.broadcastRect = function () {
798 var rect = this.contentRect_;
799
800 this.broadcastWidth = rect.width;
801 this.broadcastHeight = rect.height;
802
803 return rect;
804 };
805
806 var ResizeObserverEntry = function(target, rectInit) {
807 var contentRect = createReadOnlyRect(rectInit);
808
809 // According to the specification following properties are not writable
810 // and are also not enumerable in the native implementation.
811 //
812 // Property accessors are not being used as they'd require to define a
813 // private WeakMap storage which may cause memory leaks in browsers that
814 // don't support this type of collections.
815 defineConfigurable(this, { target: target, contentRect: contentRect });
816 };
817
818 var ResizeObserverSPI = function(callback, controller, callbackCtx) {
819 this.activeObservations_ = [];
820 this.observations_ = new MapShim();
821
822 if (typeof callback !== 'function') {
823 throw new TypeError('The callback provided as parameter 1 is not a function.');
824 }
825
826 this.callback_ = callback;
827 this.controller_ = controller;
828 this.callbackCtx_ = callbackCtx;
829 };
830
831 /**
832 * Starts observing provided element.
833 *
834 * @param {Element} target - Element to be observed.
835 * @returns {void}
836 */
837
838
839 /**
840 * Registry of the ResizeObservation instances.
841 *
842 * @private {Map<Element, ResizeObservation>}
843 */
844
845
846 /**
847 * Public ResizeObserver instance which will be passed to the callback
848 * function and used as a value of it's "this" binding.
849 *
850 * @private {ResizeObserver}
851 */
852
853 /**
854 * Collection of resize observations that have detected changes in dimensions
855 * of elements.
856 *
857 * @private {Array<ResizeObservation>}
858 */
859 ResizeObserverSPI.prototype.observe = function (target) {
860 if (!arguments.length) {
861 throw new TypeError('1 argument required, but only 0 present.');
862 }
863
864 // Do nothing if current environment doesn't have the Element interface.
865 if (typeof Element === 'undefined' || !(Element instanceof Object)) {
866 return;
867 }
868
869 if (!(target instanceof getWindowOf(target).Element)) {
870 throw new TypeError('parameter 1 is not of type "Element".');
871 }
872
873 var observations = this.observations_;
874
875 // Do nothing if element is already being observed.
876 if (observations.has(target)) {
877 return;
878 }
879
880 observations.set(target, new ResizeObservation(target));
881
882 this.controller_.addObserver(this);
883
884 // Force the update of observations.
885 this.controller_.refresh();
886 };
887
888 /**
889 * Stops observing provided element.
890 *
891 * @param {Element} target - Element to stop observing.
892 * @returns {void}
893 */
894 ResizeObserverSPI.prototype.unobserve = function (target) {
895 if (!arguments.length) {
896 throw new TypeError('1 argument required, but only 0 present.');
897 }
898
899 // Do nothing if current environment doesn't have the Element interface.
900 if (typeof Element === 'undefined' || !(Element instanceof Object)) {
901 return;
902 }
903
904 if (!(target instanceof getWindowOf(target).Element)) {
905 throw new TypeError('parameter 1 is not of type "Element".');
906 }
907
908 var observations = this.observations_;
909
910 // Do nothing if element is not being observed.
911 if (!observations.has(target)) {
912 return;
913 }
914
915 observations.delete(target);
916
917 if (!observations.size) {
918 this.controller_.removeObserver(this);
919 }
920 };
921
922 /**
923 * Stops observing all elements.
924 *
925 * @returns {void}
926 */
927 ResizeObserverSPI.prototype.disconnect = function () {
928 this.clearActive();
929 this.observations_.clear();
930 this.controller_.removeObserver(this);
931 };
932
933 /**
934 * Collects observation instances the associated element of which has changed
935 * it's content rectangle.
936 *
937 * @returns {void}
938 */
939 ResizeObserverSPI.prototype.gatherActive = function () {
940 var this$1 = this;
941
942 this.clearActive();
943
944 this.observations_.forEach(function (observation) {
945 if (observation.isActive()) {
946 this$1.activeObservations_.push(observation);
947 }
948 });
949 };
950
951 /**
952 * Invokes initial callback function with a list of ResizeObserverEntry
953 * instances collected from active resize observations.
954 *
955 * @returns {void}
956 */
957 ResizeObserverSPI.prototype.broadcastActive = function () {
958 // Do nothing if observer doesn't have active observations.
959 if (!this.hasActive()) {
960 return;
961 }
962
963 var ctx = this.callbackCtx_;
964
965 // Create ResizeObserverEntry instance for every active observation.
966 var entries = this.activeObservations_.map(function (observation) {
967 return new ResizeObserverEntry(observation.target, observation.broadcastRect());
968 });
969
970 this.callback_.call(ctx, entries, ctx);
971 this.clearActive();
972 };
973
974 /**
975 * Clears the collection of active observations.
976 *
977 * @returns {void}
978 */
979 ResizeObserverSPI.prototype.clearActive = function () {
980 this.activeObservations_.splice(0);
981 };
982
983 /**
984 * Tells whether observer has active observations.
985 *
986 * @returns {boolean}
987 */
988 ResizeObserverSPI.prototype.hasActive = function () {
989 return this.activeObservations_.length > 0;
990 };
991
992 // Registry of internal observers. If WeakMap is not available use current shim
993 // for the Map collection as it has all required methods and because WeakMap
994 // can't be fully polyfilled anyway.
995 var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
996
997 /**
998 * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
999 * exposing only those methods and properties that are defined in the spec.
1000 */
1001 var ResizeObserver = function(callback) {
1002 if (!(this instanceof ResizeObserver)) {
1003 throw new TypeError('Cannot call a class as a function.');
1004 }
1005 if (!arguments.length) {
1006 throw new TypeError('1 argument required, but only 0 present.');
1007 }
1008
1009 var controller = ResizeObserverController.getInstance();
1010 var observer = new ResizeObserverSPI(callback, controller, this);
1011
1012 observers.set(this, observer);
1013 };
1014
1015 // Expose public methods of ResizeObserver.
1016 ['observe', 'unobserve', 'disconnect'].forEach(function (method) {
1017 ResizeObserver.prototype[method] = function () {
1018 return (ref = observers.get(this))[method].apply(ref, arguments);
1019 var ref;
1020 };
1021 });
1022
1023 var index = (function () {
1024 // Export existing implementation if available.
1025 if (typeof global$1.ResizeObserver !== 'undefined') {
1026 return global$1.ResizeObserver;
1027 }
1028
1029 return ResizeObserver;
1030 })();
1031
1032 /**
1033 * @fileoverview added by tsickle
1034 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1035 */
1036 /** @type {?} */
1037 var PERFECT_SCROLLBAR_CONFIG = new core.InjectionToken('PERFECT_SCROLLBAR_CONFIG');
1038 var Geometry = /** @class */ (function () {
1039 function Geometry(x, y, w, h) {
1040 this.x = x;
1041 this.y = y;
1042 this.w = w;
1043 this.h = h;
1044 }
1045 return Geometry;
1046 }());
1047 var Position = /** @class */ (function () {
1048 function Position(x, y) {
1049 this.x = x;
1050 this.y = y;
1051 }
1052 return Position;
1053 }());
1054 /** @type {?} */
1055 var PerfectScrollbarEvents = [
1056 'psScrollY',
1057 'psScrollX',
1058 'psScrollUp',
1059 'psScrollDown',
1060 'psScrollLeft',
1061 'psScrollRight',
1062 'psYReachEnd',
1063 'psYReachStart',
1064 'psXReachEnd',
1065 'psXReachStart'
1066 ];
1067 var PerfectScrollbarConfig = /** @class */ (function () {
1068 function PerfectScrollbarConfig(config) {
1069 if (config === void 0) { config = {}; }
1070 this.assign(config);
1071 }
1072 /**
1073 * @param {?=} config
1074 * @return {?}
1075 */
1076 PerfectScrollbarConfig.prototype.assign = /**
1077 * @param {?=} config
1078 * @return {?}
1079 */
1080 function (config) {
1081 if (config === void 0) { config = {}; }
1082 for (var key in config) {
1083 this[(/** @type {?} */ (key))] = config[(/** @type {?} */ (key))];
1084 }
1085 };
1086 return PerfectScrollbarConfig;
1087 }());
1088
1089 /**
1090 * @fileoverview added by tsickle
1091 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1092 */
1093 var PerfectScrollbarDirective = /** @class */ (function () {
1094 function PerfectScrollbarDirective(zone, differs, elementRef, platformId, defaults) {
1095 this.zone = zone;
1096 this.differs = differs;
1097 this.elementRef = elementRef;
1098 this.platformId = platformId;
1099 this.defaults = defaults;
1100 this.instance = null;
1101 this.ro = null;
1102 this.timeout = null;
1103 this.animation = null;
1104 this.configDiff = null;
1105 this.ngDestroy = new rxjs.Subject();
1106 this.disabled = false;
1107 this.psScrollY = new core.EventEmitter();
1108 this.psScrollX = new core.EventEmitter();
1109 this.psScrollUp = new core.EventEmitter();
1110 this.psScrollDown = new core.EventEmitter();
1111 this.psScrollLeft = new core.EventEmitter();
1112 this.psScrollRight = new core.EventEmitter();
1113 this.psYReachEnd = new core.EventEmitter();
1114 this.psYReachStart = new core.EventEmitter();
1115 this.psXReachEnd = new core.EventEmitter();
1116 this.psXReachStart = new core.EventEmitter();
1117 }
1118 /**
1119 * @return {?}
1120 */
1121 PerfectScrollbarDirective.prototype.ngOnInit = /**
1122 * @return {?}
1123 */
1124 function () {
1125 var _this = this;
1126 if (!this.disabled && common.isPlatformBrowser(this.platformId)) {
1127 /** @type {?} */
1128 var config_1 = new PerfectScrollbarConfig(this.defaults);
1129 config_1.assign(this.config); // Custom configuration
1130 this.zone.runOutsideAngular(function () {
1131 _this.instance = new PerfectScrollbar(_this.elementRef.nativeElement, config_1);
1132 });
1133 if (!this.configDiff) {
1134 this.configDiff = this.differs.find(this.config || {}).create();
1135 this.configDiff.diff(this.config || {});
1136 }
1137 this.zone.runOutsideAngular(function () {
1138 _this.ro = new index(function () {
1139 _this.update();
1140 });
1141 if (_this.elementRef.nativeElement.children[0]) {
1142 _this.ro.observe(_this.elementRef.nativeElement.children[0]);
1143 }
1144 _this.ro.observe(_this.elementRef.nativeElement);
1145 });
1146 this.zone.runOutsideAngular(function () {
1147 PerfectScrollbarEvents.forEach(function (eventName) {
1148 /** @type {?} */
1149 var eventType = eventName.replace(/([A-Z])/g, function (c) { return "-" + c.toLowerCase(); });
1150 rxjs.fromEvent(_this.elementRef.nativeElement, eventType)
1151 .pipe(operators.debounceTime(20), operators.takeUntil(_this.ngDestroy))
1152 .subscribe(function (event) {
1153 _this[eventName].emit(event);
1154 });
1155 });
1156 });
1157 }
1158 };
1159 /**
1160 * @return {?}
1161 */
1162 PerfectScrollbarDirective.prototype.ngOnDestroy = /**
1163 * @return {?}
1164 */
1165 function () {
1166 var _this = this;
1167 if (common.isPlatformBrowser(this.platformId)) {
1168 this.ngDestroy.next();
1169 this.ngDestroy.complete();
1170 if (this.ro) {
1171 this.ro.disconnect();
1172 }
1173 if (this.timeout && typeof window !== 'undefined') {
1174 window.clearTimeout(this.timeout);
1175 }
1176 this.zone.runOutsideAngular(function () {
1177 if (_this.instance) {
1178 _this.instance.destroy();
1179 }
1180 });
1181 this.instance = null;
1182 }
1183 };
1184 /**
1185 * @return {?}
1186 */
1187 PerfectScrollbarDirective.prototype.ngDoCheck = /**
1188 * @return {?}
1189 */
1190 function () {
1191 if (!this.disabled && this.configDiff && common.isPlatformBrowser(this.platformId)) {
1192 /** @type {?} */
1193 var changes = this.configDiff.diff(this.config || {});
1194 if (changes) {
1195 this.ngOnDestroy();
1196 this.ngOnInit();
1197 }
1198 }
1199 };
1200 /**
1201 * @param {?} changes
1202 * @return {?}
1203 */
1204 PerfectScrollbarDirective.prototype.ngOnChanges = /**
1205 * @param {?} changes
1206 * @return {?}
1207 */
1208 function (changes) {
1209 if (changes['disabled'] && !changes['disabled'].isFirstChange() && common.isPlatformBrowser(this.platformId)) {
1210 if (changes['disabled'].currentValue !== changes['disabled'].previousValue) {
1211 if (changes['disabled'].currentValue === true) {
1212 this.ngOnDestroy();
1213 }
1214 else if (changes['disabled'].currentValue === false) {
1215 this.ngOnInit();
1216 }
1217 }
1218 }
1219 };
1220 /**
1221 * @return {?}
1222 */
1223 PerfectScrollbarDirective.prototype.ps = /**
1224 * @return {?}
1225 */
1226 function () {
1227 return this.instance;
1228 };
1229 /**
1230 * @return {?}
1231 */
1232 PerfectScrollbarDirective.prototype.update = /**
1233 * @return {?}
1234 */
1235 function () {
1236 var _this = this;
1237 if (typeof window !== 'undefined') {
1238 if (this.timeout) {
1239 window.clearTimeout(this.timeout);
1240 }
1241 this.timeout = window.setTimeout(function () {
1242 if (!_this.disabled && _this.configDiff) {
1243 try {
1244 _this.zone.runOutsideAngular(function () {
1245 if (_this.instance) {
1246 _this.instance.update();
1247 }
1248 });
1249 }
1250 catch (error) {
1251 // Update can be finished after destroy so catch errors
1252 }
1253 }
1254 }, 0);
1255 }
1256 };
1257 /**
1258 * @param {?=} prefix
1259 * @return {?}
1260 */
1261 PerfectScrollbarDirective.prototype.geometry = /**
1262 * @param {?=} prefix
1263 * @return {?}
1264 */
1265 function (prefix) {
1266 if (prefix === void 0) { prefix = 'scroll'; }
1267 return new Geometry(this.elementRef.nativeElement[prefix + 'Left'], this.elementRef.nativeElement[prefix + 'Top'], this.elementRef.nativeElement[prefix + 'Width'], this.elementRef.nativeElement[prefix + 'Height']);
1268 };
1269 /**
1270 * @param {?=} absolute
1271 * @return {?}
1272 */
1273 PerfectScrollbarDirective.prototype.position = /**
1274 * @param {?=} absolute
1275 * @return {?}
1276 */
1277 function (absolute) {
1278 if (absolute === void 0) { absolute = false; }
1279 if (!absolute && this.instance) {
1280 return new Position(this.instance.reach.x || 0, this.instance.reach.y || 0);
1281 }
1282 else {
1283 return new Position(this.elementRef.nativeElement.scrollLeft, this.elementRef.nativeElement.scrollTop);
1284 }
1285 };
1286 /**
1287 * @param {?=} direction
1288 * @return {?}
1289 */
1290 PerfectScrollbarDirective.prototype.scrollable = /**
1291 * @param {?=} direction
1292 * @return {?}
1293 */
1294 function (direction) {
1295 if (direction === void 0) { direction = 'any'; }
1296 /** @type {?} */
1297 var element = this.elementRef.nativeElement;
1298 if (direction === 'any') {
1299 return element.classList.contains('ps--active-x') ||
1300 element.classList.contains('ps--active-y');
1301 }
1302 else if (direction === 'both') {
1303 return element.classList.contains('ps--active-x') &&
1304 element.classList.contains('ps--active-y');
1305 }
1306 else {
1307 return element.classList.contains('ps--active-' + direction);
1308 }
1309 };
1310 /**
1311 * @param {?} x
1312 * @param {?=} y
1313 * @param {?=} speed
1314 * @return {?}
1315 */
1316 PerfectScrollbarDirective.prototype.scrollTo = /**
1317 * @param {?} x
1318 * @param {?=} y
1319 * @param {?=} speed
1320 * @return {?}
1321 */
1322 function (x, y, speed) {
1323 if (!this.disabled) {
1324 if (y == null && speed == null) {
1325 this.animateScrolling('scrollTop', x, speed);
1326 }
1327 else {
1328 if (x != null) {
1329 this.animateScrolling('scrollLeft', x, speed);
1330 }
1331 if (y != null) {
1332 this.animateScrolling('scrollTop', y, speed);
1333 }
1334 }
1335 }
1336 };
1337 /**
1338 * @param {?} x
1339 * @param {?=} speed
1340 * @return {?}
1341 */
1342 PerfectScrollbarDirective.prototype.scrollToX = /**
1343 * @param {?} x
1344 * @param {?=} speed
1345 * @return {?}
1346 */
1347 function (x, speed) {
1348 this.animateScrolling('scrollLeft', x, speed);
1349 };
1350 /**
1351 * @param {?} y
1352 * @param {?=} speed
1353 * @return {?}
1354 */
1355 PerfectScrollbarDirective.prototype.scrollToY = /**
1356 * @param {?} y
1357 * @param {?=} speed
1358 * @return {?}
1359 */
1360 function (y, speed) {
1361 this.animateScrolling('scrollTop', y, speed);
1362 };
1363 /**
1364 * @param {?=} offset
1365 * @param {?=} speed
1366 * @return {?}
1367 */
1368 PerfectScrollbarDirective.prototype.scrollToTop = /**
1369 * @param {?=} offset
1370 * @param {?=} speed
1371 * @return {?}
1372 */
1373 function (offset, speed) {
1374 this.animateScrolling('scrollTop', (offset || 0), speed);
1375 };
1376 /**
1377 * @param {?=} offset
1378 * @param {?=} speed
1379 * @return {?}
1380 */
1381 PerfectScrollbarDirective.prototype.scrollToLeft = /**
1382 * @param {?=} offset
1383 * @param {?=} speed
1384 * @return {?}
1385 */
1386 function (offset, speed) {
1387 this.animateScrolling('scrollLeft', (offset || 0), speed);
1388 };
1389 /**
1390 * @param {?=} offset
1391 * @param {?=} speed
1392 * @return {?}
1393 */
1394 PerfectScrollbarDirective.prototype.scrollToRight = /**
1395 * @param {?=} offset
1396 * @param {?=} speed
1397 * @return {?}
1398 */
1399 function (offset, speed) {
1400 /** @type {?} */
1401 var left = this.elementRef.nativeElement.scrollWidth -
1402 this.elementRef.nativeElement.clientWidth;
1403 this.animateScrolling('scrollLeft', left - (offset || 0), speed);
1404 };
1405 /**
1406 * @param {?=} offset
1407 * @param {?=} speed
1408 * @return {?}
1409 */
1410 PerfectScrollbarDirective.prototype.scrollToBottom = /**
1411 * @param {?=} offset
1412 * @param {?=} speed
1413 * @return {?}
1414 */
1415 function (offset, speed) {
1416 /** @type {?} */
1417 var top = this.elementRef.nativeElement.scrollHeight -
1418 this.elementRef.nativeElement.clientHeight;
1419 this.animateScrolling('scrollTop', top - (offset || 0), speed);
1420 };
1421 /**
1422 * @param {?} qs
1423 * @param {?=} offset
1424 * @param {?=} speed
1425 * @return {?}
1426 */
1427 PerfectScrollbarDirective.prototype.scrollToElement = /**
1428 * @param {?} qs
1429 * @param {?=} offset
1430 * @param {?=} speed
1431 * @return {?}
1432 */
1433 function (qs, offset, speed) {
1434 /** @type {?} */
1435 var element = this.elementRef.nativeElement.querySelector(qs);
1436 if (element) {
1437 /** @type {?} */
1438 var elementPos = element.getBoundingClientRect();
1439 /** @type {?} */
1440 var scrollerPos = this.elementRef.nativeElement.getBoundingClientRect();
1441 if (this.elementRef.nativeElement.classList.contains('ps--active-x')) {
1442 /** @type {?} */
1443 var currentPos = this.elementRef.nativeElement['scrollLeft'];
1444 /** @type {?} */
1445 var position = elementPos.left - scrollerPos.left + currentPos;
1446 this.animateScrolling('scrollLeft', position + (offset || 0), speed);
1447 }
1448 if (this.elementRef.nativeElement.classList.contains('ps--active-y')) {
1449 /** @type {?} */
1450 var currentPos = this.elementRef.nativeElement['scrollTop'];
1451 /** @type {?} */
1452 var position = elementPos.top - scrollerPos.top + currentPos;
1453 this.animateScrolling('scrollTop', position + (offset || 0), speed);
1454 }
1455 }
1456 };
1457 /**
1458 * @param {?} target
1459 * @param {?} value
1460 * @param {?=} speed
1461 * @return {?}
1462 */
1463 PerfectScrollbarDirective.prototype.animateScrolling = /**
1464 * @param {?} target
1465 * @param {?} value
1466 * @param {?=} speed
1467 * @return {?}
1468 */
1469 function (target, value, speed) {
1470 var _this = this;
1471 if (this.animation) {
1472 window.cancelAnimationFrame(this.animation);
1473 this.animation = null;
1474 }
1475 if (!speed || typeof window === 'undefined') {
1476 this.elementRef.nativeElement[target] = value;
1477 }
1478 else if (value !== this.elementRef.nativeElement[target]) {
1479 /** @type {?} */
1480 var newValue_1 = 0;
1481 /** @type {?} */
1482 var scrollCount_1 = 0;
1483 /** @type {?} */
1484 var oldTimestamp_1 = performance.now();
1485 /** @type {?} */
1486 var oldValue_1 = this.elementRef.nativeElement[target];
1487 /** @type {?} */
1488 var cosParameter_1 = (oldValue_1 - value) / 2;
1489 /** @type {?} */
1490 var step_1 = function (newTimestamp) {
1491 scrollCount_1 += Math.PI / (speed / (newTimestamp - oldTimestamp_1));
1492 newValue_1 = Math.round(value + cosParameter_1 + cosParameter_1 * Math.cos(scrollCount_1));
1493 // Only continue animation if scroll position has not changed
1494 if (_this.elementRef.nativeElement[target] === oldValue_1) {
1495 if (scrollCount_1 >= Math.PI) {
1496 _this.animateScrolling(target, value, 0);
1497 }
1498 else {
1499 _this.elementRef.nativeElement[target] = newValue_1;
1500 // On a zoomed out page the resulting offset may differ
1501 oldValue_1 = _this.elementRef.nativeElement[target];
1502 oldTimestamp_1 = newTimestamp;
1503 _this.animation = window.requestAnimationFrame(step_1);
1504 }
1505 }
1506 };
1507 window.requestAnimationFrame(step_1);
1508 }
1509 };
1510 PerfectScrollbarDirective.decorators = [
1511 { type: core.Directive, args: [{
1512 selector: '[perfectScrollbar]',
1513 exportAs: 'ngxPerfectScrollbar'
1514 },] }
1515 ];
1516 /** @nocollapse */
1517 PerfectScrollbarDirective.ctorParameters = function () { return [
1518 { type: core.NgZone },
1519 { type: core.KeyValueDiffers },
1520 { type: core.ElementRef },
1521 { type: Object, decorators: [{ type: core.Inject, args: [core.PLATFORM_ID,] }] },
1522 { type: undefined, decorators: [{ type: core.Optional }, { type: core.Inject, args: [PERFECT_SCROLLBAR_CONFIG,] }] }
1523 ]; };
1524 PerfectScrollbarDirective.propDecorators = {
1525 disabled: [{ type: core.Input }],
1526 config: [{ type: core.Input, args: ['perfectScrollbar',] }],
1527 psScrollY: [{ type: core.Output }],
1528 psScrollX: [{ type: core.Output }],
1529 psScrollUp: [{ type: core.Output }],
1530 psScrollDown: [{ type: core.Output }],
1531 psScrollLeft: [{ type: core.Output }],
1532 psScrollRight: [{ type: core.Output }],
1533 psYReachEnd: [{ type: core.Output }],
1534 psYReachStart: [{ type: core.Output }],
1535 psXReachEnd: [{ type: core.Output }],
1536 psXReachStart: [{ type: core.Output }]
1537 };
1538 return PerfectScrollbarDirective;
1539 }());
1540
1541 /**
1542 * @fileoverview added by tsickle
1543 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1544 */
1545 var PerfectScrollbarComponent = /** @class */ (function () {
1546 function PerfectScrollbarComponent(zone, cdRef, platformId) {
1547 this.zone = zone;
1548 this.cdRef = cdRef;
1549 this.platformId = platformId;
1550 this.states = {};
1551 this.indicatorX = false;
1552 this.indicatorY = false;
1553 this.interaction = false;
1554 this.scrollPositionX = 0;
1555 this.scrollPositionY = 0;
1556 this.scrollDirectionX = 0;
1557 this.scrollDirectionY = 0;
1558 this.usePropagationX = false;
1559 this.usePropagationY = false;
1560 this.allowPropagationX = false;
1561 this.allowPropagationY = false;
1562 this.stateTimeout = null;
1563 this.ngDestroy = new rxjs.Subject();
1564 this.stateUpdate = new rxjs.Subject();
1565 this.disabled = false;
1566 this.usePSClass = true;
1567 this.autoPropagation = false;
1568 this.scrollIndicators = false;
1569 this.psScrollY = new core.EventEmitter();
1570 this.psScrollX = new core.EventEmitter();
1571 this.psScrollUp = new core.EventEmitter();
1572 this.psScrollDown = new core.EventEmitter();
1573 this.psScrollLeft = new core.EventEmitter();
1574 this.psScrollRight = new core.EventEmitter();
1575 this.psYReachEnd = new core.EventEmitter();
1576 this.psYReachStart = new core.EventEmitter();
1577 this.psXReachEnd = new core.EventEmitter();
1578 this.psXReachStart = new core.EventEmitter();
1579 }
1580 /**
1581 * @return {?}
1582 */
1583 PerfectScrollbarComponent.prototype.ngOnInit = /**
1584 * @return {?}
1585 */
1586 function () {
1587 var _this = this;
1588 if (common.isPlatformBrowser(this.platformId)) {
1589 this.stateUpdate
1590 .pipe(operators.takeUntil(this.ngDestroy), operators.distinctUntilChanged(function (a, b) { return (a === b && !_this.stateTimeout); }))
1591 .subscribe(function (state) {
1592 if (_this.stateTimeout && typeof window !== 'undefined') {
1593 window.clearTimeout(_this.stateTimeout);
1594 _this.stateTimeout = null;
1595 }
1596 if (state === 'x' || state === 'y') {
1597 _this.interaction = false;
1598 if (state === 'x') {
1599 _this.indicatorX = false;
1600 _this.states.left = false;
1601 _this.states.right = false;
1602 if (_this.autoPropagation && _this.usePropagationX) {
1603 _this.allowPropagationX = false;
1604 }
1605 }
1606 else if (state === 'y') {
1607 _this.indicatorY = false;
1608 _this.states.top = false;
1609 _this.states.bottom = false;
1610 if (_this.autoPropagation && _this.usePropagationY) {
1611 _this.allowPropagationY = false;
1612 }
1613 }
1614 }
1615 else {
1616 if (state === 'left' || state === 'right') {
1617 _this.states.left = false;
1618 _this.states.right = false;
1619 _this.states[state] = true;
1620 if (_this.autoPropagation && _this.usePropagationX) {
1621 _this.indicatorX = true;
1622 }
1623 }
1624 else if (state === 'top' || state === 'bottom') {
1625 _this.states.top = false;
1626 _this.states.bottom = false;
1627 _this.states[state] = true;
1628 if (_this.autoPropagation && _this.usePropagationY) {
1629 _this.indicatorY = true;
1630 }
1631 }
1632 if (_this.autoPropagation && typeof window !== 'undefined') {
1633 _this.stateTimeout = window.setTimeout(function () {
1634 _this.indicatorX = false;
1635 _this.indicatorY = false;
1636 _this.stateTimeout = null;
1637 if (_this.interaction && (_this.states.left || _this.states.right)) {
1638 _this.allowPropagationX = true;
1639 }
1640 if (_this.interaction && (_this.states.top || _this.states.bottom)) {
1641 _this.allowPropagationY = true;
1642 }
1643 _this.cdRef.markForCheck();
1644 }, 500);
1645 }
1646 }
1647 _this.cdRef.markForCheck();
1648 _this.cdRef.detectChanges();
1649 });
1650 this.zone.runOutsideAngular(function () {
1651 if (_this.directiveRef) {
1652 /** @type {?} */
1653 var element = _this.directiveRef.elementRef.nativeElement;
1654 rxjs.fromEvent(element, 'wheel')
1655 .pipe(operators.takeUntil(_this.ngDestroy))
1656 .subscribe(function (event) {
1657 if (!_this.disabled && _this.autoPropagation) {
1658 /** @type {?} */
1659 var scrollDeltaX = event.deltaX;
1660 /** @type {?} */
1661 var scrollDeltaY = event.deltaY;
1662 _this.checkPropagation(event, scrollDeltaX, scrollDeltaY);
1663 }
1664 });
1665 rxjs.fromEvent(element, 'touchmove')
1666 .pipe(operators.takeUntil(_this.ngDestroy))
1667 .subscribe(function (event) {
1668 if (!_this.disabled && _this.autoPropagation) {
1669 /** @type {?} */
1670 var scrollPositionX = event.touches[0].clientX;
1671 /** @type {?} */
1672 var scrollPositionY = event.touches[0].clientY;
1673 /** @type {?} */
1674 var scrollDeltaX = scrollPositionX - _this.scrollPositionX;
1675 /** @type {?} */
1676 var scrollDeltaY = scrollPositionY - _this.scrollPositionY;
1677 _this.checkPropagation(event, scrollDeltaX, scrollDeltaY);
1678 _this.scrollPositionX = scrollPositionX;
1679 _this.scrollPositionY = scrollPositionY;
1680 }
1681 });
1682 rxjs.merge(rxjs.fromEvent(element, 'ps-scroll-x')
1683 .pipe(operators.mapTo('x')), rxjs.fromEvent(element, 'ps-scroll-y')
1684 .pipe(operators.mapTo('y')), rxjs.fromEvent(element, 'ps-x-reach-end')
1685 .pipe(operators.mapTo('right')), rxjs.fromEvent(element, 'ps-y-reach-end')
1686 .pipe(operators.mapTo('bottom')), rxjs.fromEvent(element, 'ps-x-reach-start')
1687 .pipe(operators.mapTo('left')), rxjs.fromEvent(element, 'ps-y-reach-start')
1688 .pipe(operators.mapTo('top')))
1689 .pipe(operators.takeUntil(_this.ngDestroy))
1690 .subscribe(function (state) {
1691 if (!_this.disabled && (_this.autoPropagation || _this.scrollIndicators)) {
1692 _this.stateUpdate.next(state);
1693 }
1694 });
1695 }
1696 });
1697 window.setTimeout(function () {
1698 PerfectScrollbarEvents.forEach(function (eventName) {
1699 if (_this.directiveRef) {
1700 _this.directiveRef[eventName] = _this[eventName];
1701 }
1702 });
1703 }, 0);
1704 }
1705 };
1706 /**
1707 * @return {?}
1708 */
1709 PerfectScrollbarComponent.prototype.ngOnDestroy = /**
1710 * @return {?}
1711 */
1712 function () {
1713 if (common.isPlatformBrowser(this.platformId)) {
1714 this.ngDestroy.next();
1715 this.ngDestroy.unsubscribe();
1716 if (this.stateTimeout && typeof window !== 'undefined') {
1717 window.clearTimeout(this.stateTimeout);
1718 }
1719 }
1720 };
1721 /**
1722 * @return {?}
1723 */
1724 PerfectScrollbarComponent.prototype.ngDoCheck = /**
1725 * @return {?}
1726 */
1727 function () {
1728 if (common.isPlatformBrowser(this.platformId)) {
1729 if (!this.disabled && this.autoPropagation && this.directiveRef) {
1730 /** @type {?} */
1731 var element = this.directiveRef.elementRef.nativeElement;
1732 this.usePropagationX = element.classList.contains('ps--active-x');
1733 this.usePropagationY = element.classList.contains('ps--active-y');
1734 }
1735 }
1736 };
1737 /**
1738 * @param {?} event
1739 * @param {?} deltaX
1740 * @param {?} deltaY
1741 * @return {?}
1742 */
1743 PerfectScrollbarComponent.prototype.checkPropagation = /**
1744 * @param {?} event
1745 * @param {?} deltaX
1746 * @param {?} deltaY
1747 * @return {?}
1748 */
1749 function (event, deltaX, deltaY) {
1750 this.interaction = true;
1751 /** @type {?} */
1752 var scrollDirectionX = (deltaX < 0) ? -1 : 1;
1753 /** @type {?} */
1754 var scrollDirectionY = (deltaY < 0) ? -1 : 1;
1755 if ((this.usePropagationX && this.usePropagationY) ||
1756 (this.usePropagationX && (!this.allowPropagationX ||
1757 (this.scrollDirectionX !== scrollDirectionX))) ||
1758 (this.usePropagationY && (!this.allowPropagationY ||
1759 (this.scrollDirectionY !== scrollDirectionY)))) {
1760 event.preventDefault();
1761 event.stopPropagation();
1762 }
1763 if (!!deltaX) {
1764 this.scrollDirectionX = scrollDirectionX;
1765 }
1766 if (!!deltaY) {
1767 this.scrollDirectionY = scrollDirectionY;
1768 }
1769 this.stateUpdate.next('interaction');
1770 this.cdRef.detectChanges();
1771 };
1772 PerfectScrollbarComponent.decorators = [
1773 { type: core.Component, args: [{
1774 selector: 'perfect-scrollbar',
1775 exportAs: 'ngxPerfectScrollbar',
1776 template: "<div style=\"position: static;\" [class.ps]=\"usePSClass\" [perfectScrollbar]=\"config\" [disabled]=\"disabled\">\n <div class=\"ps-content\">\n <ng-content></ng-content>\n </div>\n\n <div *ngIf=\"scrollIndicators\" class=\"ps-overlay\" [class.ps-at-top]=\"states.top\" [class.ps-at-left]=\"states.left\" [class.ps-at-right]=\"states.right\" [class.ps-at-bottom]=\"states.bottom\">\n <div class=\"ps-indicator-top\" [class.ps-indicator-show]=\"indicatorY && interaction\"></div>\n <div class=\"ps-indicator-left\" [class.ps-indicator-show]=\"indicatorX && interaction\"></div>\n <div class=\"ps-indicator-right\" [class.ps-indicator-show]=\"indicatorX && interaction\"></div>\n <div class=\"ps-indicator-bottom\" [class.ps-indicator-show]=\"indicatorY && interaction\"></div>\n </div>\n</div>\n",
1777 encapsulation: core.ViewEncapsulation.None,
1778 styles: ["/*\n TODO: Remove important flags after this bug if fixed:\n https://github.com/angular/flex-layout/issues/381\n*/\n\nperfect-scrollbar {\n position: relative;\n\n display: block;\n overflow: hidden;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n}\n\nperfect-scrollbar[hidden] {\n display: none;\n}\n\nperfect-scrollbar[fxflex] {\n display: flex;\n flex-direction: column;\n height: auto;\n min-width: 0;\n min-height: 0;\n\n -webkit-box-direction: column;\n -webkit-box-orient: column;\n}\n\nperfect-scrollbar[fxflex] > .ps {\n -ms-flex: 1 1 auto;\n\n flex: 1 1 auto;\n width: auto;\n height: auto;\n min-width: 0;\n min-height: 0;\n\n -webkit-box-flex: 1;\n}\n\nperfect-scrollbar[fxlayout] > .ps,\nperfect-scrollbar[fxlayout] > .ps > .ps-content {\n display: flex;\n\n -ms-flex: 1 1 auto;\n\n flex: 1 1 auto;\n flex-direction: inherit;\n align-items: inherit;\n align-content: inherit;\n justify-content: inherit;\n width: 100%;\n height: 100%;\n\n -webkit-box-align: inherit;\n -webkit-box-direction: inherit;\n -webkit-box-flex: 1;\n -webkit-box-orient: inherit;\n -webkit-box-pack: inherit;\n}\n\nperfect-scrollbar[fxlayout='row'] > .ps,\nperfect-scrollbar[fxlayout='row'] > .ps > .ps-content, {\n flex-direction: row !important;\n\n -webkit-box-direction: row !important;\n -webkit-box-orient: row !important;\n}\n\nperfect-scrollbar[fxlayout='column'] > .ps,\nperfect-scrollbar[fxlayout='column'] > .ps > .ps-content {\n flex-direction: column !important;\n\n -webkit-box-direction: column !important;\n -webkit-box-orient: column !important;\n}\n\nperfect-scrollbar > .ps {\n position: static;\n\n display: block;\n width: inherit;\n height: inherit;\n max-width: inherit;\n max-height: inherit;\n}\n\nperfect-scrollbar > .ps > .ps-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n display: block;\n overflow: hidden;\n\n pointer-events: none;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-top,\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-left,\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-right,\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-bottom {\n position: absolute;\n\n opacity: 0;\n\n transition: opacity 300ms ease-in-out;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-top,\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-bottom {\n left: 0;\n\n min-width: 100%;\n min-height: 24px;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-left,\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-right {\n top: 0;\n\n min-width: 24px;\n min-height: 100%;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-top {\n top: 0;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-left {\n left: 0;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-right {\n right: 0;\n}\n\nperfect-scrollbar > .ps > .ps-overlay .ps-indicator-bottom {\n bottom: 0;\n}\n\nperfect-scrollbar > .ps.ps--active-y > .ps__rail-y {\n top: 0 !important;\n right: 0 !important;\n left: auto !important;\n\n width: 10px;\n\n cursor: default;\n\n transition:\n width 200ms linear,\n opacity 200ms linear,\n background-color 200ms linear;\n}\n\nperfect-scrollbar > .ps.ps--active-y > .ps__rail-y:hover,\nperfect-scrollbar > .ps.ps--active-y > .ps__rail-y.ps--clicking {\n width: 15px;\n}\n\nperfect-scrollbar > .ps.ps--active-x > .ps__rail-x {\n top: auto !important;\n bottom: 0 !important;\n left: 0 !important;\n\n height: 10px;\n\n cursor: default;\n\n transition:\n height 200ms linear,\n opacity 200ms linear,\n background-color 200ms linear;\n}\n\nperfect-scrollbar > .ps.ps--active-x > .ps__rail-x:hover,\nperfect-scrollbar > .ps.ps--active-x > .ps__rail-x.ps--clicking {\n height: 15px;\n}\n\nperfect-scrollbar > .ps.ps--active-x.ps--active-y > .ps__rail-y {\n margin: 0 0 10px;\n}\n\nperfect-scrollbar > .ps.ps--active-x.ps--active-y > .ps__rail-x {\n margin: 0 10px 0 0;\n}\n\nperfect-scrollbar > .ps.ps--scrolling-y > .ps__rail-y,\nperfect-scrollbar > .ps.ps--scrolling-x > .ps__rail-x {\n opacity: 0.9;\n\n background-color: #eee;\n}\n\nperfect-scrollbar.ps-show-always > .ps.ps--active-y > .ps__rail-y,\nperfect-scrollbar.ps-show-always > .ps.ps--active-x > .ps__rail-x {\n opacity: 0.6;\n}\n\nperfect-scrollbar.ps-show-active > .ps.ps--active-y > .ps-overlay:not(.ps-at-top) .ps-indicator-top {\n opacity: 1;\n\n background: linear-gradient(to bottom, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active > .ps.ps--active-y > .ps-overlay:not(.ps-at-bottom) .ps-indicator-bottom {\n opacity: 1;\n\n background: linear-gradient(to top, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active > .ps.ps--active-x > .ps-overlay:not(.ps-at-left) .ps-indicator-left {\n opacity: 1;\n\n background: linear-gradient(to right, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active > .ps.ps--active-x > .ps-overlay:not(.ps-at-right) .ps-indicator-right {\n opacity: 1;\n\n background: linear-gradient(to left, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-y > .ps-overlay.ps-at-top .ps-indicator-top {\n background: linear-gradient(to bottom, rgba(170, 170, 170, 0.5) 0%, rgba(170, 170, 170, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-y > .ps-overlay.ps-at-bottom .ps-indicator-bottom {\n background: linear-gradient(to top, rgba(170, 170, 170, 0.5) 0%, rgba(170, 170, 170, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-x > .ps-overlay.ps-at-left .ps-indicator-left {\n background: linear-gradient(to right, rgba(170, 170, 170, 0.5) 0%, rgba(170, 170, 170, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-x > .ps-overlay.ps-at-right .ps-indicator-right {\n background: linear-gradient(to left, rgba(170, 170, 170, 0.5) 0%, rgba(170, 170, 170, 0) 100%);\n}\n\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-y > .ps-overlay.ps-at-top .ps-indicator-top.ps-indicator-show,\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-y > .ps-overlay.ps-at-bottom .ps-indicator-bottom.ps-indicator-show,\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-x > .ps-overlay.ps-at-left .ps-indicator-left.ps-indicator-show,\nperfect-scrollbar.ps-show-active.ps-show-limits > .ps.ps--active-x > .ps-overlay.ps-at-right .ps-indicator-right.ps-indicator-show {\n opacity: 1;\n}\n", "/*\n * Container style\n */\n.ps {\n overflow: hidden !important;\n overflow-anchor: none;\n -ms-overflow-style: none;\n touch-action: auto;\n -ms-touch-action: auto;\n}\n\n/*\n * Scrollbar rail styles\n */\n.ps__rail-x {\n display: none;\n opacity: 0;\n transition: background-color .2s linear, opacity .2s linear;\n -webkit-transition: background-color .2s linear, opacity .2s linear;\n height: 15px;\n /* there must be 'bottom' or 'top' for ps__rail-x */\n bottom: 0px;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps__rail-y {\n display: none;\n opacity: 0;\n transition: background-color .2s linear, opacity .2s linear;\n -webkit-transition: background-color .2s linear, opacity .2s linear;\n width: 15px;\n /* there must be 'right' or 'left' for ps__rail-y */\n right: 0;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps--active-x > .ps__rail-x,\n.ps--active-y > .ps__rail-y {\n display: block;\n background-color: transparent;\n}\n\n.ps:hover > .ps__rail-x,\n.ps:hover > .ps__rail-y,\n.ps--focus > .ps__rail-x,\n.ps--focus > .ps__rail-y,\n.ps--scrolling-x > .ps__rail-x,\n.ps--scrolling-y > .ps__rail-y {\n opacity: 0.6;\n}\n\n.ps .ps__rail-x:hover,\n.ps .ps__rail-y:hover,\n.ps .ps__rail-x:focus,\n.ps .ps__rail-y:focus,\n.ps .ps__rail-x.ps--clicking,\n.ps .ps__rail-y.ps--clicking {\n background-color: #eee;\n opacity: 0.9;\n}\n\n/*\n * Scrollbar thumb styles\n */\n.ps__thumb-x {\n background-color: #aaa;\n border-radius: 6px;\n transition: background-color .2s linear, height .2s ease-in-out;\n -webkit-transition: background-color .2s linear, height .2s ease-in-out;\n height: 6px;\n /* there must be 'bottom' for ps__thumb-x */\n bottom: 2px;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps__thumb-y {\n background-color: #aaa;\n border-radius: 6px;\n transition: background-color .2s linear, width .2s ease-in-out;\n -webkit-transition: background-color .2s linear, width .2s ease-in-out;\n width: 6px;\n /* there must be 'right' for ps__thumb-y */\n right: 2px;\n /* please don't change 'position' */\n position: absolute;\n}\n\n.ps__rail-x:hover > .ps__thumb-x,\n.ps__rail-x:focus > .ps__thumb-x,\n.ps__rail-x.ps--clicking .ps__thumb-x {\n background-color: #999;\n height: 11px;\n}\n\n.ps__rail-y:hover > .ps__thumb-y,\n.ps__rail-y:focus > .ps__thumb-y,\n.ps__rail-y.ps--clicking .ps__thumb-y {\n background-color: #999;\n width: 11px;\n}\n\n/* MS supports */\n@supports (-ms-overflow-style: none) {\n .ps {\n overflow: auto !important;\n }\n}\n\n@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {\n .ps {\n overflow: auto !important;\n }\n}\n"]
1779 }] }
1780 ];
1781 /** @nocollapse */
1782 PerfectScrollbarComponent.ctorParameters = function () { return [
1783 { type: core.NgZone },
1784 { type: core.ChangeDetectorRef },
1785 { type: Object, decorators: [{ type: core.Inject, args: [core.PLATFORM_ID,] }] }
1786 ]; };
1787 PerfectScrollbarComponent.propDecorators = {
1788 disabled: [{ type: core.Input }],
1789 usePSClass: [{ type: core.Input }],
1790 autoPropagation: [{ type: core.HostBinding, args: ['class.ps-show-limits',] }, { type: core.Input }],
1791 scrollIndicators: [{ type: core.HostBinding, args: ['class.ps-show-active',] }, { type: core.Input }],
1792 config: [{ type: core.Input }],
1793 psScrollY: [{ type: core.Output }],
1794 psScrollX: [{ type: core.Output }],
1795 psScrollUp: [{ type: core.Output }],
1796 psScrollDown: [{ type: core.Output }],
1797 psScrollLeft: [{ type: core.Output }],
1798 psScrollRight: [{ type: core.Output }],
1799 psYReachEnd: [{ type: core.Output }],
1800 psYReachStart: [{ type: core.Output }],
1801 psXReachEnd: [{ type: core.Output }],
1802 psXReachStart: [{ type: core.Output }],
1803 directiveRef: [{ type: core.ViewChild, args: [PerfectScrollbarDirective,] }]
1804 };
1805 return PerfectScrollbarComponent;
1806 }());
1807
1808 /**
1809 * @fileoverview added by tsickle
1810 * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1811 */
1812 var PerfectScrollbarModule = /** @class */ (function () {
1813 function PerfectScrollbarModule() {
1814 }
1815 PerfectScrollbarModule.decorators = [
1816 { type: core.NgModule, args: [{
1817 imports: [common.CommonModule],
1818 declarations: [PerfectScrollbarComponent, PerfectScrollbarDirective],
1819 exports: [common.CommonModule, PerfectScrollbarComponent, PerfectScrollbarDirective]
1820 },] }
1821 ];
1822 return PerfectScrollbarModule;
1823 }());
1824
1825 exports.PerfectScrollbarComponent = PerfectScrollbarComponent;
1826 exports.PerfectScrollbarDirective = PerfectScrollbarDirective;
1827 exports.Geometry = Geometry;
1828 exports.Position = Position;
1829 exports.PERFECT_SCROLLBAR_CONFIG = PERFECT_SCROLLBAR_CONFIG;
1830 exports.PerfectScrollbarConfig = PerfectScrollbarConfig;
1831 exports.PerfectScrollbarModule = PerfectScrollbarModule;
1832
1833 Object.defineProperty(exports, '__esModule', { value: true });
1834
1835})));
1836//# sourceMappingURL=ngx-perfect-scrollbar.umd.js.map