@skyux/core 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/documentation.json +137 -134
- package/esm2020/lib/modules/adapter-service/adapter.service.mjs +11 -7
- package/esm2020/lib/modules/affix/affix.service.mjs +7 -3
- package/esm2020/lib/modules/numeric/numeric.pipe.mjs +4 -5
- package/esm2020/lib/modules/numeric/numeric.service.mjs +2 -2
- package/esm2020/lib/modules/resize-observer/resize-observer-media-query.service.mjs +42 -29
- package/esm2020/lib/modules/resize-observer/resize-observer.service.mjs +17 -11
- package/esm2020/lib/modules/scrollable-host/scrollable-host.service.mjs +29 -26
- package/esm2020/testing/core-testing.module.mjs +29 -0
- package/esm2020/testing/mock-media-query.service.mjs +3 -1
- package/esm2020/testing/mock-ui-config.service.mjs +1 -1
- package/esm2020/testing/public-api.mjs +2 -1
- package/fesm2015/skyux-core-testing.mjs +28 -2
- package/fesm2015/skyux-core-testing.mjs.map +1 -1
- package/fesm2015/skyux-core.mjs +102 -77
- package/fesm2015/skyux-core.mjs.map +1 -1
- package/fesm2020/skyux-core-testing.mjs +28 -2
- package/fesm2020/skyux-core-testing.mjs.map +1 -1
- package/fesm2020/skyux-core.mjs +102 -76
- package/fesm2020/skyux-core.mjs.map +1 -1
- package/lib/modules/adapter-service/adapter.service.d.ts +1 -1
- package/lib/modules/affix/affix.service.d.ts +1 -1
- package/lib/modules/numeric/numeric.pipe.d.ts +3 -4
- package/lib/modules/numeric/numeric.service.d.ts +1 -1
- package/lib/modules/resize-observer/resize-observer-media-query.service.d.ts +2 -4
- package/lib/modules/resize-observer/resize-observer.service.d.ts +1 -2
- package/lib/modules/scrollable-host/scrollable-host.service.d.ts +7 -4
- package/package.json +2 -2
- package/testing/core-testing.module.d.ts +6 -0
- package/testing/mock-ui-config.service.d.ts +2 -1
- package/testing/public-api.d.ts +1 -0
package/fesm2015/skyux-core.mjs
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
2
|
import { NgModule, Injectable, EventEmitter, Directive, Input, Output, Injector, ViewContainerRef, Component, ChangeDetectionStrategy, ViewChild, InjectionToken, Optional, Inject, Pipe, ElementRef } from '@angular/core';
|
3
|
+
import { __classPrivateFieldSet, __classPrivateFieldGet, __awaiter } from 'tslib';
|
3
4
|
import * as i4 from '@angular/common';
|
4
5
|
import { CommonModule } from '@angular/common';
|
5
6
|
import { Subject, fromEvent, BehaviorSubject, ReplaySubject, Observable, of } from 'rxjs';
|
6
7
|
import { takeUntil, debounceTime, finalize } from 'rxjs/operators';
|
7
|
-
import { __awaiter } from 'tslib';
|
8
8
|
import * as i1 from '@skyux/i18n';
|
9
9
|
import { getLibStringForLocale, SkyI18nModule, SKY_LIB_RESOURCES_PROVIDERS, SkyIntlNumberFormatStyle, SkyIntlNumberFormatter } from '@skyux/i18n';
|
10
10
|
import * as i3 from '@angular/router';
|
@@ -45,6 +45,7 @@ var SkyMediaBreakpoints;
|
|
45
45
|
SkyMediaBreakpoints[SkyMediaBreakpoints["lg"] = 4] = "lg";
|
46
46
|
})(SkyMediaBreakpoints || (SkyMediaBreakpoints = {}));
|
47
47
|
|
48
|
+
var _SkyCoreAdapterService_renderer;
|
48
49
|
const SKY_TABBABLE_SELECTOR = [
|
49
50
|
'a[href]',
|
50
51
|
'area[href]',
|
@@ -61,7 +62,8 @@ const SKY_TABBABLE_SELECTOR = [
|
|
61
62
|
class SkyCoreAdapterService {
|
62
63
|
constructor(rendererFactory) {
|
63
64
|
this.rendererFactory = rendererFactory;
|
64
|
-
|
65
|
+
_SkyCoreAdapterService_renderer.set(this, void 0);
|
66
|
+
__classPrivateFieldSet(this, _SkyCoreAdapterService_renderer, this.rendererFactory.createRenderer(undefined, null), "f");
|
65
67
|
}
|
66
68
|
/**
|
67
69
|
* Set the responsive container CSS class for a given element.
|
@@ -72,10 +74,10 @@ class SkyCoreAdapterService {
|
|
72
74
|
*/
|
73
75
|
setResponsiveContainerClass(elementRef, breakpoint) {
|
74
76
|
const nativeEl = elementRef.nativeElement;
|
75
|
-
this.
|
76
|
-
this.
|
77
|
-
this.
|
78
|
-
this.
|
77
|
+
__classPrivateFieldGet(this, _SkyCoreAdapterService_renderer, "f").removeClass(nativeEl, 'sky-responsive-container-xs');
|
78
|
+
__classPrivateFieldGet(this, _SkyCoreAdapterService_renderer, "f").removeClass(nativeEl, 'sky-responsive-container-sm');
|
79
|
+
__classPrivateFieldGet(this, _SkyCoreAdapterService_renderer, "f").removeClass(nativeEl, 'sky-responsive-container-md');
|
80
|
+
__classPrivateFieldGet(this, _SkyCoreAdapterService_renderer, "f").removeClass(nativeEl, 'sky-responsive-container-lg');
|
79
81
|
let newClass;
|
80
82
|
switch (breakpoint) {
|
81
83
|
case SkyMediaBreakpoints.xs: {
|
@@ -95,7 +97,7 @@ class SkyCoreAdapterService {
|
|
95
97
|
break;
|
96
98
|
}
|
97
99
|
}
|
98
|
-
this.
|
100
|
+
__classPrivateFieldGet(this, _SkyCoreAdapterService_renderer, "f").addClass(nativeEl, newClass);
|
99
101
|
}
|
100
102
|
/**
|
101
103
|
* This method temporarily enables/disables pointer events.
|
@@ -258,6 +260,7 @@ class SkyCoreAdapterService {
|
|
258
260
|
return hasBounds;
|
259
261
|
}
|
260
262
|
}
|
263
|
+
_SkyCoreAdapterService_renderer = new WeakMap();
|
261
264
|
SkyCoreAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
|
262
265
|
SkyCoreAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterService, providedIn: 'root' });
|
263
266
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterService, decorators: [{
|
@@ -716,18 +719,21 @@ class SkyAffixer {
|
|
716
719
|
}
|
717
720
|
}
|
718
721
|
|
722
|
+
var _SkyAffixService_renderer;
|
719
723
|
class SkyAffixService {
|
720
724
|
constructor(rendererFactory) {
|
721
|
-
|
725
|
+
_SkyAffixService_renderer.set(this, void 0);
|
726
|
+
__classPrivateFieldSet(this, _SkyAffixService_renderer, rendererFactory.createRenderer(undefined, null), "f");
|
722
727
|
}
|
723
728
|
/**
|
724
729
|
* Creates an instance of [[SkyAffixer]].
|
725
730
|
* @param affixed The element to be affixed.
|
726
731
|
*/
|
727
732
|
createAffixer(affixed) {
|
728
|
-
return new SkyAffixer(affixed.nativeElement, this
|
733
|
+
return new SkyAffixer(affixed.nativeElement, __classPrivateFieldGet(this, _SkyAffixService_renderer, "f"));
|
729
734
|
}
|
730
735
|
}
|
736
|
+
_SkyAffixService_renderer = new WeakMap();
|
731
737
|
SkyAffixService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
|
732
738
|
SkyAffixService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixService, providedIn: 'root' });
|
733
739
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixService, decorators: [{
|
@@ -1816,7 +1822,7 @@ class SkyNumericService {
|
|
1816
1822
|
return this._locale || 'en-US';
|
1817
1823
|
}
|
1818
1824
|
/**
|
1819
|
-
*
|
1825
|
+
* Formats a number based on the provided options.
|
1820
1826
|
* @param value The number to format.
|
1821
1827
|
* @param options Format options.
|
1822
1828
|
*/
|
@@ -1982,10 +1988,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
|
|
1982
1988
|
* M for millions, B for billions, and T for trillions. The pipe also formats for currency.
|
1983
1989
|
* Be sure you have a space after the two curly brackets opening the pipe and
|
1984
1990
|
* a space before the two curly brackets closing the pipe or it will not work.
|
1985
|
-
* Usage:
|
1986
|
-
* ```
|
1987
|
-
* {{ value | skyNumeric(config) }}
|
1988
|
-
* ```
|
1989
1991
|
*/
|
1990
1992
|
class SkyNumericPipe {
|
1991
1993
|
constructor(localeProvider, numericService, changeDetector) {
|
@@ -2006,6 +2008,9 @@ class SkyNumericPipe {
|
|
2006
2008
|
this.ngUnsubscribe.next();
|
2007
2009
|
this.ngUnsubscribe.complete();
|
2008
2010
|
}
|
2011
|
+
/**
|
2012
|
+
* Formats a number based on the provided options.
|
2013
|
+
*/
|
2009
2014
|
transform(value, config) {
|
2010
2015
|
const newCacheKey = (config ? JSON.stringify(config, Object.keys(config).sort()) : '') +
|
2011
2016
|
`${value}_${(config === null || config === void 0 ? void 0 : config.locale) || this.providerLocale}`;
|
@@ -2488,19 +2493,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
|
|
2488
2493
|
}]
|
2489
2494
|
}] });
|
2490
2495
|
|
2496
|
+
var _SkyResizeObserverService_resizeObserver, _SkyResizeObserverService_tracking;
|
2491
2497
|
/**
|
2492
2498
|
* Service to create rxjs observables for changes to the content box dimensions of elements.
|
2493
2499
|
*/
|
2494
2500
|
class SkyResizeObserverService {
|
2495
2501
|
constructor(zone) {
|
2496
2502
|
this.zone = zone;
|
2497
|
-
this
|
2498
|
-
this
|
2503
|
+
_SkyResizeObserverService_resizeObserver.set(this, void 0);
|
2504
|
+
_SkyResizeObserverService_tracking.set(this, []);
|
2505
|
+
__classPrivateFieldSet(this, _SkyResizeObserverService_resizeObserver, new ResizeObserver((entries) => {
|
2499
2506
|
entries.forEach((entry) => this.callback(entry));
|
2500
|
-
});
|
2507
|
+
}), "f");
|
2501
2508
|
}
|
2502
2509
|
ngOnDestroy() {
|
2503
|
-
this.
|
2510
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_resizeObserver, "f").disconnect();
|
2504
2511
|
}
|
2505
2512
|
/**
|
2506
2513
|
* Create rxjs observable to get size changes for an element ref.
|
@@ -2509,22 +2516,22 @@ class SkyResizeObserverService {
|
|
2509
2516
|
return this.observeAndTrack(element).subjectObservable;
|
2510
2517
|
}
|
2511
2518
|
observeAndTrack(element) {
|
2512
|
-
const checkTracking = this.
|
2519
|
+
const checkTracking = __classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f").findIndex((value) => {
|
2513
2520
|
return !value.subject.closed && value.element === element.nativeElement;
|
2514
2521
|
});
|
2515
2522
|
if (checkTracking === -1) {
|
2516
|
-
this.
|
2523
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_resizeObserver, "f").observe(element.nativeElement);
|
2517
2524
|
}
|
2518
2525
|
const subject = new Subject();
|
2519
2526
|
const subjectObservable = subject.pipe(finalize(() => {
|
2520
2527
|
// Are there any other tracking entries still watching this element?
|
2521
|
-
const checkTracking = this.
|
2528
|
+
const checkTracking = __classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f").findIndex((value) => {
|
2522
2529
|
return (value.subject !== subject &&
|
2523
2530
|
!value.subject.closed &&
|
2524
2531
|
value.element === element.nativeElement);
|
2525
2532
|
});
|
2526
2533
|
if (checkTracking === -1) {
|
2527
|
-
this.
|
2534
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_resizeObserver, "f").unobserve(element.nativeElement);
|
2528
2535
|
}
|
2529
2536
|
}));
|
2530
2537
|
const tracking = {
|
@@ -2532,15 +2539,17 @@ class SkyResizeObserverService {
|
|
2532
2539
|
subject,
|
2533
2540
|
subjectObservable,
|
2534
2541
|
};
|
2535
|
-
this.
|
2542
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f").push(tracking);
|
2536
2543
|
return tracking;
|
2537
2544
|
}
|
2538
2545
|
callback(entry) {
|
2539
|
-
this
|
2546
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f")
|
2540
2547
|
.filter((value) => !(value.subject.closed || value.subject.isStopped))
|
2541
2548
|
.forEach((value) => {
|
2542
2549
|
/* istanbul ignore else */
|
2543
2550
|
if (value.element === entry.target) {
|
2551
|
+
// Execute the callback within NgZone because Angular does not "monkey patch"
|
2552
|
+
// ResizeObserver like it does for other features in the DOM.
|
2544
2553
|
this.zone.run(() => {
|
2545
2554
|
value.subject.next(entry);
|
2546
2555
|
});
|
@@ -2548,6 +2557,7 @@ class SkyResizeObserverService {
|
|
2548
2557
|
});
|
2549
2558
|
}
|
2550
2559
|
}
|
2560
|
+
_SkyResizeObserverService_resizeObserver = new WeakMap(), _SkyResizeObserverService_tracking = new WeakMap();
|
2551
2561
|
SkyResizeObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
2552
2562
|
SkyResizeObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverService, providedIn: 'any' });
|
2553
2563
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverService, decorators: [{
|
@@ -2557,15 +2567,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImpor
|
|
2557
2567
|
}]
|
2558
2568
|
}], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
|
2559
2569
|
|
2570
|
+
var _SkyResizeObserverMediaQueryService_breakpoints, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, _SkyResizeObserverMediaQueryService_stopListening, _SkyResizeObserverMediaQueryService_target;
|
2560
2571
|
/**
|
2561
2572
|
* Acts like `SkyMediaQueryService` for a container element, emitting the same responsive breakpoints.
|
2562
2573
|
*/
|
2563
2574
|
class SkyResizeObserverMediaQueryService {
|
2564
2575
|
constructor(resizeObserverService) {
|
2565
2576
|
this.resizeObserverService = resizeObserverService;
|
2566
|
-
this
|
2577
|
+
_SkyResizeObserverMediaQueryService_breakpoints.set(this, [
|
2567
2578
|
{
|
2568
|
-
check: (width) => width <= 767,
|
2579
|
+
check: (width) => width > 0 && width <= 767,
|
2569
2580
|
name: SkyMediaBreakpoints.xs,
|
2570
2581
|
},
|
2571
2582
|
{
|
@@ -2580,11 +2591,12 @@ class SkyResizeObserverMediaQueryService {
|
|
2580
2591
|
check: (width) => width > 1199,
|
2581
2592
|
name: SkyMediaBreakpoints.lg,
|
2582
2593
|
},
|
2583
|
-
];
|
2584
|
-
this
|
2585
|
-
this
|
2586
|
-
|
2587
|
-
|
2594
|
+
]);
|
2595
|
+
_SkyResizeObserverMediaQueryService_currentBreakpointObservable.set(this, new ReplaySubject(1));
|
2596
|
+
_SkyResizeObserverMediaQueryService_stopListening.set(this, new Subject());
|
2597
|
+
_SkyResizeObserverMediaQueryService_target.set(this, void 0);
|
2598
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").subscribe(() => {
|
2599
|
+
__classPrivateFieldSet(this, _SkyResizeObserverMediaQueryService_target, undefined, "f");
|
2588
2600
|
this.updateBreakpoint(undefined);
|
2589
2601
|
});
|
2590
2602
|
}
|
@@ -2595,10 +2607,10 @@ class SkyResizeObserverMediaQueryService {
|
|
2595
2607
|
return this._currentBreakpoint;
|
2596
2608
|
}
|
2597
2609
|
ngOnDestroy() {
|
2598
|
-
this.
|
2610
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").next();
|
2599
2611
|
this._currentBreakpoint = undefined;
|
2600
|
-
this.
|
2601
|
-
this.
|
2612
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").complete();
|
2613
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, "f").complete();
|
2602
2614
|
}
|
2603
2615
|
/**
|
2604
2616
|
* @internal
|
@@ -2611,25 +2623,21 @@ class SkyResizeObserverMediaQueryService {
|
|
2611
2623
|
* time. Any previous subscriptions will be unsubscribed when a new element is observed.
|
2612
2624
|
*/
|
2613
2625
|
observe(element) {
|
2614
|
-
if (this
|
2615
|
-
if (this
|
2626
|
+
if (__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_target, "f")) {
|
2627
|
+
if (__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_target, "f") === element) {
|
2616
2628
|
return this;
|
2617
2629
|
}
|
2618
|
-
this.
|
2619
|
-
}
|
2620
|
-
this._target = element;
|
2621
|
-
const width = element.nativeElement.offsetWidth;
|
2622
|
-
if (width) {
|
2623
|
-
const breakpoint = this.checkBreakpoint(width);
|
2624
|
-
this.updateBreakpoint(breakpoint);
|
2630
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").next();
|
2625
2631
|
}
|
2632
|
+
__classPrivateFieldSet(this, _SkyResizeObserverMediaQueryService_target, element, "f");
|
2633
|
+
this.checkWidth(element);
|
2626
2634
|
this.resizeObserverService
|
2627
2635
|
.observe(element)
|
2628
|
-
.pipe(takeUntil(this
|
2636
|
+
.pipe(takeUntil(__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f")))
|
2629
2637
|
.subscribe((value) => {
|
2630
2638
|
const breakpoint = this.checkBreakpoint(value.contentRect.width);
|
2631
2639
|
/* istanbul ignore else */
|
2632
|
-
if (breakpoint !== this.
|
2640
|
+
if (breakpoint !== this.current) {
|
2633
2641
|
this.updateBreakpoint(breakpoint);
|
2634
2642
|
}
|
2635
2643
|
});
|
@@ -2639,25 +2647,39 @@ class SkyResizeObserverMediaQueryService {
|
|
2639
2647
|
* Stop watching the container element.
|
2640
2648
|
*/
|
2641
2649
|
unobserve() {
|
2642
|
-
this.
|
2650
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").next();
|
2643
2651
|
}
|
2644
2652
|
/**
|
2645
2653
|
* Subscribes to element size changes that cross breakpoints.
|
2646
2654
|
*/
|
2647
2655
|
subscribe(listener) {
|
2648
|
-
return this
|
2649
|
-
.pipe(takeUntil(this
|
2650
|
-
.subscribe(
|
2656
|
+
return __classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, "f")
|
2657
|
+
.pipe(takeUntil(__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f")))
|
2658
|
+
.subscribe((value) => {
|
2659
|
+
listener(value);
|
2660
|
+
});
|
2651
2661
|
}
|
2652
2662
|
updateBreakpoint(breakpoint) {
|
2653
2663
|
this._currentBreakpoint = breakpoint;
|
2654
|
-
this.
|
2664
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, "f").next(breakpoint);
|
2655
2665
|
}
|
2656
2666
|
checkBreakpoint(width) {
|
2657
|
-
|
2658
|
-
|
2667
|
+
const breakpoint = __classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_breakpoints, "f").find((breakpoint) => breakpoint.check(width));
|
2668
|
+
/* istanbul ignore else */
|
2669
|
+
if (breakpoint) {
|
2670
|
+
return breakpoint.name;
|
2671
|
+
}
|
2672
|
+
}
|
2673
|
+
checkWidth(element) {
|
2674
|
+
const width = element.nativeElement.offsetWidth || 0;
|
2675
|
+
const breakpoint = this.checkBreakpoint(width);
|
2676
|
+
/* istanbul ignore else */
|
2677
|
+
if (breakpoint !== this._currentBreakpoint) {
|
2678
|
+
this.updateBreakpoint(breakpoint);
|
2679
|
+
}
|
2659
2680
|
}
|
2660
2681
|
}
|
2682
|
+
_SkyResizeObserverMediaQueryService_breakpoints = new WeakMap(), _SkyResizeObserverMediaQueryService_currentBreakpointObservable = new WeakMap(), _SkyResizeObserverMediaQueryService_stopListening = new WeakMap(), _SkyResizeObserverMediaQueryService_target = new WeakMap();
|
2661
2683
|
SkyResizeObserverMediaQueryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverMediaQueryService, deps: [{ token: SkyResizeObserverService }], target: i0.ɵɵFactoryTarget.Injectable });
|
2662
2684
|
SkyResizeObserverMediaQueryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverMediaQueryService, providedIn: 'any' });
|
2663
2685
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverMediaQueryService, decorators: [{
|
@@ -2688,8 +2710,7 @@ class SkyScrollableHostService {
|
|
2688
2710
|
/**
|
2689
2711
|
* Returns an observable which emits the given element's current scrollable host
|
2690
2712
|
* @param elementRef The element whose scrollable host is being requested
|
2691
|
-
* @
|
2692
|
-
* @returns An observable which emits the current scrollable host
|
2713
|
+
* @returns An observable which emits the current scrollable host element.
|
2693
2714
|
* @internal
|
2694
2715
|
*/
|
2695
2716
|
watchScrollableHost(elementRef) {
|
@@ -2699,11 +2720,13 @@ class SkyScrollableHostService {
|
|
2699
2720
|
return new Observable((subscriber) => {
|
2700
2721
|
subscribers.push(subscriber);
|
2701
2722
|
let scrollableHost = this.findScrollableHost(elementRef.nativeElement);
|
2723
|
+
// Setup mutation observers only once, for all subscribers.
|
2702
2724
|
if (subscribers.length === 1) {
|
2703
2725
|
parentMutationObserver = this.mutationObserverSvc.create(() => {
|
2704
2726
|
const newScrollableHost = this.findScrollableHost(elementRef.nativeElement);
|
2727
|
+
// Reset observer if scrollable host changes.
|
2705
2728
|
if (newScrollableHost !== scrollableHost &&
|
2706
|
-
elementRef
|
2729
|
+
this.isElementVisible(elementRef)) {
|
2707
2730
|
scrollableHost = newScrollableHost;
|
2708
2731
|
this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
|
2709
2732
|
notifySubscribers(subscribers, scrollableHost);
|
@@ -2711,7 +2734,9 @@ class SkyScrollableHostService {
|
|
2711
2734
|
});
|
2712
2735
|
this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
|
2713
2736
|
documentHiddenElementMutationObserver = this.mutationObserverSvc.create(() => {
|
2714
|
-
if (scrollableHost && !elementRef
|
2737
|
+
if (scrollableHost && !this.isElementVisible(elementRef)) {
|
2738
|
+
// If the scrollable host is not visible, set it to undefined and unsubscribe from its mutation changes.
|
2739
|
+
// Then, observe the document element so that a new scrollable host can be found.
|
2715
2740
|
scrollableHost = undefined;
|
2716
2741
|
this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
|
2717
2742
|
notifySubscribers(subscribers, scrollableHost);
|
@@ -2719,10 +2744,11 @@ class SkyScrollableHostService {
|
|
2719
2744
|
});
|
2720
2745
|
this.observeDocumentHiddenElementChanges(documentHiddenElementMutationObserver);
|
2721
2746
|
}
|
2747
|
+
// Emit the scrollable host to the subscriber.
|
2722
2748
|
subscriber.next(scrollableHost);
|
2749
|
+
// Teardown callback for the subscription.
|
2723
2750
|
subscriber.add(() => {
|
2724
2751
|
const subIndex = subscribers.indexOf(subscriber);
|
2725
|
-
/* sanity check */
|
2726
2752
|
/* istanbul ignore else */
|
2727
2753
|
if (subIndex >= 0) {
|
2728
2754
|
subscribers.splice(subIndex, 1);
|
@@ -2737,7 +2763,6 @@ class SkyScrollableHostService {
|
|
2737
2763
|
/**
|
2738
2764
|
* Returns an observable which emits whenever the element's scrollable host emits a scroll event. The observable will always emit the scroll events from the elements current scrollable host and will update based on any scrollable host changes. The observable will also emit once whenever the scrollable host changes.
|
2739
2765
|
* @param elementRef The element whose scrollable host scroll events are being requested
|
2740
|
-
* @param completionObservable An observable which alerts the internal observers that they should complete
|
2741
2766
|
* @returns An observable which emits when the elements scrollable host is scrolled or is changed
|
2742
2767
|
*/
|
2743
2768
|
watchScrollableHostScrollEvents(elementRef) {
|
@@ -2748,6 +2773,7 @@ class SkyScrollableHostService {
|
|
2748
2773
|
let scrollEventSubscription;
|
2749
2774
|
return new Observable((subscriber) => {
|
2750
2775
|
subscribers.push(subscriber);
|
2776
|
+
// Setup mutation observers only once, for all subscribers.
|
2751
2777
|
if (subscribers.length === 1) {
|
2752
2778
|
scrollableHostSubscription = this.watchScrollableHost(elementRef).subscribe((newScrollableHost) => {
|
2753
2779
|
newScrollableHostObservable.next();
|
@@ -2757,6 +2783,8 @@ class SkyScrollableHostService {
|
|
2757
2783
|
}
|
2758
2784
|
scrollableHost = newScrollableHost;
|
2759
2785
|
newScrollableHostObservable = new Subject();
|
2786
|
+
// Only subscribe to scroll events if the host element is defined.
|
2787
|
+
/* istanbul ignore else */
|
2760
2788
|
if (newScrollableHost) {
|
2761
2789
|
scrollEventSubscription = fromEvent(newScrollableHost, 'scroll')
|
2762
2790
|
.pipe(takeUntil(newScrollableHostObservable))
|
@@ -2766,9 +2794,9 @@ class SkyScrollableHostService {
|
|
2766
2794
|
}
|
2767
2795
|
});
|
2768
2796
|
}
|
2797
|
+
// Teardown callback for the subscription.
|
2769
2798
|
subscriber.add(() => {
|
2770
2799
|
const subIndex = subscribers.indexOf(subscriber);
|
2771
|
-
/* sanity check */
|
2772
2800
|
/* istanbul ignore else */
|
2773
2801
|
if (subIndex >= 0) {
|
2774
2802
|
subscribers.splice(subIndex, 1);
|
@@ -2785,7 +2813,6 @@ class SkyScrollableHostService {
|
|
2785
2813
|
const regex = /(auto|scroll)/;
|
2786
2814
|
const windowObj = this.windowRef.nativeWindow;
|
2787
2815
|
const bodyObj = windowObj.document.body;
|
2788
|
-
/* Sanity check */
|
2789
2816
|
if (!element) {
|
2790
2817
|
return windowObj;
|
2791
2818
|
}
|
@@ -2793,7 +2820,7 @@ class SkyScrollableHostService {
|
|
2793
2820
|
let parent = element;
|
2794
2821
|
do {
|
2795
2822
|
parent = parent.parentNode;
|
2796
|
-
|
2823
|
+
// Return `window` if the parent element has been removed from the DOM.
|
2797
2824
|
if (!(parent instanceof HTMLElement)) {
|
2798
2825
|
return windowObj;
|
2799
2826
|
}
|
@@ -2816,22 +2843,20 @@ class SkyScrollableHostService {
|
|
2816
2843
|
}
|
2817
2844
|
observeForScrollableHostChanges(element, mutationObserver) {
|
2818
2845
|
mutationObserver.disconnect();
|
2819
|
-
|
2820
|
-
|
2821
|
-
|
2822
|
-
|
2823
|
-
|
2824
|
-
|
2825
|
-
|
2826
|
-
|
2827
|
-
|
2828
|
-
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
});
|
2834
|
-
}
|
2846
|
+
const target = element instanceof HTMLElement ? element : document.documentElement;
|
2847
|
+
mutationObserver.observe(target, {
|
2848
|
+
attributes: true,
|
2849
|
+
attributeFilter: ['class', 'style'],
|
2850
|
+
childList: true,
|
2851
|
+
subtree: true,
|
2852
|
+
});
|
2853
|
+
}
|
2854
|
+
/**
|
2855
|
+
* Determines if an element is "visible" in the DOM.
|
2856
|
+
* @see https://stackoverflow.com/a/11639664/6178885
|
2857
|
+
*/
|
2858
|
+
isElementVisible(elementRef) {
|
2859
|
+
return elementRef.nativeElement.offsetParent;
|
2835
2860
|
}
|
2836
2861
|
}
|
2837
2862
|
SkyScrollableHostService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyScrollableHostService, deps: [{ token: MutationObserverService }, { token: SkyAppWindowRef }], target: i0.ɵɵFactoryTarget.Injectable });
|