@skyux/core 5.9.7 → 5.10.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/bundles/skyux-core-testing.umd.js +30 -0
- package/bundles/skyux-core.umd.js +1000 -980
- package/documentation.json +104 -104
- package/esm2015/lib/modules/adapter-service/adapter.service.js +10 -6
- package/esm2015/lib/modules/adapter-service/adapter.service.js.map +1 -1
- package/esm2015/lib/modules/affix/affix.service.js +6 -2
- package/esm2015/lib/modules/affix/affix.service.js.map +1 -1
- package/esm2015/lib/modules/resize-observer/resize-observer-media-query.service.js +28 -21
- package/esm2015/lib/modules/resize-observer/resize-observer-media-query.service.js.map +1 -1
- package/esm2015/lib/modules/resize-observer/resize-observer.service.js +16 -10
- package/esm2015/lib/modules/resize-observer/resize-observer.service.js.map +1 -1
- package/esm2015/lib/modules/scrollable-host/scrollable-host.service.js +28 -25
- package/esm2015/lib/modules/scrollable-host/scrollable-host.service.js.map +1 -1
- package/esm2015/testing/core-testing.module.js +29 -0
- package/esm2015/testing/core-testing.module.js.map +1 -0
- package/esm2015/testing/mock-media-query.service.js +2 -0
- package/esm2015/testing/mock-media-query.service.js.map +1 -1
- package/esm2015/testing/mock-ui-config.service.js.map +1 -1
- package/esm2015/testing/public-api.js +1 -0
- package/esm2015/testing/public-api.js.map +1 -1
- package/fesm2015/skyux-core-testing.js +28 -2
- package/fesm2015/skyux-core-testing.js.map +1 -1
- package/fesm2015/skyux-core.js +85 -64
- package/fesm2015/skyux-core.js.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/resize-observer/resize-observer-media-query.service.d.ts +1 -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.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
2
|
import { NgModule, Injectable, EventEmitter, Directive, Input, Output, Injector, ViewContainerRef, Component, ChangeDetectionStrategy, ViewChild, Pipe, ElementRef, Optional } from '@angular/core';
|
3
|
+
import { __classPrivateFieldSet, __classPrivateFieldGet } 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';
|
@@ -44,6 +45,7 @@ var SkyMediaBreakpoints;
|
|
44
45
|
SkyMediaBreakpoints[SkyMediaBreakpoints["lg"] = 4] = "lg";
|
45
46
|
})(SkyMediaBreakpoints || (SkyMediaBreakpoints = {}));
|
46
47
|
|
48
|
+
var _SkyCoreAdapterService_renderer;
|
47
49
|
const SKY_TABBABLE_SELECTOR = [
|
48
50
|
'a[href]',
|
49
51
|
'area[href]',
|
@@ -60,7 +62,8 @@ const SKY_TABBABLE_SELECTOR = [
|
|
60
62
|
class SkyCoreAdapterService {
|
61
63
|
constructor(rendererFactory) {
|
62
64
|
this.rendererFactory = rendererFactory;
|
63
|
-
|
65
|
+
_SkyCoreAdapterService_renderer.set(this, void 0);
|
66
|
+
__classPrivateFieldSet(this, _SkyCoreAdapterService_renderer, this.rendererFactory.createRenderer(undefined, null), "f");
|
64
67
|
}
|
65
68
|
/**
|
66
69
|
* Set the responsive container CSS class for a given element.
|
@@ -71,10 +74,10 @@ class SkyCoreAdapterService {
|
|
71
74
|
*/
|
72
75
|
setResponsiveContainerClass(elementRef, breakpoint) {
|
73
76
|
const nativeEl = elementRef.nativeElement;
|
74
|
-
this.
|
75
|
-
this.
|
76
|
-
this.
|
77
|
-
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');
|
78
81
|
let newClass;
|
79
82
|
switch (breakpoint) {
|
80
83
|
case SkyMediaBreakpoints.xs: {
|
@@ -94,7 +97,7 @@ class SkyCoreAdapterService {
|
|
94
97
|
break;
|
95
98
|
}
|
96
99
|
}
|
97
|
-
this.
|
100
|
+
__classPrivateFieldGet(this, _SkyCoreAdapterService_renderer, "f").addClass(nativeEl, newClass);
|
98
101
|
}
|
99
102
|
/**
|
100
103
|
* This method temporarily enables/disables pointer events.
|
@@ -258,6 +261,7 @@ class SkyCoreAdapterService {
|
|
258
261
|
return hasBounds;
|
259
262
|
}
|
260
263
|
}
|
264
|
+
_SkyCoreAdapterService_renderer = new WeakMap();
|
261
265
|
SkyCoreAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyCoreAdapterService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
|
262
266
|
SkyCoreAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyCoreAdapterService, providedIn: 'root' });
|
263
267
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyCoreAdapterService, decorators: [{
|
@@ -719,18 +723,21 @@ class SkyAffixer {
|
|
719
723
|
}
|
720
724
|
}
|
721
725
|
|
726
|
+
var _SkyAffixService_renderer;
|
722
727
|
class SkyAffixService {
|
723
728
|
constructor(rendererFactory) {
|
724
|
-
|
729
|
+
_SkyAffixService_renderer.set(this, void 0);
|
730
|
+
__classPrivateFieldSet(this, _SkyAffixService_renderer, rendererFactory.createRenderer(undefined, null), "f");
|
725
731
|
}
|
726
732
|
/**
|
727
733
|
* Creates an instance of [[SkyAffixer]].
|
728
734
|
* @param affixed The element to be affixed.
|
729
735
|
*/
|
730
736
|
createAffixer(affixed) {
|
731
|
-
return new SkyAffixer(affixed.nativeElement, this
|
737
|
+
return new SkyAffixer(affixed.nativeElement, __classPrivateFieldGet(this, _SkyAffixService_renderer, "f"));
|
732
738
|
}
|
733
739
|
}
|
740
|
+
_SkyAffixService_renderer = new WeakMap();
|
734
741
|
SkyAffixService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyAffixService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
|
735
742
|
SkyAffixService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyAffixService, providedIn: 'root' });
|
736
743
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyAffixService, decorators: [{
|
@@ -2416,19 +2423,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
2416
2423
|
}]
|
2417
2424
|
}] });
|
2418
2425
|
|
2426
|
+
var _SkyResizeObserverService_resizeObserver, _SkyResizeObserverService_tracking;
|
2419
2427
|
/**
|
2420
2428
|
* Service to create rxjs observables for changes to the content box dimensions of elements.
|
2421
2429
|
*/
|
2422
2430
|
class SkyResizeObserverService {
|
2423
2431
|
constructor(zone) {
|
2424
2432
|
this.zone = zone;
|
2425
|
-
this
|
2426
|
-
this
|
2433
|
+
_SkyResizeObserverService_resizeObserver.set(this, void 0);
|
2434
|
+
_SkyResizeObserverService_tracking.set(this, []);
|
2435
|
+
__classPrivateFieldSet(this, _SkyResizeObserverService_resizeObserver, new ResizeObserver((entries) => {
|
2427
2436
|
entries.forEach((entry) => this.callback(entry));
|
2428
|
-
});
|
2437
|
+
}), "f");
|
2429
2438
|
}
|
2430
2439
|
ngOnDestroy() {
|
2431
|
-
this.
|
2440
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_resizeObserver, "f").disconnect();
|
2432
2441
|
}
|
2433
2442
|
/**
|
2434
2443
|
* Create rxjs observable to get size changes for an element ref.
|
@@ -2437,22 +2446,22 @@ class SkyResizeObserverService {
|
|
2437
2446
|
return this.observeAndTrack(element).subjectObservable;
|
2438
2447
|
}
|
2439
2448
|
observeAndTrack(element) {
|
2440
|
-
const checkTracking = this.
|
2449
|
+
const checkTracking = __classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f").findIndex((value) => {
|
2441
2450
|
return !value.subject.closed && value.element === element.nativeElement;
|
2442
2451
|
});
|
2443
2452
|
if (checkTracking === -1) {
|
2444
|
-
this.
|
2453
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_resizeObserver, "f").observe(element.nativeElement);
|
2445
2454
|
}
|
2446
2455
|
const subject = new Subject();
|
2447
2456
|
const subjectObservable = subject.pipe(finalize(() => {
|
2448
2457
|
// Are there any other tracking entries still watching this element?
|
2449
|
-
const checkTracking = this.
|
2458
|
+
const checkTracking = __classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f").findIndex((value) => {
|
2450
2459
|
return (value.subject !== subject &&
|
2451
2460
|
!value.subject.closed &&
|
2452
2461
|
value.element === element.nativeElement);
|
2453
2462
|
});
|
2454
2463
|
if (checkTracking === -1) {
|
2455
|
-
this.
|
2464
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_resizeObserver, "f").unobserve(element.nativeElement);
|
2456
2465
|
}
|
2457
2466
|
}));
|
2458
2467
|
const tracking = {
|
@@ -2460,15 +2469,17 @@ class SkyResizeObserverService {
|
|
2460
2469
|
subject,
|
2461
2470
|
subjectObservable,
|
2462
2471
|
};
|
2463
|
-
this.
|
2472
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f").push(tracking);
|
2464
2473
|
return tracking;
|
2465
2474
|
}
|
2466
2475
|
callback(entry) {
|
2467
|
-
this
|
2476
|
+
__classPrivateFieldGet(this, _SkyResizeObserverService_tracking, "f")
|
2468
2477
|
.filter((value) => !(value.subject.closed || value.subject.isStopped))
|
2469
2478
|
.forEach((value) => {
|
2470
2479
|
/* istanbul ignore else */
|
2471
2480
|
if (value.element === entry.target) {
|
2481
|
+
// Execute the callback within NgZone because Angular does not "monkey patch"
|
2482
|
+
// ResizeObserver like it does for other features in the DOM.
|
2472
2483
|
this.zone.run(() => {
|
2473
2484
|
value.subject.next(entry);
|
2474
2485
|
});
|
@@ -2476,6 +2487,7 @@ class SkyResizeObserverService {
|
|
2476
2487
|
});
|
2477
2488
|
}
|
2478
2489
|
}
|
2490
|
+
_SkyResizeObserverService_resizeObserver = new WeakMap(), _SkyResizeObserverService_tracking = new WeakMap();
|
2479
2491
|
SkyResizeObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyResizeObserverService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
2480
2492
|
SkyResizeObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyResizeObserverService, providedIn: 'any' });
|
2481
2493
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyResizeObserverService, decorators: [{
|
@@ -2485,13 +2497,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
|
|
2485
2497
|
}]
|
2486
2498
|
}], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
|
2487
2499
|
|
2500
|
+
var _SkyResizeObserverMediaQueryService_breakpoints, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, _SkyResizeObserverMediaQueryService_stopListening, _SkyResizeObserverMediaQueryService_target;
|
2488
2501
|
/**
|
2489
2502
|
* Acts like `SkyMediaQueryService` for a container element, emitting the same responsive breakpoints.
|
2490
2503
|
*/
|
2491
2504
|
class SkyResizeObserverMediaQueryService {
|
2492
2505
|
constructor(resizeObserverService) {
|
2493
2506
|
this.resizeObserverService = resizeObserverService;
|
2494
|
-
this
|
2507
|
+
_SkyResizeObserverMediaQueryService_breakpoints.set(this, [
|
2495
2508
|
{
|
2496
2509
|
check: (width) => width > 0 && width <= 767,
|
2497
2510
|
name: SkyMediaBreakpoints.xs,
|
@@ -2508,11 +2521,12 @@ class SkyResizeObserverMediaQueryService {
|
|
2508
2521
|
check: (width) => width > 1199,
|
2509
2522
|
name: SkyMediaBreakpoints.lg,
|
2510
2523
|
},
|
2511
|
-
];
|
2512
|
-
this
|
2513
|
-
this
|
2514
|
-
|
2515
|
-
|
2524
|
+
]);
|
2525
|
+
_SkyResizeObserverMediaQueryService_currentBreakpointObservable.set(this, new ReplaySubject(1));
|
2526
|
+
_SkyResizeObserverMediaQueryService_stopListening.set(this, new Subject());
|
2527
|
+
_SkyResizeObserverMediaQueryService_target.set(this, void 0);
|
2528
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").subscribe(() => {
|
2529
|
+
__classPrivateFieldSet(this, _SkyResizeObserverMediaQueryService_target, undefined, "f");
|
2516
2530
|
this.updateBreakpoint(undefined);
|
2517
2531
|
});
|
2518
2532
|
}
|
@@ -2523,10 +2537,10 @@ class SkyResizeObserverMediaQueryService {
|
|
2523
2537
|
return this._currentBreakpoint;
|
2524
2538
|
}
|
2525
2539
|
ngOnDestroy() {
|
2526
|
-
this.
|
2540
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").next();
|
2527
2541
|
this._currentBreakpoint = undefined;
|
2528
|
-
this.
|
2529
|
-
this.
|
2542
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").complete();
|
2543
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, "f").complete();
|
2530
2544
|
}
|
2531
2545
|
/**
|
2532
2546
|
* @internal
|
@@ -2539,21 +2553,21 @@ class SkyResizeObserverMediaQueryService {
|
|
2539
2553
|
* time. Any previous subscriptions will be unsubscribed when a new element is observed.
|
2540
2554
|
*/
|
2541
2555
|
observe(element) {
|
2542
|
-
if (this
|
2543
|
-
if (this
|
2556
|
+
if (__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_target, "f")) {
|
2557
|
+
if (__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_target, "f") === element) {
|
2544
2558
|
return this;
|
2545
2559
|
}
|
2546
|
-
this.
|
2560
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").next();
|
2547
2561
|
}
|
2548
|
-
this
|
2562
|
+
__classPrivateFieldSet(this, _SkyResizeObserverMediaQueryService_target, element, "f");
|
2549
2563
|
this.checkWidth(element);
|
2550
2564
|
this.resizeObserverService
|
2551
2565
|
.observe(element)
|
2552
|
-
.pipe(takeUntil(this
|
2566
|
+
.pipe(takeUntil(__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f")))
|
2553
2567
|
.subscribe((value) => {
|
2554
2568
|
const breakpoint = this.checkBreakpoint(value.contentRect.width);
|
2555
2569
|
/* istanbul ignore else */
|
2556
|
-
if (breakpoint !== this.
|
2570
|
+
if (breakpoint !== this.current) {
|
2557
2571
|
this.updateBreakpoint(breakpoint);
|
2558
2572
|
}
|
2559
2573
|
});
|
@@ -2563,25 +2577,28 @@ class SkyResizeObserverMediaQueryService {
|
|
2563
2577
|
* Stop watching the container element.
|
2564
2578
|
*/
|
2565
2579
|
unobserve() {
|
2566
|
-
this.
|
2580
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f").next();
|
2567
2581
|
}
|
2568
2582
|
/**
|
2569
2583
|
* Subscribes to element size changes that cross breakpoints.
|
2570
2584
|
*/
|
2571
2585
|
subscribe(listener) {
|
2572
|
-
return this
|
2573
|
-
.pipe(takeUntil(this
|
2586
|
+
return __classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, "f")
|
2587
|
+
.pipe(takeUntil(__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_stopListening, "f")))
|
2574
2588
|
.subscribe((value) => {
|
2575
2589
|
listener(value);
|
2576
2590
|
});
|
2577
2591
|
}
|
2578
2592
|
updateBreakpoint(breakpoint) {
|
2579
2593
|
this._currentBreakpoint = breakpoint;
|
2580
|
-
this.
|
2594
|
+
__classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_currentBreakpointObservable, "f").next(breakpoint);
|
2581
2595
|
}
|
2582
2596
|
checkBreakpoint(width) {
|
2583
|
-
|
2584
|
-
|
2597
|
+
const breakpoint = __classPrivateFieldGet(this, _SkyResizeObserverMediaQueryService_breakpoints, "f").find((breakpoint) => breakpoint.check(width));
|
2598
|
+
/* istanbul ignore else */
|
2599
|
+
if (breakpoint) {
|
2600
|
+
return breakpoint.name;
|
2601
|
+
}
|
2585
2602
|
}
|
2586
2603
|
checkWidth(element) {
|
2587
2604
|
const width = element.nativeElement.offsetWidth || 0;
|
@@ -2592,6 +2609,7 @@ class SkyResizeObserverMediaQueryService {
|
|
2592
2609
|
}
|
2593
2610
|
}
|
2594
2611
|
}
|
2612
|
+
_SkyResizeObserverMediaQueryService_breakpoints = new WeakMap(), _SkyResizeObserverMediaQueryService_currentBreakpointObservable = new WeakMap(), _SkyResizeObserverMediaQueryService_stopListening = new WeakMap(), _SkyResizeObserverMediaQueryService_target = new WeakMap();
|
2595
2613
|
SkyResizeObserverMediaQueryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyResizeObserverMediaQueryService, deps: [{ token: SkyResizeObserverService }], target: i0.ɵɵFactoryTarget.Injectable });
|
2596
2614
|
SkyResizeObserverMediaQueryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyResizeObserverMediaQueryService, providedIn: 'any' });
|
2597
2615
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyResizeObserverMediaQueryService, decorators: [{
|
@@ -2622,8 +2640,7 @@ class SkyScrollableHostService {
|
|
2622
2640
|
/**
|
2623
2641
|
* Returns an observable which emits the given element's current scrollable host
|
2624
2642
|
* @param elementRef The element whose scrollable host is being requested
|
2625
|
-
* @
|
2626
|
-
* @returns An observable which emits the current scrollable host
|
2643
|
+
* @returns An observable which emits the current scrollable host element.
|
2627
2644
|
* @internal
|
2628
2645
|
*/
|
2629
2646
|
watchScrollableHost(elementRef) {
|
@@ -2633,11 +2650,13 @@ class SkyScrollableHostService {
|
|
2633
2650
|
return new Observable((subscriber) => {
|
2634
2651
|
subscribers.push(subscriber);
|
2635
2652
|
let scrollableHost = this.findScrollableHost(elementRef.nativeElement);
|
2653
|
+
// Setup mutation observers only once, for all subscribers.
|
2636
2654
|
if (subscribers.length === 1) {
|
2637
2655
|
parentMutationObserver = this.mutationObserverSvc.create(() => {
|
2638
2656
|
const newScrollableHost = this.findScrollableHost(elementRef.nativeElement);
|
2657
|
+
// Reset observer if scrollable host changes.
|
2639
2658
|
if (newScrollableHost !== scrollableHost &&
|
2640
|
-
elementRef
|
2659
|
+
this.isElementVisible(elementRef)) {
|
2641
2660
|
scrollableHost = newScrollableHost;
|
2642
2661
|
this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
|
2643
2662
|
notifySubscribers(subscribers, scrollableHost);
|
@@ -2645,7 +2664,9 @@ class SkyScrollableHostService {
|
|
2645
2664
|
});
|
2646
2665
|
this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
|
2647
2666
|
documentHiddenElementMutationObserver = this.mutationObserverSvc.create(() => {
|
2648
|
-
if (scrollableHost && !elementRef
|
2667
|
+
if (scrollableHost && !this.isElementVisible(elementRef)) {
|
2668
|
+
// If the scrollable host is not visible, set it to undefined and unsubscribe from its mutation changes.
|
2669
|
+
// Then, observe the document element so that a new scrollable host can be found.
|
2649
2670
|
scrollableHost = undefined;
|
2650
2671
|
this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
|
2651
2672
|
notifySubscribers(subscribers, scrollableHost);
|
@@ -2653,10 +2674,11 @@ class SkyScrollableHostService {
|
|
2653
2674
|
});
|
2654
2675
|
this.observeDocumentHiddenElementChanges(documentHiddenElementMutationObserver);
|
2655
2676
|
}
|
2677
|
+
// Emit the scrollable host to the subscriber.
|
2656
2678
|
subscriber.next(scrollableHost);
|
2679
|
+
// Teardown callback for the subscription.
|
2657
2680
|
subscriber.add(() => {
|
2658
2681
|
const subIndex = subscribers.indexOf(subscriber);
|
2659
|
-
/* sanity check */
|
2660
2682
|
/* istanbul ignore else */
|
2661
2683
|
if (subIndex >= 0) {
|
2662
2684
|
subscribers.splice(subIndex, 1);
|
@@ -2671,7 +2693,6 @@ class SkyScrollableHostService {
|
|
2671
2693
|
/**
|
2672
2694
|
* 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.
|
2673
2695
|
* @param elementRef The element whose scrollable host scroll events are being requested
|
2674
|
-
* @param completionObservable An observable which alerts the internal observers that they should complete
|
2675
2696
|
* @returns An observable which emits when the elements scrollable host is scrolled or is changed
|
2676
2697
|
*/
|
2677
2698
|
watchScrollableHostScrollEvents(elementRef) {
|
@@ -2682,6 +2703,7 @@ class SkyScrollableHostService {
|
|
2682
2703
|
let scrollEventSubscription;
|
2683
2704
|
return new Observable((subscriber) => {
|
2684
2705
|
subscribers.push(subscriber);
|
2706
|
+
// Setup mutation observers only once, for all subscribers.
|
2685
2707
|
if (subscribers.length === 1) {
|
2686
2708
|
scrollableHostSubscription = this.watchScrollableHost(elementRef).subscribe((newScrollableHost) => {
|
2687
2709
|
newScrollableHostObservable.next();
|
@@ -2691,6 +2713,8 @@ class SkyScrollableHostService {
|
|
2691
2713
|
}
|
2692
2714
|
scrollableHost = newScrollableHost;
|
2693
2715
|
newScrollableHostObservable = new Subject();
|
2716
|
+
// Only subscribe to scroll events if the host element is defined.
|
2717
|
+
/* istanbul ignore else */
|
2694
2718
|
if (newScrollableHost) {
|
2695
2719
|
scrollEventSubscription = fromEvent(newScrollableHost, 'scroll')
|
2696
2720
|
.pipe(takeUntil(newScrollableHostObservable))
|
@@ -2700,9 +2724,9 @@ class SkyScrollableHostService {
|
|
2700
2724
|
}
|
2701
2725
|
});
|
2702
2726
|
}
|
2727
|
+
// Teardown callback for the subscription.
|
2703
2728
|
subscriber.add(() => {
|
2704
2729
|
const subIndex = subscribers.indexOf(subscriber);
|
2705
|
-
/* sanity check */
|
2706
2730
|
/* istanbul ignore else */
|
2707
2731
|
if (subIndex >= 0) {
|
2708
2732
|
subscribers.splice(subIndex, 1);
|
@@ -2719,7 +2743,6 @@ class SkyScrollableHostService {
|
|
2719
2743
|
const regex = /(auto|scroll)/;
|
2720
2744
|
const windowObj = this.windowRef.nativeWindow;
|
2721
2745
|
const bodyObj = windowObj.document.body;
|
2722
|
-
/* Sanity check */
|
2723
2746
|
if (!element) {
|
2724
2747
|
return windowObj;
|
2725
2748
|
}
|
@@ -2727,7 +2750,7 @@ class SkyScrollableHostService {
|
|
2727
2750
|
let parent = element;
|
2728
2751
|
do {
|
2729
2752
|
parent = parent.parentNode;
|
2730
|
-
|
2753
|
+
// Return `window` if the parent element has been removed from the DOM.
|
2731
2754
|
if (!(parent instanceof HTMLElement)) {
|
2732
2755
|
return windowObj;
|
2733
2756
|
}
|
@@ -2750,22 +2773,20 @@ class SkyScrollableHostService {
|
|
2750
2773
|
}
|
2751
2774
|
observeForScrollableHostChanges(element, mutationObserver) {
|
2752
2775
|
mutationObserver.disconnect();
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
});
|
2768
|
-
}
|
2776
|
+
const target = element instanceof HTMLElement ? element : document.documentElement;
|
2777
|
+
mutationObserver.observe(target, {
|
2778
|
+
attributes: true,
|
2779
|
+
attributeFilter: ['class', 'style'],
|
2780
|
+
childList: true,
|
2781
|
+
subtree: true,
|
2782
|
+
});
|
2783
|
+
}
|
2784
|
+
/**
|
2785
|
+
* Determines if an element is "visible" in the DOM.
|
2786
|
+
* @see https://stackoverflow.com/a/11639664/6178885
|
2787
|
+
*/
|
2788
|
+
isElementVisible(elementRef) {
|
2789
|
+
return elementRef.nativeElement.offsetParent;
|
2769
2790
|
}
|
2770
2791
|
}
|
2771
2792
|
SkyScrollableHostService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyScrollableHostService, deps: [{ token: MutationObserverService }, { token: SkyAppWindowRef }], target: i0.ɵɵFactoryTarget.Injectable });
|