@scion/components 15.0.1 → 16.0.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/dimension/dimension.directive.d.ts +2 -2
- package/esm2022/dimension/dimension.directive.mjs +84 -0
- package/esm2022/dimension/dimension.module.mjs +39 -0
- package/esm2022/sashbox/element-ref.directive.mjs +28 -0
- package/esm2022/sashbox/sash-initializer.directive.mjs +33 -0
- package/esm2022/sashbox/sash.directive.mjs +145 -0
- package/esm2022/sashbox/sashbox.component.mjs +279 -0
- package/esm2022/sashbox/sashbox.module.mjs +70 -0
- package/esm2022/splitter/splitter.component.mjs +228 -0
- package/esm2022/splitter/splitter.module.mjs +43 -0
- package/esm2022/throbber/ellipsis-throbber/ellipsis-throbber.component.mjs +26 -0
- package/esm2022/throbber/ripple-throbber/ripple-throbber.component.mjs +26 -0
- package/esm2022/throbber/roller-throbber/roller-throbber.component.mjs +26 -0
- package/esm2022/throbber/spinner-throbber/spinner-throbber.component.mjs +27 -0
- package/esm2022/throbber/throbber.component.mjs +68 -0
- package/esm2022/throbber/throbber.module.mjs +49 -0
- package/esm2022/viewport/native-scrollbar-track-size-provider.service.mjs +115 -0
- package/esm2022/viewport/scrollable.directive.mjs +94 -0
- package/esm2022/viewport/scrollbar/scrollbar.component.mjs +323 -0
- package/esm2022/viewport/viewport.component.mjs +282 -0
- package/esm2022/viewport/viewport.module.mjs +51 -0
- package/{fesm2015 → fesm2022}/scion-components-dimension.mjs +12 -7
- package/{fesm2015 → fesm2022}/scion-components-dimension.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/scion-components-sashbox.mjs +47 -42
- package/{fesm2020 → fesm2022}/scion-components-sashbox.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/scion-components-splitter.mjs +22 -17
- package/{fesm2020 → fesm2022}/scion-components-splitter.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/scion-components-throbber.mjs +28 -23
- package/{fesm2015 → fesm2022}/scion-components-throbber.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/scion-components-viewport.mjs +65 -60
- package/{fesm2015 → fesm2022}/scion-components-viewport.mjs.map +1 -1
- package/package.json +27 -43
- package/sashbox/sash-initializer.directive.d.ts +1 -1
- package/sashbox/sash.directive.d.ts +1 -1
- package/sashbox/sashbox.component.d.ts +1 -1
- package/splitter/splitter.component.d.ts +1 -1
- package/throbber/throbber.component.d.ts +1 -1
- package/viewport/_scrollbar.scss +1 -1
- package/viewport/scrollable.directive.d.ts +1 -1
- package/viewport/scrollbar/scrollbar.component.d.ts +1 -1
- package/viewport/viewport.component.d.ts +2 -2
- package/esm2020/dimension/dimension.directive.mjs +0 -83
- package/esm2020/dimension/dimension.module.mjs +0 -38
- package/esm2020/sashbox/element-ref.directive.mjs +0 -27
- package/esm2020/sashbox/sash-initializer.directive.mjs +0 -32
- package/esm2020/sashbox/sash.directive.mjs +0 -144
- package/esm2020/sashbox/sashbox.component.mjs +0 -278
- package/esm2020/sashbox/sashbox.module.mjs +0 -69
- package/esm2020/splitter/splitter.component.mjs +0 -227
- package/esm2020/splitter/splitter.module.mjs +0 -42
- package/esm2020/throbber/ellipsis-throbber/ellipsis-throbber.component.mjs +0 -25
- package/esm2020/throbber/ripple-throbber/ripple-throbber.component.mjs +0 -25
- package/esm2020/throbber/roller-throbber/roller-throbber.component.mjs +0 -25
- package/esm2020/throbber/spinner-throbber/spinner-throbber.component.mjs +0 -26
- package/esm2020/throbber/throbber.component.mjs +0 -67
- package/esm2020/throbber/throbber.module.mjs +0 -48
- package/esm2020/viewport/native-scrollbar-track-size-provider.service.mjs +0 -114
- package/esm2020/viewport/scrollable.directive.mjs +0 -93
- package/esm2020/viewport/scrollbar/scrollbar.component.mjs +0 -322
- package/esm2020/viewport/viewport.component.mjs +0 -281
- package/esm2020/viewport/viewport.module.mjs +0 -50
- package/fesm2015/scion-components-sashbox.mjs +0 -554
- package/fesm2015/scion-components-sashbox.mjs.map +0 -1
- package/fesm2015/scion-components-splitter.mjs +0 -284
- package/fesm2015/scion-components-splitter.mjs.map +0 -1
- package/fesm2015/scion-components-throbber.mjs +0 -214
- package/fesm2015/scion-components-viewport.mjs +0 -861
- package/fesm2015/scion-components.mjs +0 -4
- package/fesm2015/scion-components.mjs.map +0 -1
- package/fesm2020/scion-components-dimension.mjs +0 -135
- package/fesm2020/scion-components-dimension.mjs.map +0 -1
- package/fesm2020/scion-components-throbber.mjs.map +0 -1
- package/fesm2020/scion-components-viewport.mjs.map +0 -1
- /package/{esm2020 → esm2022}/dimension/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/dimension/scion-components-dimension.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/sashbox/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/sashbox/sashbox-accessor.mjs +0 -0
- /package/{esm2020 → esm2022}/sashbox/scion-components-sashbox.mjs +0 -0
- /package/{esm2020 → esm2022}/scion-components.mjs +0 -0
- /package/{esm2020 → esm2022}/splitter/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/splitter/scion-components-splitter.mjs +0 -0
- /package/{esm2020 → esm2022}/throbber/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/throbber/scion-components-throbber.mjs +0 -0
- /package/{esm2020 → esm2022}/viewport/public_api.mjs +0 -0
- /package/{esm2020 → esm2022}/viewport/scion-components-viewport.mjs +0 -0
- /package/{fesm2020 → fesm2022}/scion-components.mjs +0 -0
- /package/{fesm2020 → fesm2022}/scion-components.mjs.map +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2018-2019 Swiss Federal Railways
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
+
*/
|
|
10
|
+
import { Inject, Injectable } from '@angular/core';
|
|
11
|
+
import { DOCUMENT } from '@angular/common';
|
|
12
|
+
import { BehaviorSubject, fromEvent, Subject } from 'rxjs';
|
|
13
|
+
import { debounceTime, distinctUntilChanged, map, startWith, takeUntil } from 'rxjs/operators';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
/**
|
|
16
|
+
* Provides the native scrollbar tracksize.
|
|
17
|
+
*
|
|
18
|
+
* @dynamic ignore 'strictMetadataEmit' errors due to the usage of {@link Document} as ambient type for DI.
|
|
19
|
+
*/
|
|
20
|
+
class SciNativeScrollbarTrackSizeProvider {
|
|
21
|
+
constructor(_document, _zone) {
|
|
22
|
+
this._document = _document;
|
|
23
|
+
this._zone = _zone;
|
|
24
|
+
this._trackSize$ = new BehaviorSubject(null);
|
|
25
|
+
this._destroy$ = new Subject();
|
|
26
|
+
this.installNativeScrollbarTrackSizeListener();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns an {Observable} which emits the native scrollbar track size, if any, or else `null`.
|
|
30
|
+
*
|
|
31
|
+
* Upon subscription, it emits the track size immediately, and then continuously emits when the track size changes.
|
|
32
|
+
*/
|
|
33
|
+
get trackSize$() {
|
|
34
|
+
return this._trackSize$;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the native scrollbar track size, if any, or else `null`.
|
|
38
|
+
*/
|
|
39
|
+
get trackSize() {
|
|
40
|
+
return this._trackSize$.getValue();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Computes the native scrollbar track size.
|
|
44
|
+
*
|
|
45
|
+
* @returns native track size, or `null` if the native scrollbars sit on top of the content.
|
|
46
|
+
*/
|
|
47
|
+
computeTrackSize() {
|
|
48
|
+
// create temporary viewport and viewport client with native scrollbars to compute scrolltrack width
|
|
49
|
+
const viewportDiv = this._document.createElement('div');
|
|
50
|
+
setStyle(viewportDiv, {
|
|
51
|
+
position: 'absolute',
|
|
52
|
+
overflow: 'scroll',
|
|
53
|
+
height: '100px',
|
|
54
|
+
width: '100px',
|
|
55
|
+
border: 0,
|
|
56
|
+
visibility: 'hidden',
|
|
57
|
+
});
|
|
58
|
+
const viewportClientDiv = this._document.createElement('div');
|
|
59
|
+
setStyle(viewportClientDiv, {
|
|
60
|
+
height: '100%',
|
|
61
|
+
width: '100%',
|
|
62
|
+
border: 0,
|
|
63
|
+
});
|
|
64
|
+
viewportDiv.appendChild(viewportClientDiv);
|
|
65
|
+
this._document.body.appendChild(viewportDiv);
|
|
66
|
+
const trackSize = {
|
|
67
|
+
hScrollbarTrackHeight: viewportDiv.offsetHeight - viewportClientDiv.offsetHeight,
|
|
68
|
+
vScrollbarTrackWidth: viewportDiv.offsetWidth - viewportClientDiv.offsetWidth,
|
|
69
|
+
};
|
|
70
|
+
// destroy temporary viewport
|
|
71
|
+
this._document.body.removeChild(viewportDiv);
|
|
72
|
+
if (trackSize.hScrollbarTrackHeight === 0 && trackSize.vScrollbarTrackWidth === 0) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
return trackSize;
|
|
76
|
+
}
|
|
77
|
+
installNativeScrollbarTrackSizeListener() {
|
|
78
|
+
// We compute the size of the native scrollbar track when the browser fires the onresize window event.
|
|
79
|
+
// This event is also fired on page zoom or when displaying a hidden document. Hidden documents do not have
|
|
80
|
+
// a scrollbar track size until being displayed, e.g., after showing hidden iframes.
|
|
81
|
+
this._zone.runOutsideAngular(() => {
|
|
82
|
+
fromEvent(window, 'resize')
|
|
83
|
+
.pipe(debounceTime(5), startWith(null), // trigger the initial computation
|
|
84
|
+
map(() => this.computeTrackSize()), distinctUntilChanged((t1, t2) => JSON.stringify(t1) === JSON.stringify(t2)), takeUntil(this._destroy$))
|
|
85
|
+
.subscribe(trackSize => {
|
|
86
|
+
this._zone.run(() => this._trackSize$.next(trackSize));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
ngOnDestroy() {
|
|
91
|
+
this._destroy$.next();
|
|
92
|
+
}
|
|
93
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, deps: [{ token: DOCUMENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
94
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, providedIn: 'root' }); }
|
|
95
|
+
}
|
|
96
|
+
export { SciNativeScrollbarTrackSizeProvider };
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciNativeScrollbarTrackSizeProvider, decorators: [{
|
|
98
|
+
type: Injectable,
|
|
99
|
+
args: [{ providedIn: 'root' }]
|
|
100
|
+
}], ctorParameters: function () { return [{ type: Document, decorators: [{
|
|
101
|
+
type: Inject,
|
|
102
|
+
args: [DOCUMENT]
|
|
103
|
+
}] }, { type: i0.NgZone }]; } });
|
|
104
|
+
/**
|
|
105
|
+
* Applies the given style(s) to the given element.
|
|
106
|
+
*
|
|
107
|
+
* Specify styles to be modified by passing a dictionary containing CSS property names (hyphen case).
|
|
108
|
+
* To remove a style, set its value to `null`.
|
|
109
|
+
*
|
|
110
|
+
* @ignore
|
|
111
|
+
*/
|
|
112
|
+
function setStyle(element, style) {
|
|
113
|
+
Object.keys(style).forEach(key => element.style.setProperty(key, style[key]));
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlLXNjcm9sbGJhci10cmFjay1zaXplLXByb3ZpZGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zY2lvbi9jb21wb25lbnRzL3ZpZXdwb3J0L3NyYy9uYXRpdmUtc2Nyb2xsYmFyLXRyYWNrLXNpemUtcHJvdmlkZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFvQixNQUFNLGVBQWUsQ0FBQztBQUNwRSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFDLGVBQWUsRUFBRSxTQUFTLEVBQWMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFFN0Y7Ozs7R0FJRztBQUNILE1BQ2EsbUNBQW1DO0lBSzlDLFlBQXNDLFNBQW1CLEVBQVUsS0FBYTtRQUExQyxjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQVUsVUFBSyxHQUFMLEtBQUssQ0FBUTtRQUgvRCxnQkFBVyxHQUFHLElBQUksZUFBZSxDQUFrQyxJQUFJLENBQUMsQ0FBQztRQUN6RSxjQUFTLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUcvQyxJQUFJLENBQUMsdUNBQXVDLEVBQUUsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQVcsVUFBVTtRQUNuQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGdCQUFnQjtR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LENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgU3dpc3MgRmVkZXJhbCBSYWlsd2F5c1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGVcbiAqIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wXG4gKiB3aGljaCBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC9cbiAqXG4gKiAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge0luamVjdCwgSW5qZWN0YWJsZSwgTmdab25lLCBPbkRlc3Ryb3l9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0LCBmcm9tRXZlbnQsIE9ic2VydmFibGUsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHN0YXJ0V2l0aCwgdGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIG5hdGl2ZSBzY3JvbGxiYXIgdHJhY2tzaXplLlxuICpcbiAqIEBkeW5hbWljIGlnbm9yZSAnc3RyaWN0TWV0YWRhdGFFbWl0JyBlcnJvcnMgZHVlIHRvIHRoZSB1c2FnZSBvZiB7QGxpbmsgRG9jdW1lbnR9IGFzIGFtYmllbnQgdHlwZSBmb3IgREkuXG4gKi9cbkBJbmplY3RhYmxlKHtwcm92aWRlZEluOiAncm9vdCd9KVxuZXhwb3J0IGNsYXNzIFNjaU5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZVByb3ZpZGVyIGltcGxlbWVudHMgT25EZXN0cm95IHtcblxuICBwcml2YXRlIHJlYWRvbmx5IF90cmFja1NpemUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxOYXRpdmVTY3JvbGxiYXJUcmFja1NpemUgfCBudWxsPihudWxsKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgX2RvY3VtZW50OiBEb2N1bWVudCwgcHJpdmF0ZSBfem9uZTogTmdab25lKSB7XG4gICAgdGhpcy5pbnN0YWxsTmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplTGlzdGVuZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIHtPYnNlcnZhYmxlfSB3aGljaCBlbWl0cyB0aGUgbmF0aXZlIHNjcm9sbGJhciB0cmFjayBzaXplLCBpZiBhbnksIG9yIGVsc2UgYG51bGxgLlxuICAgKlxuICAgKiBVcG9uIHN1YnNjcmlwdGlvbiwgaXQgZW1pdHMgdGhlIHRyYWNrIHNpemUgaW1tZWRpYXRlbHksIGFuZCB0aGVuIGNvbnRpbnVvdXNseSBlbWl0cyB3aGVuIHRoZSB0cmFjayBzaXplIGNoYW5nZXMuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHRyYWNrU2l6ZSQoKTogT2JzZXJ2YWJsZTxOYXRpdmVTY3JvbGxiYXJUcmFja1NpemUgfCBudWxsPiB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYWNrU2l6ZSQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbmF0aXZlIHNjcm9sbGJhciB0cmFjayBzaXplLCBpZiBhbnksIG9yIGVsc2UgYG51bGxgLlxuICAgKi9cbiAgcHVibGljIGdldCB0cmFja1NpemUoKTogTmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYWNrU2l6ZSQuZ2V0VmFsdWUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgbmF0aXZlIHNjcm9sbGJhciB0cmFjayBzaXplLlxuICAgKlxuICAgKiBAcmV0dXJucyBuYXRpdmUgdHJhY2sgc2l6ZSwgb3IgYG51bGxgIGlmIHRoZSBuYXRpdmUgc2Nyb2xsYmFycyBzaXQgb24gdG9wIG9mIHRoZSBjb250ZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlVHJhY2tTaXplKCk6IE5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZSB8IG51bGwge1xuICAgIC8vIGNyZWF0ZSB0ZW1wb3Jhcnkgdmlld3BvcnQgYW5kIHZpZXdwb3J0IGNsaWVudCB3aXRoIG5hdGl2ZSBzY3JvbGxiYXJzIHRvIGNvbXB1dGUgc2Nyb2xsdHJhY2sgd2lkdGhcbiAgICBjb25zdCB2aWV3cG9ydERpdiA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHNldFN0eWxlKHZpZXdwb3J0RGl2LCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIG92ZXJmbG93OiAnc2Nyb2xsJyxcbiAgICAgIGhlaWdodDogJzEwMHB4JyxcbiAgICAgIHdpZHRoOiAnMTAwcHgnLFxuICAgICAgYm9yZGVyOiAwLFxuICAgICAgdmlzaWJpbGl0eTogJ2hpZGRlbicsXG4gICAgfSk7XG5cbiAgICBjb25zdCB2aWV3cG9ydENsaWVudERpdiA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHNldFN0eWxlKHZpZXdwb3J0Q2xpZW50RGl2LCB7XG4gICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICBib3JkZXI6IDAsXG4gICAgfSk7XG5cbiAgICB2aWV3cG9ydERpdi5hcHBlbmRDaGlsZCh2aWV3cG9ydENsaWVudERpdik7XG4gICAgdGhpcy5fZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh2aWV3cG9ydERpdik7XG5cbiAgICBjb25zdCB0cmFja1NpemU6IE5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZSA9IHtcbiAgICAgIGhTY3JvbGxiYXJUcmFja0hlaWdodDogdmlld3BvcnREaXYub2Zmc2V0SGVpZ2h0IC0gdmlld3BvcnRDbGllbnREaXYub2Zmc2V0SGVpZ2h0LFxuICAgICAgdlNjcm9sbGJhclRyYWNrV2lkdGg6IHZpZXdwb3J0RGl2Lm9mZnNldFdpZHRoIC0gdmlld3BvcnRDbGllbnREaXYub2Zmc2V0V2lkdGgsXG4gICAgfTtcblxuICAgIC8vIGRlc3Ryb3kgdGVtcG9yYXJ5IHZpZXdwb3J0XG4gICAgdGhpcy5fZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh2aWV3cG9ydERpdik7XG4gICAgaWYgKHRyYWNrU2l6ZS5oU2Nyb2xsYmFyVHJhY2tIZWlnaHQgPT09IDAgJiYgdHJhY2tTaXplLnZTY3JvbGxiYXJUcmFja1dpZHRoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhY2tTaXplO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnN0YWxsTmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplTGlzdGVuZXIoKTogdm9pZCB7XG4gICAgLy8gV2UgY29tcHV0ZSB0aGUgc2l6ZSBvZiB0aGUgbmF0aXZlIHNjcm9sbGJhciB0cmFjayB3aGVuIHRoZSBicm93c2VyIGZpcmVzIHRoZSBvbnJlc2l6ZSB3aW5kb3cgZXZlbnQuXG4gICAgLy8gVGhpcyBldmVudCBpcyBhbHNvIGZpcmVkIG9uIHBhZ2Ugem9vbSBvciB3aGVuIGRpc3BsYXlpbmcgYSBoaWRkZW4gZG9jdW1lbnQuIEhpZGRlbiBkb2N1bWVudHMgZG8gbm90IGhhdmVcbiAgICAvLyBhIHNjcm9sbGJhciB0cmFjayBzaXplIHVudGlsIGJlaW5nIGRpc3BsYXllZCwgZS5nLiwgYWZ0ZXIgc2hvd2luZyBoaWRkZW4gaWZyYW1lcy5cbiAgICB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBkZWJvdW5jZVRpbWUoNSksXG4gICAgICAgICAgc3RhcnRXaXRoKG51bGwpLCAvLyB0cmlnZ2VyIHRoZSBpbml0aWFsIGNvbXB1dGF0aW9uXG4gICAgICAgICAgbWFwKCgpID0+IHRoaXMuY29tcHV0ZVRyYWNrU2l6ZSgpKSxcbiAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgodDEsIHQyKSA9PiBKU09OLnN0cmluZ2lmeSh0MSkgPT09IEpTT04uc3RyaW5naWZ5KHQyKSksXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKHRyYWNrU2l6ZSA9PiB7XG4gICAgICAgICAgdGhpcy5fem9uZS5ydW4oKCkgPT4gdGhpcy5fdHJhY2tTaXplJC5uZXh0KHRyYWNrU2l6ZSkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZXN0cm95JC5uZXh0KCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBnaXZlbiBzdHlsZShzKSB0byB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAqXG4gKiBTcGVjaWZ5IHN0eWxlcyB0byBiZSBtb2RpZmllZCBieSBwYXNzaW5nIGEgZGljdGlvbmFyeSBjb250YWluaW5nIENTUyBwcm9wZXJ0eSBuYW1lcyAoaHlwaGVuIGNhc2UpLlxuICogVG8gcmVtb3ZlIGEgc3R5bGUsIHNldCBpdHMgdmFsdWUgdG8gYG51bGxgLlxuICpcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gc2V0U3R5bGUoZWxlbWVudDogSFRNTEVsZW1lbnQsIHN0eWxlOiB7W3N0eWxlOiBzdHJpbmddOiBhbnkgfCBudWxsfSk6IHZvaWQge1xuICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaChrZXkgPT4gZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eShrZXksIHN0eWxlW2tleV0pKTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBuYXRpdmUgc2Nyb2xsYmFyIHRyYWNrIHNpemUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplIHtcbiAgaFNjcm9sbGJhclRyYWNrSGVpZ2h0OiBudW1iZXI7XG4gIHZTY3JvbGxiYXJUcmFja1dpZHRoOiBudW1iZXI7XG59XG4iXX0=
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2018-2019 Swiss Federal Railways
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
+
*/
|
|
10
|
+
import { Directive, Input } from '@angular/core';
|
|
11
|
+
import { map, takeUntil } from 'rxjs/operators';
|
|
12
|
+
import { merge, Subject } from 'rxjs';
|
|
13
|
+
import * as i0 from "@angular/core";
|
|
14
|
+
import * as i1 from "./native-scrollbar-track-size-provider.service";
|
|
15
|
+
/**
|
|
16
|
+
* Makes the host element natively scrollable and hides native scrollbars by default, unless native scrollbars
|
|
17
|
+
* already sit on top of the viewport (e.g. in OS X).
|
|
18
|
+
*
|
|
19
|
+
* Because there is no cross-browser API to hide scrollbars without losing native scroll support, we set 'overflow'
|
|
20
|
+
* to 'scroll' but shift the native scrollbars out of the visible viewport area. The shift offset is computed upfront.
|
|
21
|
+
*
|
|
22
|
+
* This directive expects its host element to be the only child in document flow in its parent DOM element. It makes the host element
|
|
23
|
+
* fill up the entire space (width and height set to 100%). The parent element must have its CSS `overflow` property set to `hidden`
|
|
24
|
+
* to hide the pushed out native scrollbars.
|
|
25
|
+
*/
|
|
26
|
+
class SciScrollableDirective {
|
|
27
|
+
constructor(_host, _renderer, nativeScrollbarTrackSizeProvider) {
|
|
28
|
+
this._host = _host;
|
|
29
|
+
this._renderer = _renderer;
|
|
30
|
+
this._destroy$ = new Subject();
|
|
31
|
+
this._inputChange$ = new Subject();
|
|
32
|
+
/**
|
|
33
|
+
* Controls whether to display native scrollbars.
|
|
34
|
+
* Has no effect if the native scrollbar sits on top of the content, e.g. in OS X.
|
|
35
|
+
*/
|
|
36
|
+
this.isDisplayNativeScrollbar = false;
|
|
37
|
+
merge(nativeScrollbarTrackSizeProvider.trackSize$, this._inputChange$.pipe(map(() => nativeScrollbarTrackSizeProvider.trackSize)))
|
|
38
|
+
.pipe(takeUntil(this._destroy$))
|
|
39
|
+
.subscribe(nativeScrollbarTrackSize => {
|
|
40
|
+
if (nativeScrollbarTrackSize === null) { // the native scrollbar sits on top of the content
|
|
41
|
+
this.useNativeScrollbars();
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.isDisplayNativeScrollbar ? this.useNativeScrollbars() : this.shiftNativeScrollbars(nativeScrollbarTrackSize);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Uses the native scrollbars when content overflows.
|
|
50
|
+
*/
|
|
51
|
+
useNativeScrollbars() {
|
|
52
|
+
this.setStyle(this._host.nativeElement, {
|
|
53
|
+
overflow: 'auto',
|
|
54
|
+
width: '100%',
|
|
55
|
+
height: '100%',
|
|
56
|
+
marginRight: 0,
|
|
57
|
+
marginBottom: 0,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Shifts the native scrollbars out of the visible viewport area.
|
|
62
|
+
*/
|
|
63
|
+
shiftNativeScrollbars(nativeScrollbarTrackSize) {
|
|
64
|
+
this.setStyle(this._host.nativeElement, {
|
|
65
|
+
overflow: 'scroll',
|
|
66
|
+
width: `calc(100% + ${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,
|
|
67
|
+
height: `calc(100% + ${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,
|
|
68
|
+
marginRight: `-${nativeScrollbarTrackSize.vScrollbarTrackWidth}px`,
|
|
69
|
+
marginBottom: `-${nativeScrollbarTrackSize.hScrollbarTrackHeight}px`,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
setStyle(element, style) {
|
|
73
|
+
Object.keys(style).forEach(key => this._renderer.setStyle(element, key, style[key]));
|
|
74
|
+
}
|
|
75
|
+
ngOnChanges(changes) {
|
|
76
|
+
this._inputChange$.next();
|
|
77
|
+
}
|
|
78
|
+
ngOnDestroy() {
|
|
79
|
+
this._destroy$.next();
|
|
80
|
+
}
|
|
81
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciScrollableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.SciNativeScrollbarTrackSizeProvider }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
82
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.1", type: SciScrollableDirective, selector: "[sciScrollable]", inputs: { isDisplayNativeScrollbar: ["sciScrollableDisplayNativeScrollbar", "isDisplayNativeScrollbar"] }, usesOnChanges: true, ngImport: i0 }); }
|
|
83
|
+
}
|
|
84
|
+
export { SciScrollableDirective };
|
|
85
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciScrollableDirective, decorators: [{
|
|
86
|
+
type: Directive,
|
|
87
|
+
args: [{
|
|
88
|
+
selector: '[sciScrollable]',
|
|
89
|
+
}]
|
|
90
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.SciNativeScrollbarTrackSizeProvider }]; }, propDecorators: { isDisplayNativeScrollbar: [{
|
|
91
|
+
type: Input,
|
|
92
|
+
args: ['sciScrollableDisplayNativeScrollbar']
|
|
93
|
+
}] } });
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsYWJsZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zY2lvbi9jb21wb25lbnRzL3ZpZXdwb3J0L3NyYy9zY3JvbGxhYmxlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sRUFBQyxTQUFTLEVBQWMsS0FBSyxFQUFpRCxNQUFNLGVBQWUsQ0FBQztBQUUzRyxPQUFPLEVBQUMsR0FBRyxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDOzs7QUFHcEM7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BR2Esc0JBQXNCO0lBWWpDLFlBQW9CLEtBQWlDLEVBQ2pDLFNBQW9CLEVBQzVCLGdDQUFxRTtRQUY3RCxVQUFLLEdBQUwsS0FBSyxDQUE0QjtRQUNqQyxjQUFTLEdBQVQsU0FBUyxDQUFXO1FBWGhDLGNBQVMsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ2hDLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUU1Qzs7O1dBR0c7UUFFSSw2QkFBd0IsR0FBWSxLQUFLLENBQUM7UUFLL0MsS0FBSyxDQUNILGdDQUFnQyxDQUFDLFVBQVUsRUFDM0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLGdDQUFnQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQy9FO2FBQ0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7YUFDL0IsU0FBUyxDQUFDLHdCQUF3QixDQUFDLEVBQUU7WUFDcEMsSUFBSSx3QkFBd0IsS0FBSyxJQUFJLEVBQUUsRUFBRSxrREFBa0Q7Z0JBQ3pGLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2FBQzVCO2lCQUNJO2dCQUNILElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO2FBQ25IO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxtQkFBbUI7UUFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTtZQUN0QyxRQUFRLEVBQUUsTUFBTTtZQUNoQixLQUFLLEVBQUUsTUFBTTtZQUNiLE1BQU0sRUFBRSxNQUFNO1lBQ2QsV0FBVyxFQUFFLENBQUM7WUFDZCxZQUFZLEVBQUUsQ0FBQztTQUNoQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxxQkFBcUIsQ0FBQyx3QkFBa0Q7UUFDOUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTtZQUN0QyxRQUFRLEVBQUUsUUFBUTtZQUNsQixLQUFLLEVBQUUsZUFBZSx3QkFBd0IsQ0FBQyxvQkFBb0IsSUFBSTtZQUN2RSxNQUFNLEVBQUUsZUFBZSx3QkFBd0IsQ0FBQyxxQkFBcUIsSUFBSTtZQUN6RSxXQUFXLEVBQUUsSUFBSSx3QkFBd0IsQ0FBQyxvQkFBb0IsSUFBSTtZQUNsRSxZQUFZLEVBQUUsSUFBSSx3QkFBd0IsQ0FBQyxxQkFBcUIsSUFBSTtTQUNyRSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sUUFBUSxDQUFDLE9BQWdCLEVBQUUsS0FBaUI7UUFDbEQsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUVNLFdBQVcsQ0FBQyxPQUFzQjtRQUN2QyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFTSxXQUFXO1FBQ2hCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDeEIsQ0FBQzs4R0FsRVUsc0JBQXNCO2tHQUF0QixzQkFBc0I7O1NBQXRCLHNCQUFzQjsyRkFBdEIsc0JBQXNCO2tCQUhsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxpQkFBaUI7aUJBQzVCOzJLQVdRLHdCQUF3QjtzQkFEOUIsS0FBSzt1QkFBQyxxQ0FBcUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgU3dpc3MgRmVkZXJhbCBSYWlsd2F5c1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGVcbiAqIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wXG4gKiB3aGljaCBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC9cbiAqXG4gKiAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge0RpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBSZW5kZXJlcjIsIFNpbXBsZUNoYW5nZXN9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtOYXRpdmVTY3JvbGxiYXJUcmFja1NpemUsIFNjaU5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZVByb3ZpZGVyfSBmcm9tICcuL25hdGl2ZS1zY3JvbGxiYXItdHJhY2stc2l6ZS1wcm92aWRlci5zZXJ2aWNlJztcbmltcG9ydCB7bWFwLCB0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7bWVyZ2UsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtEaWN0aW9uYXJ5fSBmcm9tICdAc2Npb24vdG9vbGtpdC91dGlsJztcblxuLyoqXG4gKiBNYWtlcyB0aGUgaG9zdCBlbGVtZW50IG5hdGl2ZWx5IHNjcm9sbGFibGUgYW5kIGhpZGVzIG5hdGl2ZSBzY3JvbGxiYXJzIGJ5IGRlZmF1bHQsIHVubGVzcyBuYXRpdmUgc2Nyb2xsYmFyc1xuICogYWxyZWFkeSBzaXQgb24gdG9wIG9mIHRoZSB2aWV3cG9ydCAoZS5nLiBpbiBPUyBYKS5cbiAqXG4gKiBCZWNhdXNlIHRoZXJlIGlzIG5vIGNyb3NzLWJyb3dzZXIgQVBJIHRvIGhpZGUgc2Nyb2xsYmFycyB3aXRob3V0IGxvc2luZyBuYXRpdmUgc2Nyb2xsIHN1cHBvcnQsIHdlIHNldCAnb3ZlcmZsb3cnXG4gKiB0byAnc2Nyb2xsJyBidXQgc2hpZnQgdGhlIG5hdGl2ZSBzY3JvbGxiYXJzIG91dCBvZiB0aGUgdmlzaWJsZSB2aWV3cG9ydCBhcmVhLiBUaGUgc2hpZnQgb2Zmc2V0IGlzIGNvbXB1dGVkIHVwZnJvbnQuXG4gKlxuICogVGhpcyBkaXJlY3RpdmUgZXhwZWN0cyBpdHMgaG9zdCBlbGVtZW50IHRvIGJlIHRoZSBvbmx5IGNoaWxkIGluIGRvY3VtZW50IGZsb3cgaW4gaXRzIHBhcmVudCBET00gZWxlbWVudC4gSXQgbWFrZXMgdGhlIGhvc3QgZWxlbWVudFxuICogZmlsbCB1cCB0aGUgZW50aXJlIHNwYWNlICh3aWR0aCBhbmQgaGVpZ2h0IHNldCB0byAxMDAlKS4gVGhlIHBhcmVudCBlbGVtZW50IG11c3QgaGF2ZSBpdHMgQ1NTIGBvdmVyZmxvd2AgcHJvcGVydHkgc2V0IHRvIGBoaWRkZW5gXG4gKiB0byBoaWRlIHRoZSBwdXNoZWQgb3V0IG5hdGl2ZSBzY3JvbGxiYXJzLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbc2NpU2Nyb2xsYWJsZV0nLFxufSlcbmV4cG9ydCBjbGFzcyBTY2lTY3JvbGxhYmxlRGlyZWN0aXZlIGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXG4gIHByaXZhdGUgX2Rlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfaW5wdXRDaGFuZ2UkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKipcbiAgICogQ29udHJvbHMgd2hldGhlciB0byBkaXNwbGF5IG5hdGl2ZSBzY3JvbGxiYXJzLlxuICAgKiBIYXMgbm8gZWZmZWN0IGlmIHRoZSBuYXRpdmUgc2Nyb2xsYmFyIHNpdHMgb24gdG9wIG9mIHRoZSBjb250ZW50LCBlLmcuIGluIE9TIFguXG4gICAqL1xuICBASW5wdXQoJ3NjaVNjcm9sbGFibGVEaXNwbGF5TmF0aXZlU2Nyb2xsYmFyJykgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8taW5wdXQtcmVuYW1lXG4gIHB1YmxpYyBpc0Rpc3BsYXlOYXRpdmVTY3JvbGxiYXI6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9ob3N0OiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplUHJvdmlkZXI6IFNjaU5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZVByb3ZpZGVyKSB7XG4gICAgbWVyZ2UoXG4gICAgICBuYXRpdmVTY3JvbGxiYXJUcmFja1NpemVQcm92aWRlci50cmFja1NpemUkLFxuICAgICAgdGhpcy5faW5wdXRDaGFuZ2UkLnBpcGUobWFwKCgpID0+IG5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZVByb3ZpZGVyLnRyYWNrU2l6ZSkpLFxuICAgIClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKG5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVTY3JvbGxiYXJUcmFja1NpemUgPT09IG51bGwpIHsgLy8gdGhlIG5hdGl2ZSBzY3JvbGxiYXIgc2l0cyBvbiB0b3Agb2YgdGhlIGNvbnRlbnRcbiAgICAgICAgICB0aGlzLnVzZU5hdGl2ZVNjcm9sbGJhcnMoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzLmlzRGlzcGxheU5hdGl2ZVNjcm9sbGJhciA/IHRoaXMudXNlTmF0aXZlU2Nyb2xsYmFycygpIDogdGhpcy5zaGlmdE5hdGl2ZVNjcm9sbGJhcnMobmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXNlcyB0aGUgbmF0aXZlIHNjcm9sbGJhcnMgd2hlbiBjb250ZW50IG92ZXJmbG93cy5cbiAgICovXG4gIHByaXZhdGUgdXNlTmF0aXZlU2Nyb2xsYmFycygpOiB2b2lkIHtcbiAgICB0aGlzLnNldFN0eWxlKHRoaXMuX2hvc3QubmF0aXZlRWxlbWVudCwge1xuICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgIG1hcmdpblJpZ2h0OiAwLFxuICAgICAgbWFyZ2luQm90dG9tOiAwLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNoaWZ0cyB0aGUgbmF0aXZlIHNjcm9sbGJhcnMgb3V0IG9mIHRoZSB2aXNpYmxlIHZpZXdwb3J0IGFyZWEuXG4gICAqL1xuICBwcml2YXRlIHNoaWZ0TmF0aXZlU2Nyb2xsYmFycyhuYXRpdmVTY3JvbGxiYXJUcmFja1NpemU6IE5hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZSk6IHZvaWQge1xuICAgIHRoaXMuc2V0U3R5bGUodGhpcy5faG9zdC5uYXRpdmVFbGVtZW50LCB7XG4gICAgICBvdmVyZmxvdzogJ3Njcm9sbCcsXG4gICAgICB3aWR0aDogYGNhbGMoMTAwJSArICR7bmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplLnZTY3JvbGxiYXJUcmFja1dpZHRofXB4YCxcbiAgICAgIGhlaWdodDogYGNhbGMoMTAwJSArICR7bmF0aXZlU2Nyb2xsYmFyVHJhY2tTaXplLmhTY3JvbGxiYXJUcmFja0hlaWdodH1weGAsXG4gICAgICBtYXJnaW5SaWdodDogYC0ke25hdGl2ZVNjcm9sbGJhclRyYWNrU2l6ZS52U2Nyb2xsYmFyVHJhY2tXaWR0aH1weGAsXG4gICAgICBtYXJnaW5Cb3R0b206IGAtJHtuYXRpdmVTY3JvbGxiYXJUcmFja1NpemUuaFNjcm9sbGJhclRyYWNrSGVpZ2h0fXB4YCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3R5bGUoZWxlbWVudDogRWxlbWVudCwgc3R5bGU6IERpY3Rpb25hcnkpOiB2b2lkIHtcbiAgICBPYmplY3Qua2V5cyhzdHlsZSkuZm9yRWFjaChrZXkgPT4gdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUoZWxlbWVudCwga2V5LCBzdHlsZVtrZXldKSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHRoaXMuX2lucHV0Q2hhbmdlJC5uZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fZGVzdHJveSQubmV4dCgpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2018-2019 Swiss Federal Railways
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made
|
|
5
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
+
*
|
|
8
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
+
*/
|
|
10
|
+
import { DOCUMENT } from '@angular/common';
|
|
11
|
+
import { ChangeDetectionStrategy, Component, HostBinding, Inject, Input, NgZone, ViewChild } from '@angular/core';
|
|
12
|
+
import { fromEvent, merge, of, Subject, timer } from 'rxjs';
|
|
13
|
+
import { debounceTime, first, map, startWith, switchMap, takeUntil, takeWhile, withLatestFrom } from 'rxjs/operators';
|
|
14
|
+
import { fromDimension$, fromMutation$ } from '@scion/toolkit/observable';
|
|
15
|
+
import { filterArray, subscribeInside } from '@scion/toolkit/operators';
|
|
16
|
+
import * as i0 from "@angular/core";
|
|
17
|
+
/**
|
|
18
|
+
* Renders a vertical or horizontal scrollbar.
|
|
19
|
+
*
|
|
20
|
+
* The scrollbar features the following functionality:
|
|
21
|
+
* - allows to move the thumb by mouse or touch
|
|
22
|
+
* - enlarges the thumb if the mouse pointer is near the thumb
|
|
23
|
+
* - allows paging on mousedown on the scroll track
|
|
24
|
+
*
|
|
25
|
+
* ### CSS styling:
|
|
26
|
+
*
|
|
27
|
+
* You can override the following CSS variables:
|
|
28
|
+
*
|
|
29
|
+
* - sci-scrollbar-color: Sets the color of the scrollbar (by default, uses `rgb(78, 78, 78)`).
|
|
30
|
+
*
|
|
31
|
+
* Example:
|
|
32
|
+
*
|
|
33
|
+
* ```css
|
|
34
|
+
*
|
|
35
|
+
* sci-scrollbar {
|
|
36
|
+
* --sci-scrollbar-color: blue;
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
class SciScrollbarComponent {
|
|
41
|
+
/**
|
|
42
|
+
* Timeout for debouncing viewport resize events that trigger the scroll position computation.
|
|
43
|
+
*
|
|
44
|
+
* Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
45
|
+
* trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
46
|
+
* expands a panel that contains a viewport.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
static { this.VIEWPORT_RESIZE_DEBOUNCE_TIME = 50; }
|
|
51
|
+
get vertical() {
|
|
52
|
+
return this.direction === 'vscroll';
|
|
53
|
+
}
|
|
54
|
+
get horizontal() {
|
|
55
|
+
return this.direction === 'hscroll';
|
|
56
|
+
}
|
|
57
|
+
get scrolling() {
|
|
58
|
+
return this._lastDragPosition !== null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The viewport to provide scrollbars for.
|
|
62
|
+
*/
|
|
63
|
+
set setViewport(viewport) {
|
|
64
|
+
this._viewport = viewport;
|
|
65
|
+
this._viewportChange$.next();
|
|
66
|
+
}
|
|
67
|
+
constructor(_host, _document, _zone) {
|
|
68
|
+
this._host = _host;
|
|
69
|
+
this._document = _document;
|
|
70
|
+
this._zone = _zone;
|
|
71
|
+
this._destroy$ = new Subject();
|
|
72
|
+
this._viewportChange$ = new Subject();
|
|
73
|
+
this._lastDragPosition = null;
|
|
74
|
+
this._overflow = false;
|
|
75
|
+
this._thumbSizeFr = 0;
|
|
76
|
+
this._thumbPositionFr = 0;
|
|
77
|
+
/**
|
|
78
|
+
* Specifies the direction of the scrollbar.
|
|
79
|
+
*
|
|
80
|
+
* By default, if not specified, renders a vertical scrollbar.
|
|
81
|
+
*/
|
|
82
|
+
this.direction = 'vscroll';
|
|
83
|
+
this._viewportChange$
|
|
84
|
+
.pipe(switchMap(() => {
|
|
85
|
+
if (!this._viewport) {
|
|
86
|
+
return of(undefined);
|
|
87
|
+
}
|
|
88
|
+
return merge(this.viewportScrollChange$(), this.viewportDimensionChange$({ debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME }), this.viewportClientDimensionChange$({ debounceTime: SciScrollbarComponent.VIEWPORT_RESIZE_DEBOUNCE_TIME }));
|
|
89
|
+
}), subscribeInside(continueFn => this._zone.runOutsideAngular(continueFn)), takeUntil(this._destroy$))
|
|
90
|
+
.subscribe(() => {
|
|
91
|
+
if (this._viewport) {
|
|
92
|
+
this.renderScrollPosition();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.unsetScrollPosition();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Computes the scroll position and updates CSS variables to render the scroll position in the UI.
|
|
101
|
+
*/
|
|
102
|
+
renderScrollPosition() {
|
|
103
|
+
NgZone.assertNotInAngularZone();
|
|
104
|
+
const viewportSize = this.viewportSize;
|
|
105
|
+
const viewportClientSize = this.viewportClientSize;
|
|
106
|
+
const thumbPositionFr = this.scrollPosition / viewportClientSize;
|
|
107
|
+
const thumbSizeFr = viewportSize / viewportClientSize;
|
|
108
|
+
const overflow = viewportClientSize > viewportSize;
|
|
109
|
+
if (thumbPositionFr !== this._thumbPositionFr || thumbSizeFr !== this._thumbSizeFr) {
|
|
110
|
+
this._thumbPositionFr = thumbPositionFr;
|
|
111
|
+
this._thumbSizeFr = thumbSizeFr;
|
|
112
|
+
this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', thumbPositionFr);
|
|
113
|
+
this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', thumbSizeFr);
|
|
114
|
+
}
|
|
115
|
+
if (overflow !== this._overflow) {
|
|
116
|
+
this._overflow = overflow;
|
|
117
|
+
overflow ? this._host.nativeElement.classList.add('overflow') : this._host.nativeElement.classList.remove('overflow');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clears CSS variables used for rendering the scroll position in the UI.
|
|
122
|
+
*/
|
|
123
|
+
unsetScrollPosition() {
|
|
124
|
+
NgZone.assertNotInAngularZone();
|
|
125
|
+
this._thumbPositionFr = 0;
|
|
126
|
+
this._thumbSizeFr = 0;
|
|
127
|
+
this._overflow = false;
|
|
128
|
+
this.setCssVariable('--ɵsci-scrollbar-thumb-position-fr', 0);
|
|
129
|
+
this.setCssVariable('--ɵsci-scrollbar-thumb-size-fr', 0);
|
|
130
|
+
this._host.nativeElement.classList.remove('overflow');
|
|
131
|
+
}
|
|
132
|
+
/* @docs-private */
|
|
133
|
+
onTouchStart(event) {
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
this._lastDragPosition = this.vertical ? event.touches[0].screenY : event.touches[0].screenX;
|
|
136
|
+
}
|
|
137
|
+
/* @docs-private */
|
|
138
|
+
onTouchMove(event) {
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
const newDragPositionPx = this.vertical ? event.touches[0].screenY : event.touches[0].screenX;
|
|
141
|
+
const scrollbarPanPx = newDragPositionPx - this._lastDragPosition;
|
|
142
|
+
const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);
|
|
143
|
+
this._lastDragPosition = newDragPositionPx;
|
|
144
|
+
this.moveViewportClient(viewportPanPx);
|
|
145
|
+
}
|
|
146
|
+
/* @docs-private */
|
|
147
|
+
onTouchEnd(event) {
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
this._lastDragPosition = null;
|
|
150
|
+
}
|
|
151
|
+
/* @docs-private */
|
|
152
|
+
onMouseDown(mousedownEvent) {
|
|
153
|
+
if (mousedownEvent.button !== 0) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
mousedownEvent.preventDefault();
|
|
157
|
+
this._lastDragPosition = this.vertical ? mousedownEvent.screenY : mousedownEvent.screenX;
|
|
158
|
+
// Listen for 'mousemove' events
|
|
159
|
+
this._zone.runOutsideAngular(() => {
|
|
160
|
+
const mousemoveListener = merge(fromEvent(this._document, 'mousemove'), fromEvent(this._document, 'sci-mousemove'))
|
|
161
|
+
.pipe(takeUntil(this._destroy$))
|
|
162
|
+
.subscribe(mousemoveEvent => {
|
|
163
|
+
mousemoveEvent.preventDefault();
|
|
164
|
+
const newDragPositionPx = this.vertical ? mousemoveEvent.screenY : mousemoveEvent.screenX;
|
|
165
|
+
const scrollbarPanPx = newDragPositionPx - this._lastDragPosition;
|
|
166
|
+
const viewportPanPx = this.toViewportPanPx(scrollbarPanPx);
|
|
167
|
+
this._lastDragPosition = newDragPositionPx;
|
|
168
|
+
this.moveViewportClient(viewportPanPx);
|
|
169
|
+
});
|
|
170
|
+
// Listen for 'mouseup' events; use 'capture phase' and 'stop propagation' to not close overlays
|
|
171
|
+
merge(fromEvent(this._document, 'mouseup', { capture: true }), fromEvent(this._document, 'sci-mouseup'))
|
|
172
|
+
.pipe(first(), takeUntil(this._destroy$))
|
|
173
|
+
.subscribe(mouseupEvent => {
|
|
174
|
+
mouseupEvent.stopPropagation();
|
|
175
|
+
mousemoveListener.unsubscribe();
|
|
176
|
+
this._lastDragPosition = null;
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/* @docs-private */
|
|
181
|
+
onScrollTrackMouseDown(event, direction) {
|
|
182
|
+
const signum = (direction === 'up' ? -1 : +1);
|
|
183
|
+
this.scrollWhileMouseDown(this.toViewportPanPx(signum * this.thumbSize), event);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Projects the given scrollbar scroll pixels into viewport scroll pixels.
|
|
187
|
+
*/
|
|
188
|
+
toViewportPanPx(scrollbarPanPx) {
|
|
189
|
+
const scrollRangePx = this.trackSize - this.thumbSize;
|
|
190
|
+
const scrollRatio = scrollbarPanPx / scrollRangePx;
|
|
191
|
+
return scrollRatio * (this.viewportClientSize - this.viewportSize);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Moves the viewport client by the specified numbers of pixels.
|
|
195
|
+
*/
|
|
196
|
+
moveViewportClient(viewportPanPx) {
|
|
197
|
+
if (this.vertical) {
|
|
198
|
+
this._viewport.scrollTop += viewportPanPx;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
this._viewport.scrollLeft += viewportPanPx;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Indicates if the content overflows.
|
|
206
|
+
*/
|
|
207
|
+
get overflow() {
|
|
208
|
+
return this._overflow;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Scrolls continuously while holding the mouse pressed, or until the mouse leaves the scrolltrack.
|
|
212
|
+
*/
|
|
213
|
+
scrollWhileMouseDown(viewportScrollPx, mousedownEvent) {
|
|
214
|
+
// The `EventTarget` type of `Event.target` is not yet compatible with `FromEventTarget` used in `fromEvent`.
|
|
215
|
+
// This will be fixed in rxjs version 7.0.0. Refer to https://github.com/ReactiveX/rxjs/commit/5f022d784570684632e6fd5ae247fc259ee34c4b
|
|
216
|
+
// for more details.
|
|
217
|
+
const scrollTrackElement = mousedownEvent.target;
|
|
218
|
+
// scroll continuously every 50ms after an initial delay of 250ms
|
|
219
|
+
timer(250, 50)
|
|
220
|
+
.pipe(
|
|
221
|
+
// continue chain with latest mouse event
|
|
222
|
+
withLatestFrom(merge(of(mousedownEvent), fromEvent(scrollTrackElement, 'mousemove')), (tick, event) => event),
|
|
223
|
+
// start immediately
|
|
224
|
+
startWith(mousedownEvent),
|
|
225
|
+
// stop scrolling if the thumb hits the mouse pointer position
|
|
226
|
+
takeWhile((event) => scrollTrackElement === this._document.elementFromPoint(event.clientX, event.clientY)), debounceTime(10),
|
|
227
|
+
// stop scrolling on mouseout or mouseup
|
|
228
|
+
takeUntil(merge(fromEvent(scrollTrackElement, 'mouseout'), fromEvent(scrollTrackElement, 'mouseup'))))
|
|
229
|
+
.subscribe(() => {
|
|
230
|
+
this.moveViewportClient(viewportScrollPx);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Emits whenever the viewport scrolls.
|
|
235
|
+
*/
|
|
236
|
+
viewportScrollChange$() {
|
|
237
|
+
return fromEvent(this._viewport, 'scroll', { passive: true }).pipe(map(() => undefined));
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Emits on subscription, and then each time the size of the viewport changes.
|
|
241
|
+
*/
|
|
242
|
+
viewportDimensionChange$(options) {
|
|
243
|
+
return fromDimension$(this._viewport)
|
|
244
|
+
.pipe(
|
|
245
|
+
// Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
246
|
+
// trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
247
|
+
// expands a panel that contains a viewport.
|
|
248
|
+
debounceTime(options.debounceTime), map(() => undefined));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Emits on subscription, and then each time the size or style property of the viewport client changes.
|
|
252
|
+
*/
|
|
253
|
+
viewportClientDimensionChange$(options) {
|
|
254
|
+
return this.children$(this._viewport)
|
|
255
|
+
.pipe(switchMap(children => merge(...children.map(child => merge(fromDimension$(child),
|
|
256
|
+
// Observe style mutations since some transformations change the scroll position without necessarily triggering a dimension change,
|
|
257
|
+
// e.g., `scale` or `translate` used by some virtual scroll implementations
|
|
258
|
+
fromMutation$(child, { subtree: false, childList: false, attributeFilter: ['style'] }))))),
|
|
259
|
+
// Debouncing is particularly important in the context of Angular animations, since they continuously
|
|
260
|
+
// trigger resize events. Debouncing prevents the scrollbar from flickering, for example, when the user
|
|
261
|
+
// expands a panel that contains a viewport.
|
|
262
|
+
debounceTime(options.debounceTime), map(() => undefined));
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Emits the children of the passed element, and then each time child elements are added or removed.
|
|
266
|
+
*/
|
|
267
|
+
children$(element) {
|
|
268
|
+
return fromMutation$(element, { subtree: false, childList: true })
|
|
269
|
+
.pipe(startWith(undefined), map(() => Array.from(element.children)), filterArray((child) => child instanceof HTMLElement));
|
|
270
|
+
}
|
|
271
|
+
setCssVariable(key, value) {
|
|
272
|
+
this._host.nativeElement.style.setProperty(key, value);
|
|
273
|
+
}
|
|
274
|
+
get viewportSize() {
|
|
275
|
+
return this._viewport ? (this.vertical ? this._viewport.clientHeight : this._viewport.clientWidth) : 0;
|
|
276
|
+
}
|
|
277
|
+
get viewportClientSize() {
|
|
278
|
+
return this._viewport ? (this.vertical ? this._viewport.scrollHeight : this._viewport.scrollWidth) : 0;
|
|
279
|
+
}
|
|
280
|
+
get scrollPosition() {
|
|
281
|
+
return this._viewport ? (this.vertical ? this._viewport.scrollTop : this._viewport.scrollLeft) : 0;
|
|
282
|
+
}
|
|
283
|
+
get thumbSize() {
|
|
284
|
+
const thumbElement = this.thumbElement.nativeElement;
|
|
285
|
+
return this.vertical ? thumbElement.clientHeight : thumbElement.clientWidth;
|
|
286
|
+
}
|
|
287
|
+
get trackSize() {
|
|
288
|
+
const trackElement = this._host.nativeElement;
|
|
289
|
+
return this.vertical ? trackElement.clientHeight : trackElement.clientWidth;
|
|
290
|
+
}
|
|
291
|
+
/* @docs-private */
|
|
292
|
+
ngOnDestroy() {
|
|
293
|
+
this._destroy$.next();
|
|
294
|
+
}
|
|
295
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciScrollbarComponent, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
296
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.1", type: SciScrollbarComponent, selector: "sci-scrollbar", inputs: { direction: "direction", setViewport: ["viewport", "setViewport"] }, host: { properties: { "class.vertical": "this.vertical", "class.horizontal": "this.horizontal", "class.scrolling": "this.scrolling" } }, viewQueries: [{ propertyName: "thumbElement", first: true, predicate: ["thumb_handle"], descendants: true, static: true }], ngImport: i0, template: "<!-- scrolltrack to move the viewport client upwards (paging) -->\n<div class=\"scrolltrack-start\" (mousedown)=\"onScrollTrackMouseDown($event, 'up')\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n (touchcancel)=\"onTouchEnd($event)\">\n <div class=\"thumb\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\">\n </div>\n</div>\n\n<!-- scrolltrack to move the viewport client downwards (paging) -->\n<div class=\"scrolltrack-end\" (mousedown)=\"onScrollTrackMouseDown($event, 'down')\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;border:2px solid transparent;box-sizing:border-box;--sci-scrollbar-color: rgb(78, 78, 78);--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column}:host.horizontal{flex-direction:row}:host>div.scrolltrack-start{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host>div.thumb-handle{flex-basis:20px;display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column}:host>div.thumb-handle.horizontal{flex-direction:row}:host>div.thumb-handle>div.thumb{flex:auto;border-radius:4px;background-color:var(--sci-scrollbar-color);opacity:.4;transition-duration:125ms;transition-property:width,height;transition-timing-function:ease-out}:host>div.thumb-handle>div.thumb.vertical{width:60%}:host>div.thumb-handle>div.thumb.horizontal{height:60%}:host>div.scrolltrack-end{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}:host-context:not(.overflow){display:none}:host-context:hover>div.thumb-handle>div.thumb,:host-context(.scrolling)>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host-context:hover>div.thumb-handle>div.thumb.vertical,:host-context(.scrolling)>div.thumb-handle>div.thumb.vertical{width:100%}:host-context:hover>div.thumb-handle>div.thumb.horizontal,:host-context(.scrolling)>div.thumb-handle>div.thumb.horizontal{height:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
297
|
+
}
|
|
298
|
+
export { SciScrollbarComponent };
|
|
299
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.1", ngImport: i0, type: SciScrollbarComponent, decorators: [{
|
|
300
|
+
type: Component,
|
|
301
|
+
args: [{ selector: 'sci-scrollbar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- scrolltrack to move the viewport client upwards (paging) -->\n<div class=\"scrolltrack-start\" (mousedown)=\"onScrollTrackMouseDown($event, 'up')\"></div>\n\n<!-- scrollthumb -->\n<div #thumb_handle\n class=\"thumb-handle\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n (touchcancel)=\"onTouchEnd($event)\">\n <div class=\"thumb\"\n [class.vertical]=\"vertical\"\n [class.horizontal]=\"horizontal\">\n </div>\n</div>\n\n<!-- scrolltrack to move the viewport client downwards (paging) -->\n<div class=\"scrolltrack-end\" (mousedown)=\"onScrollTrackMouseDown($event, 'down')\"></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;border:2px solid transparent;box-sizing:border-box;--sci-scrollbar-color: rgb(78, 78, 78);--\\275sci-scrollbar-thumb-position-fr: 0;--\\275sci-scrollbar-thumb-size-fr: 0}:host.vertical{flex-direction:column}:host.horizontal{flex-direction:row}:host>div.scrolltrack-start{flex-grow:var(--\\275sci-scrollbar-thumb-position-fr)}:host>div.thumb-handle{flex-basis:20px;display:flex;flex-grow:var(--\\275sci-scrollbar-thumb-size-fr);align-items:center}:host>div.thumb-handle.vertical{flex-direction:column}:host>div.thumb-handle.horizontal{flex-direction:row}:host>div.thumb-handle>div.thumb{flex:auto;border-radius:4px;background-color:var(--sci-scrollbar-color);opacity:.4;transition-duration:125ms;transition-property:width,height;transition-timing-function:ease-out}:host>div.thumb-handle>div.thumb.vertical{width:60%}:host>div.thumb-handle>div.thumb.horizontal{height:60%}:host>div.scrolltrack-end{flex-grow:calc(1 - (var(--\\275sci-scrollbar-thumb-position-fr) + var(--\\275sci-scrollbar-thumb-size-fr)))}:host-context:not(.overflow){display:none}:host-context:hover>div.thumb-handle>div.thumb,:host-context(.scrolling)>div.thumb-handle>div.thumb{background-color:var(--sci-scrollbar-color);opacity:.75}:host-context:hover>div.thumb-handle>div.thumb.vertical,:host-context(.scrolling)>div.thumb-handle>div.thumb.vertical{width:100%}:host-context:hover>div.thumb-handle>div.thumb.horizontal,:host-context(.scrolling)>div.thumb-handle>div.thumb.horizontal{height:100%}\n"] }]
|
|
302
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: undefined, decorators: [{
|
|
303
|
+
type: Inject,
|
|
304
|
+
args: [DOCUMENT]
|
|
305
|
+
}] }, { type: i0.NgZone }]; }, propDecorators: { thumbElement: [{
|
|
306
|
+
type: ViewChild,
|
|
307
|
+
args: ['thumb_handle', { static: true }]
|
|
308
|
+
}], vertical: [{
|
|
309
|
+
type: HostBinding,
|
|
310
|
+
args: ['class.vertical']
|
|
311
|
+
}], horizontal: [{
|
|
312
|
+
type: HostBinding,
|
|
313
|
+
args: ['class.horizontal']
|
|
314
|
+
}], scrolling: [{
|
|
315
|
+
type: HostBinding,
|
|
316
|
+
args: ['class.scrolling']
|
|
317
|
+
}], direction: [{
|
|
318
|
+
type: Input
|
|
319
|
+
}], setViewport: [{
|
|
320
|
+
type: Input,
|
|
321
|
+
args: ['viewport']
|
|
322
|
+
}] } });
|
|
323
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NjaW9uL2NvbXBvbmVudHMvdmlld3BvcnQvc3JjL3Njcm9sbGJhci9zY3JvbGxiYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vY29tcG9uZW50cy92aWV3cG9ydC9zcmMvc2Nyb2xsYmFyL3Njcm9sbGJhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsU0FBUyxFQUFjLFdBQVcsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBYSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdkksT0FBTyxFQUFDLFNBQVMsRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDdEUsT0FBTyxFQUFDLFlBQVksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwSCxPQUFPLEVBQUMsY0FBYyxFQUFFLGFBQWEsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBQ3hFLE9BQU8sRUFBQyxXQUFXLEVBQUUsZUFBZSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7O0FBRXRFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBQ0gsTUFNYSxxQkFBcUI7SUFFaEM7Ozs7Ozs7O09BUUc7YUFDb0Isa0NBQTZCLEdBQUcsRUFBRSxBQUFMLENBQU07SUFlMUQsSUFDVyxRQUFRO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLENB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QU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQztJQUM5RSxDQUFDO0lBRUQsbUJBQW1CO0lBQ1osV0FBVztRQUNoQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3hCLENBQUM7OEdBblVVLHFCQUFxQiw0Q0EyRFosUUFBUTtrR0EzRGpCLHFCQUFxQix3WUM5Q2xDLDR5QkFxQkE7O1NEeUJhLHFCQUFxQjsyRkFBckIscUJBQXFCO2tCQU5qQyxTQUFTOytCQUNFLGVBQWUsbUJBR1IsdUJBQXVCLENBQUMsTUFBTTs7MEJBNkRsQyxNQUFNOzJCQUFDLFFBQVE7aUVBbkNyQixZQUFZO3NCQURsQixTQUFTO3VCQUFDLGNBQWMsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUM7Z0JBSTlCLFFBQVE7c0JBRGxCLFdBQVc7dUJBQUMsZ0JBQWdCO2dCQU1sQixVQUFVO3NCQURwQixXQUFXO3VCQUFDLGtCQUFrQjtnQkFNcEIsU0FBUztzQkFEbkIsV0FBVzt1QkFBQyxpQkFBaUI7Z0JBV3ZCLFNBQVM7c0JBRGYsS0FBSztnQkFPSyxXQUFXO3NCQURyQixLQUFLO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMTkgU3dpc3MgRmVkZXJhbCBSYWlsd2F5c1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGVcbiAqIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wXG4gKiB3aGljaCBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC9cbiAqXG4gKiAgU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0QmluZGluZywgSW5qZWN0LCBJbnB1dCwgTmdab25lLCBPbkRlc3Ryb3ksIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge2Zyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0LCB0aW1lcn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2RlYm91bmNlVGltZSwgZmlyc3QsIG1hcCwgc3RhcnRXaXRoLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFrZVdoaWxlLCB3aXRoTGF0ZXN0RnJvbX0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtmcm9tRGltZW5zaW9uJCwgZnJvbU11dGF0aW9uJH0gZnJvbSAnQHNjaW9uL3Rvb2xraXQvb2JzZXJ2YWJsZSc7XG5pbXBvcnQge2ZpbHRlckFycmF5LCBzdWJzY3JpYmVJbnNpZGV9IGZyb20gJ0BzY2lvbi90b29sa2l0L29wZXJhdG9ycyc7XG5cbi8qKlxuICogUmVuZGVycyBhIHZlcnRpY2FsIG9yIGhvcml6b250YWwgc2Nyb2xsYmFyLlxuICpcbiAqIFRoZSBzY3JvbGxiYXIgZmVhdHVyZXMgdGhlIGZvbGxvd2luZyBmdW5jdGlvbmFsaXR5OlxuICogLSBhbGxvd3MgdG8gbW92ZSB0aGUgdGh1bWIgYnkgbW91c2Ugb3IgdG91Y2hcbiAqIC0gZW5sYXJnZXMgdGhlIHRodW1iIGlmIHRoZSBtb3VzZSBwb2ludGVyIGlzIG5lYXIgdGhlIHRodW1iXG4gKiAtIGFsbG93cyBwYWdpbmcgb24gbW91c2Vkb3duIG9uIHRoZSBzY3JvbGwgdHJhY2tcbiAqXG4gKiAjIyMgQ1NTIHN0eWxpbmc6XG4gKlxuICogWW91IGNhbiBvdmVycmlkZSB0aGUgZm9sbG93aW5nIENTUyB2YXJpYWJsZXM6XG4gKlxuICogLSBzY2ktc2Nyb2xsYmFyLWNvbG9yOiAgICBTZXRzIHRoZSBjb2xvciBvZiB0aGUgc2Nyb2xsYmFyIChieSBkZWZhdWx0LCB1c2VzIGByZ2IoNzgsIDc4LCA3OClgKS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGNzc1xuICpcbiAqIHNjaS1zY3JvbGxiYXIge1xuICogICAtLXNjaS1zY3JvbGxiYXItY29sb3I6IGJsdWU7XG4gKiB9XG4gKiBgYGBcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2NpLXNjcm9sbGJhcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zY3JvbGxiYXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zY3JvbGxiYXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNjaVNjcm9sbGJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgLyoqXG4gICAqIFRpbWVvdXQgZm9yIGRlYm91bmNpbmcgdmlld3BvcnQgcmVzaXplIGV2ZW50cyB0aGF0IHRyaWdnZXIgdGhlIHNjcm9sbCBwb3NpdGlvbiBjb21wdXRhdGlvbi5cbiAgICpcbiAgICogRGVib3VuY2luZyBpcyBwYXJ0aWN1bGFybHkgaW1wb3J0YW50IGluIHRoZSBjb250ZXh0IG9mIEFuZ3VsYXIgYW5pbWF0aW9ucywgc2luY2UgdGhleSBjb250aW51b3VzbHlcbiAgICogdHJpZ2dlciByZXNpemUgZXZlbnRzLiBEZWJvdW5jaW5nIHByZXZlbnRzIHRoZSBzY3JvbGxiYXIgZnJvbSBmbGlja2VyaW5nLCBmb3IgZXhhbXBsZSwgd2hlbiB0aGUgdXNlclxuICAgKiBleHBhbmRzIGEgcGFuZWwgdGhhdCBjb250YWlucyBhIHZpZXdwb3J0LlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgVklFV1BPUlRfUkVTSVpFX0RFQk9VTkNFX1RJTUUgPSA1MDtcblxuICBwcml2YXRlIF9kZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgX3ZpZXdwb3J0ITogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgX3ZpZXdwb3J0Q2hhbmdlJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgX2xhc3REcmFnUG9zaXRpb246IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgX292ZXJmbG93ID0gZmFsc2U7XG4gIHByaXZhdGUgX3RodW1iU2l6ZUZyID0gMDtcbiAgcHJpdmF0ZSBfdGh1bWJQb3NpdGlvbkZyID0gMDtcblxuICAvKiBAZG9jcy1wcml2YXRlICovXG4gIEBWaWV3Q2hpbGQoJ3RodW1iX2hhbmRsZScsIHtzdGF0aWM6IHRydWV9KVxuICBwdWJsaWMgdGh1bWJFbGVtZW50ITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy52ZXJ0aWNhbCcpXG4gIHB1YmxpYyBnZXQgdmVydGljYWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlyZWN0aW9uID09PSAndnNjcm9sbCc7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmhvcml6b250YWwnKVxuICBwdWJsaWMgZ2V0IGhvcml6b250YWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlyZWN0aW9uID09PSAnaHNjcm9sbCc7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLnNjcm9sbGluZycpXG4gIHB1YmxpYyBnZXQgc2Nyb2xsaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uICE9PSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgZGlyZWN0aW9uIG9mIHRoZSBzY3JvbGxiYXIuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIGlmIG5vdCBzcGVjaWZpZWQsIHJlbmRlcnMgYSB2ZXJ0aWNhbCBzY3JvbGxiYXIuXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgZGlyZWN0aW9uOiAndnNjcm9sbCcgfCAnaHNjcm9sbCcgPSAndnNjcm9sbCc7XG5cbiAgLyoqXG4gICAqIFRoZSB2aWV3cG9ydCB0byBwcm92aWRlIHNjcm9sbGJhcnMgZm9yLlxuICAgKi9cbiAgQElucHV0KCd2aWV3cG9ydCcpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLWlucHV0LXJlbmFtZVxuICBwdWJsaWMgc2V0IHNldFZpZXdwb3J0KHZpZXdwb3J0OiBIVE1MRWxlbWVudCkge1xuICAgIHRoaXMuX3ZpZXdwb3J0ID0gdmlld3BvcnQ7XG4gICAgdGhpcy5fdmlld3BvcnRDaGFuZ2UkLm5leHQoKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2hvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgICAgICAgICAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIF9kb2N1bWVudDogYW55LFxuICAgICAgICAgICAgICBwcml2YXRlIF96b25lOiBOZ1pvbmUpIHtcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZSRcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fdmlld3BvcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbWVyZ2UoXG4gICAgICAgICAgICB0aGlzLnZpZXdwb3J0U2Nyb2xsQ2hhbmdlJCgpLFxuICAgICAgICAgICAgdGhpcy52aWV3cG9ydERpbWVuc2lvbkNoYW5nZSQoe2RlYm91bmNlVGltZTogU2NpU2Nyb2xsYmFyQ29tcG9uZW50LlZJRVdQT1JUX1JFU0laRV9ERUJPVU5DRV9USU1FfSksXG4gICAgICAgICAgICB0aGlzLnZpZXdwb3J0Q2xpZW50RGltZW5zaW9uQ2hhbmdlJCh7ZGVib3VuY2VUaW1lOiBTY2lTY3JvbGxiYXJDb21wb25lbnQuVklFV1BPUlRfUkVTSVpFX0RFQk9VTkNFX1RJTUV9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9KSxcbiAgICAgICAgc3Vic2NyaWJlSW5zaWRlKGNvbnRpbnVlRm4gPT4gdGhpcy5fem9uZS5ydW5PdXRzaWRlQW5ndWxhcihjb250aW51ZUZuKSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX3ZpZXdwb3J0KSB7XG4gICAgICAgICAgdGhpcy5yZW5kZXJTY3JvbGxQb3NpdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMudW5zZXRTY3JvbGxQb3NpdGlvbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgc2Nyb2xsIHBvc2l0aW9uIGFuZCB1cGRhdGVzIENTUyB2YXJpYWJsZXMgdG8gcmVuZGVyIHRoZSBzY3JvbGwgcG9zaXRpb24gaW4gdGhlIFVJLlxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXJTY3JvbGxQb3NpdGlvbigpOiB2b2lkIHtcbiAgICBOZ1pvbmUuYXNzZXJ0Tm90SW5Bbmd1bGFyWm9uZSgpO1xuICAgIGNvbnN0IHZpZXdwb3J0U2l6ZSA9IHRoaXMudmlld3BvcnRTaXplO1xuICAgIGNvbnN0IHZpZXdwb3J0Q2xpZW50U2l6ZSA9IHRoaXMudmlld3BvcnRDbGllbnRTaXplO1xuICAgIGNvbnN0IHRodW1iUG9zaXRpb25GciA9IHRoaXMuc2Nyb2xsUG9zaXRpb24gLyB2aWV3cG9ydENsaWVudFNpemU7XG4gICAgY29uc3QgdGh1bWJTaXplRnIgPSB2aWV3cG9ydFNpemUgLyB2aWV3cG9ydENsaWVudFNpemU7XG4gICAgY29uc3Qgb3ZlcmZsb3cgPSB2aWV3cG9ydENsaWVudFNpemUgPiB2aWV3cG9ydFNpemU7XG5cbiAgICBpZiAodGh1bWJQb3NpdGlvbkZyICE9PSB0aGlzLl90aHVtYlBvc2l0aW9uRnIgfHwgdGh1bWJTaXplRnIgIT09IHRoaXMuX3RodW1iU2l6ZUZyKSB7XG4gICAgICB0aGlzLl90aHVtYlBvc2l0aW9uRnIgPSB0aHVtYlBvc2l0aW9uRnI7XG4gICAgICB0aGlzLl90aHVtYlNpemVGciA9IHRodW1iU2l6ZUZyO1xuICAgICAgdGhpcy5zZXRDc3NWYXJpYWJsZSgnLS3JtXNjaS1zY3JvbGxiYXItdGh1bWItcG9zaXRpb24tZnInLCB0aHVtYlBvc2l0aW9uRnIpO1xuICAgICAgdGhpcy5zZXRDc3NWYXJpYWJsZSgnLS3JtXNjaS1zY3JvbGxiYXItdGh1bWItc2l6ZS1mcicsIHRodW1iU2l6ZUZyKTtcbiAgICB9XG5cbiAgICBpZiAob3ZlcmZsb3cgIT09IHRoaXMuX292ZXJmbG93KSB7XG4gICAgICB0aGlzLl9vdmVyZmxvdyA9IG92ZXJmbG93O1xuICAgICAgb3ZlcmZsb3cgPyB0aGlzLl9ob3N0Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnb3ZlcmZsb3cnKSA6IHRoaXMuX2hvc3QubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdvdmVyZmxvdycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgQ1NTIHZhcmlhYmxlcyB1c2VkIGZvciByZW5kZXJpbmcgdGhlIHNjcm9sbCBwb3NpdGlvbiBpbiB0aGUgVUkuXG4gICAqL1xuICBwcml2YXRlIHVuc2V0U2Nyb2xsUG9zaXRpb24oKTogdm9pZCB7XG4gICAgTmdab25lLmFzc2VydE5vdEluQW5ndWxhclpvbmUoKTtcbiAgICB0aGlzLl90aHVtYlBvc2l0aW9uRnIgPSAwO1xuICAgIHRoaXMuX3RodW1iU2l6ZUZyID0gMDtcbiAgICB0aGlzLl9vdmVyZmxvdyA9IGZhbHNlO1xuICAgIHRoaXMuc2V0Q3NzVmFyaWFibGUoJy0tybVzY2ktc2Nyb2xsYmFyLXRodW1iLXBvc2l0aW9uLWZyJywgMCk7XG4gICAgdGhpcy5zZXRDc3NWYXJpYWJsZSgnLS3JtXNjaS1zY3JvbGxiYXItdGh1bWItc2l6ZS1mcicsIDApO1xuICAgIHRoaXMuX2hvc3QubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdvdmVyZmxvdycpO1xuICB9XG5cbiAgLyogQGRvY3MtcHJpdmF0ZSAqL1xuICBwdWJsaWMgb25Ub3VjaFN0YXJ0KGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uID0gdGhpcy52ZXJ0aWNhbCA/IGV2ZW50LnRvdWNoZXNbMF0uc2NyZWVuWSA6IGV2ZW50LnRvdWNoZXNbMF0uc2NyZWVuWDtcbiAgfVxuXG4gIC8qIEBkb2NzLXByaXZhdGUgKi9cbiAgcHVibGljIG9uVG91Y2hNb3ZlKGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGNvbnN0IG5ld0RyYWdQb3NpdGlvblB4ID0gdGhpcy52ZXJ0aWNhbCA/IGV2ZW50LnRvdWNoZXNbMF0uc2NyZWVuWSA6IGV2ZW50LnRvdWNoZXNbMF0uc2NyZWVuWDtcbiAgICBjb25zdCBzY3JvbGxiYXJQYW5QeCA9IG5ld0RyYWdQb3NpdGlvblB4IC0gdGhpcy5fbGFzdERyYWdQb3NpdGlvbiE7XG4gICAgY29uc3Qgdmlld3BvcnRQYW5QeCA9IHRoaXMudG9WaWV3cG9ydFBhblB4KHNjcm9sbGJhclBhblB4KTtcbiAgICB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uID0gbmV3RHJhZ1Bvc2l0aW9uUHg7XG4gICAgdGhpcy5tb3ZlVmlld3BvcnRDbGllbnQodmlld3BvcnRQYW5QeCk7XG4gIH1cblxuICAvKiBAZG9jcy1wcml2YXRlICovXG4gIHB1YmxpYyBvblRvdWNoRW5kKGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uID0gbnVsbDtcbiAgfVxuXG4gIC8qIEBkb2NzLXByaXZhdGUgKi9cbiAgcHVibGljIG9uTW91c2VEb3duKG1vdXNlZG93bkV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKG1vdXNlZG93bkV2ZW50LmJ1dHRvbiAhPT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1vdXNlZG93bkV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5fbGFzdERyYWdQb3NpdGlvbiA9IHRoaXMudmVydGljYWwgPyBtb3VzZWRvd25FdmVudC5zY3JlZW5ZIDogbW91c2Vkb3duRXZlbnQuc2NyZWVuWDtcblxuICAgIC8vIExpc3RlbiBmb3IgJ21vdXNlbW92ZScgZXZlbnRzXG4gICAgdGhpcy5fem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBjb25zdCBtb3VzZW1vdmVMaXN0ZW5lciA9IG1lcmdlKGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLl9kb2N1bWVudCwgJ21vdXNlbW92ZScpLCBmcm9tRXZlbnQ8TW91c2VFdmVudD4odGhpcy5fZG9jdW1lbnQsICdzY2ktbW91c2Vtb3ZlJykpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUobW91c2Vtb3ZlRXZlbnQgPT4ge1xuICAgICAgICAgIG1vdXNlbW92ZUV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICBjb25zdCBuZXdEcmFnUG9zaXRpb25QeCA9IHRoaXMudmVydGljYWwgPyBtb3VzZW1vdmVFdmVudC5zY3JlZW5ZIDogbW91c2Vtb3ZlRXZlbnQuc2NyZWVuWDtcbiAgICAgICAgICBjb25zdCBzY3JvbGxiYXJQYW5QeCA9IG5ld0RyYWdQb3NpdGlvblB4IC0gdGhpcy5fbGFzdERyYWdQb3NpdGlvbiE7XG4gICAgICAgICAgY29uc3Qgdmlld3BvcnRQYW5QeCA9IHRoaXMudG9WaWV3cG9ydFBhblB4KHNjcm9sbGJhclBhblB4KTtcbiAgICAgICAgICB0aGlzLl9sYXN0RHJhZ1Bvc2l0aW9uID0gbmV3RHJhZ1Bvc2l0aW9uUHg7XG4gICAgICAgICAgdGhpcy5tb3ZlVmlld3BvcnRDbGllbnQodmlld3BvcnRQYW5QeCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBMaXN0ZW4gZm9yICdtb3VzZXVwJyBldmVudHM7IHVzZSAnY2FwdHVyZSBwaGFzZScgYW5kICdzdG9wIHByb3BhZ2F0aW9uJyB0byBub3QgY2xvc2Ugb3ZlcmxheXNcbiAgICAgIG1lcmdlKGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLl9kb2N1bWVudCwgJ21vdXNldXAnLCB7Y2FwdHVyZTogdHJ1ZX0pLCBmcm9tRXZlbnQ8TW91c2VFdmVudD4odGhpcy5fZG9jdW1lbnQsICdzY2ktbW91c2V1cCcpKVxuICAgICAgICAucGlwZShmaXJzdCgpLCB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKG1vdXNldXBFdmVudCA9PiB7XG4gICAgICAgICAgbW91c2V1cEV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgIG1vdXNlbW92ZUxpc3RlbmVyLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgdGhpcy5fbGFzdERyYWdQb3NpdGlvbiA9IG51bGw7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyogQGRvY3MtcHJpdmF0ZSAqL1xuICBwdWJsaWMgb25TY3JvbGxUcmFja01vdXNlRG93bihldmVudDogTW91c2VFdmVudCwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKTogdm9pZCB7XG4gICAgY29uc3Qgc2lnbnVtID0gKGRpcmVjdGlvbiA9PT0gJ3VwJyA/IC0xIDogKzEpO1xuICAgIHRoaXMuc2Nyb2xsV2hpbGVNb3VzZURvd24odGhpcy50b1ZpZXdwb3J0UGFuUHgoc2lnbnVtICogdGhpcy50aHVtYlNpemUpLCBldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdHMgdGhlIGdpdmVuIHNjcm9sbGJhciBzY3JvbGwgcGl4ZWxzIGludG8gdmlld3BvcnQgc2Nyb2xsIHBpeGVscy5cbiAgICovXG4gIHByaXZhdGUgdG9WaWV3cG9ydFBhblB4KHNjcm9sbGJhclBhblB4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IHNjcm9sbFJhbmdlUHggPSB0aGlzLnRyYWNrU2l6ZSAtIHRoaXMudGh1bWJTaXplO1xuICAgIGNvbnN0IHNjcm9sbFJhdGlvID0gc2Nyb2xsYmFyUGFuUHggLyBzY3JvbGxSYW5nZVB4O1xuICAgIHJldHVybiBzY3JvbGxSYXRpbyAqICh0aGlzLnZpZXdwb3J0Q2xpZW50U2l6ZSAtIHRoaXMudmlld3BvcnRTaXplKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlcyB0aGUgdmlld3BvcnQgY2xpZW50IGJ5IHRoZSBzcGVjaWZpZWQgbnVtYmVycyBvZiBwaXhlbHMuXG4gICAqL1xuICBwcml2YXRlIG1vdmVWaWV3cG9ydENsaWVudCh2aWV3cG9ydFBhblB4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52ZXJ0aWNhbCkge1xuICAgICAgdGhpcy5fdmlld3BvcnQuc2Nyb2xsVG9wICs9IHZpZXdwb3J0UGFuUHg7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5fdmlld3BvcnQuc2Nyb2xsTGVmdCArPSB2aWV3cG9ydFBhblB4O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGNvbnRlbnQgb3ZlcmZsb3dzLlxuICAgKi9cbiAgcHVibGljIGdldCBvdmVyZmxvdygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fb3ZlcmZsb3c7XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xscyBjb250aW51b3VzbHkgd2hpbGUgaG9sZGluZyB0aGUgbW91c2UgcHJlc3NlZCwgb3IgdW50aWwgdGhlIG1vdXNlIGxlYXZlcyB0aGUgc2Nyb2xsdHJhY2suXG4gICAqL1xuICBwcml2YXRlIHNjcm9sbFdoaWxlTW91c2VEb3duKHZpZXdwb3J0U2Nyb2xsUHg6IG51bWJlciwgbW91c2Vkb3duRXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBUaGUgYEV2ZW50VGFyZ2V0YCB0eXBlIG9mIGBFdmVudC50YXJnZXRgIGlzIG5vdCB5ZXQgY29tcGF0aWJsZSB3aXRoIGBGcm9tRXZlbnRUYXJnZXRgIHVzZWQgaW4gYGZyb21FdmVudGAuXG4gICAgLy8gVGhpcyB3aWxsIGJlIGZpeGVkIGluIHJ4anMgdmVyc2lvbiA3LjAuMC4gUmVmZXIgdG8gaHR0cHM6Ly9naXRodWIuY29tL1JlYWN0aXZlWC9yeGpzL2NvbW1pdC81ZjAyMmQ3ODQ1NzA2ODQ2MzJlNmZkNWFlMjQ3ZmMyNTllZTM0YzRiXG4gICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICBjb25zdCBzY3JvbGxUcmFja0VsZW1lbnQgPSBtb3VzZWRvd25FdmVudC50YXJnZXQgYXMgRWxlbWVudDtcblxuICAgIC8vIHNjcm9sbCBjb250aW51b3VzbHkgZXZlcnkgNTBtcyBhZnRlciBhbiBpbml0aWFsIGRlbGF5IG9mIDI1MG1zXG4gICAgdGltZXIoMjUwLCA1MClcbiAgICAgIC5waXBlKFxuICAgICAgICAvLyBjb250aW51ZSBjaGFpbiB3aXRoIGxhdGVzdCBtb3VzZSBldmVudFxuICAgICAgICB3aXRoTGF0ZXN0RnJvbShtZXJnZShvZihtb3VzZWRvd25FdmVudCksIGZyb21FdmVudDxNb3VzZUV2ZW50PihzY3JvbGxUcmFja0VsZW1lbnQsICdtb3VzZW1vdmUnKSksICh0aWNrLCBldmVudCkgPT4gZXZlbnQpLFxuICAgICAgICAvLyBzdGFydCBpbW1lZGlhdGVseVxuICAgICAgICBzdGFydFdpdGgobW91c2Vkb3duRXZlbnQpLFxuICAgICAgICAvLyBzdG9wIHNjcm9sbGluZyBpZiB0aGUgdGh1bWIgaGl0cyB0aGUgbW91c2UgcG9pbnRlciBwb3NpdGlvblxuICAgICAgICB0YWtlV2hpbGUoKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiBzY3JvbGxUcmFja0VsZW1lbnQgPT09IHRoaXMuX2RvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSkpLFxuICAgICAgICBkZWJvdW5jZVRpbWUoMTApLFxuICAgICAgICAvLyBzdG9wIHNjcm9sbGluZyBvbiBtb3VzZW91dCBvciBtb3VzZXVwXG4gICAgICAgIHRha2VVbnRpbChtZXJnZShmcm9tRXZlbnQoc2Nyb2xsVHJhY2tFbGVtZW50LCAnbW91c2VvdXQnKSwgZnJvbUV2ZW50KHNjcm9sbFRyYWNrRWxlbWVudCwgJ21vdXNldXAnKSkpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMubW92ZVZpZXdwb3J0Q2xpZW50KHZpZXdwb3J0U2Nyb2xsUHgpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgd2hlbmV2ZXIgdGhlIHZpZXdwb3J0IHNjcm9sbHMuXG4gICAqL1xuICBwcml2YXRlIHZpZXdwb3J0U2Nyb2xsQ2hhbmdlJCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gZnJvbUV2ZW50KHRoaXMuX3ZpZXdwb3J0LCAnc2Nyb2xsJywge3Bhc3NpdmU6IHRydWV9KS5waXBlKG1hcCgoKSA9PiB1bmRlZmluZWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBvbiBzdWJzY3JpcHRpb24sIGFuZCB0aGVuIGVhY2ggdGltZSB0aGUgc2l6ZSBvZiB0aGUgdmlld3BvcnQgY2hhbmdlcy5cbiAgICovXG4gIHByaXZhdGUgdmlld3BvcnREaW1lbnNpb25DaGFuZ2UkKG9wdGlvbnM6IHtkZWJvdW5jZVRpbWU6IG51bWJlcn0pOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gZnJvbURpbWVuc2lvbiQodGhpcy5fdmlld3BvcnQpXG4gICAgICAucGlwZShcbiAgICAgICAgLy8gRGVib3VuY2luZyBpcyBwYXJ0aWN1bGFybHkgaW1wb3J0YW50IGluIHRoZSBjb250ZXh0IG9mIEFuZ3VsYXIgYW5pbWF0aW9ucywgc2luY2UgdGhleSBjb250aW51b3VzbHlcbiAgICAgICAgLy8gdHJpZ2dlciByZXNpemUgZXZlbnRzLiBEZWJvdW5jaW5nIHByZXZlbnRzIHRoZSBzY3JvbGxiYXIgZnJvbSBmbGlja2VyaW5nLCBmb3IgZXhhbXBsZSwgd2hlbiB0aGUgdXNlclxuICAgICAgICAvLyBleHBhbmRzIGEgcGFuZWwgdGhhdCBjb250YWlucyBhIHZpZXdwb3J0LlxuICAgICAgICBkZWJvdW5jZVRpbWUob3B0aW9ucy5kZWJvdW5jZVRpbWUpLFxuICAgICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkKSxcbiAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgb24gc3Vic2NyaXB0aW9uLCBhbmQgdGhlbiBlYWNoIHRpbWUgdGhlIHNpemUgb3Igc3R5bGUgcHJvcGVydHkgb2YgdGhlIHZpZXdwb3J0IGNsaWVudCBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSB2aWV3cG9ydENsaWVudERpbWVuc2lvbkNoYW5nZSQob3B0aW9uczoge2RlYm91bmNlVGltZTogbnVtYmVyfSk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuJCh0aGlzLl92aWV3cG9ydClcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoY2hpbGRyZW4gPT4gbWVyZ2UoLi4uY2hpbGRyZW4ubWFwKGNoaWxkID0+IG1lcmdlKFxuICAgICAgICAgIGZyb21EaW1lbnNpb24kKGNoaWxkKSxcbiAgICAgICAgICAvLyBPYnNlcnZlIHN0eWxlIG11dGF0aW9ucyBzaW5jZSBzb21lIHRyYW5zZm9ybWF0aW9ucyBjaGFuZ2UgdGhlIHNjcm9sbCBwb3NpdGlvbiB3aXRob3V0IG5lY2Vzc2FyaWx5IHRyaWdnZXJpbmcgYSBkaW1lbnNpb24gY2hhbmdlLFxuICAgICAgICAgIC8vIGUuZy4sIGBzY2FsZWAgb3IgYHRyYW5zbGF0ZWAgdXNlZCBieSBzb21lIHZpcnR1YWwgc2Nyb2xsIGltcGxlbWVudGF0aW9uc1xuICAgICAgICAgIGZyb21NdXRhdGlvbiQoY2hpbGQsIHtzdWJ0cmVlOiBmYWxzZSwgY2hpbGRMaXN0OiBmYWxzZSwgYXR0cmlidXRlRmlsdGVyOiBbJ3N0eWxlJ119KSksXG4gICAgICAgICkpKSxcbiAgICAgICAgLy8gRGVib3VuY2luZyBpcyBwYXJ0aWN1bGFybHkgaW1wb3J0YW50IGluIHRoZSBjb250ZXh0IG9mIEFuZ3VsYXIgYW5pbWF0aW9ucywgc2luY2UgdGhleSBjb250aW51b3VzbHlcbiAgICAgICAgLy8gdHJpZ2dlciByZXNpemUgZXZlbnRzLiBEZWJvdW5jaW5nIHByZXZlbnRzIHRoZSBzY3JvbGxiYXIgZnJvbSBmbGlja2VyaW5nLCBmb3IgZXhhbXBsZSwgd2hlbiB0aGUgdXNlclxuICAgICAgICAvLyBleHBhbmRzIGEgcGFuZWwgdGhhdCBjb250YWlucyBhIHZpZXdwb3J0LlxuICAgICAgICBkZWJvdW5jZVRpbWUob3B0aW9ucy5kZWJvdW5jZVRpbWUpLFxuICAgICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkKSxcbiAgICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgdGhlIGNoaWxkcmVuIG9mIHRoZSBwYXNzZWQgZWxlbWVudCwgYW5kIHRoZW4gZWFjaCB0aW1lIGNoaWxkIGVsZW1lbnRzIGFyZSBhZGRlZCBvciByZW1vdmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjaGlsZHJlbiQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBPYnNlcnZhYmxlPEhUTUxFbGVtZW50W10+IHtcbiAgICByZXR1cm4gZnJvbU11dGF0aW9uJChlbGVtZW50LCB7c3VidHJlZTogZmFsc2UsIGNoaWxkTGlzdDogdHJ1ZX0pXG4gICAgICAucGlwZShcbiAgICAgICAgc3RhcnRXaXRoKHVuZGVmaW5lZCBhcyB2b2lkKSxcbiAgICAgICAgbWFwKCgpID0+IEFycmF5LmZyb20oZWxlbWVudC5jaGlsZHJlbikpLFxuICAgICAgICBmaWx0ZXJBcnJheSgoY2hpbGQ6IEVsZW1lbnQpOiBjaGlsZCBpcyBIVE1MRWxlbWVudCA9PiBjaGlsZCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSxcbiAgICAgICk7XG4gIH1cblxuICBwcml2YXRlIHNldENzc1ZhcmlhYmxlKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5faG9zdC5uYXRpdmVFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KGtleSwgdmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgdmlld3BvcnRTaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3ZpZXdwb3J0ID8gKHRoaXMudmVydGljYWwgPyB0aGlzLl92aWV3cG9ydC5jbGllbnRIZWlnaHQgOiB0aGlzLl92aWV3cG9ydC5jbGllbnRXaWR0aCkgOiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgdmlld3BvcnRDbGllbnRTaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3ZpZXdwb3J0ID8gKHRoaXMudmVydGljYWwgPyB0aGlzLl92aWV3cG9ydC5zY3JvbGxIZWlnaHQgOiB0aGlzLl92aWV3cG9ydC5zY3JvbGxXaWR0aCkgOiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgc2Nyb2xsUG9zaXRpb24oKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fdmlld3BvcnQgPyAodGhpcy52ZXJ0aWNhbCA/IHRoaXMuX3ZpZXdwb3J0LnNjcm9sbFRvcCA6IHRoaXMuX3ZpZXdwb3J0LnNjcm9sbExlZnQpIDogMDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHRodW1iU2l6ZSgpOiBudW1iZXIge1xuICAgIGNvbnN0IHRodW1iRWxlbWVudCA9IHRoaXMudGh1bWJFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgcmV0dXJuIHRoaXMudmVydGljYWwgPyB0aHVtYkVsZW1lbnQuY2xpZW50SGVpZ2h0IDogdGh1bWJFbGVtZW50LmNsaWVudFdpZHRoO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgdHJhY2tTaXplKCk6IG51bWJlciB7XG4gICAgY29uc3QgdHJhY2tFbGVtZW50ID0gdGhpcy5faG9zdC5uYXRpdmVFbGVtZW50O1xuICAgIHJldHVybiB0aGlzLnZlcnRpY2FsID8gdHJhY2tFbGVtZW50LmNsaWVudEhlaWdodCA6IHRyYWNrRWxlbWVudC5jbGllbnRXaWR0aDtcbiAgfVxuXG4gIC8qIEBkb2NzLXByaXZhdGUgKi9cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX2Rlc3Ryb3kkLm5leHQoKTtcbiAgfVxufVxuIiwiPCEtLSBzY3JvbGx0cmFjayB0byBtb3ZlIHRoZSB2aWV3cG9ydCBjbGllbnQgdXB3YXJkcyAocGFnaW5nKSAtLT5cbjxkaXYgY2xhc3M9XCJzY3JvbGx0cmFjay1zdGFydFwiIChtb3VzZWRvd24pPVwib25TY3JvbGxUcmFja01vdXNlRG93bigkZXZlbnQsICd1cCcpXCI+PC9kaXY+XG5cbjwhLS0gc2Nyb2xsdGh1bWIgLS0+XG48ZGl2ICN0aHVtYl9oYW5kbGVcbiAgICAgY2xhc3M9XCJ0aHVtYi1oYW5kbGVcIlxuICAgICBbY2xhc3MudmVydGljYWxdPVwidmVydGljYWxcIlxuICAgICBbY2xhc3MuaG9yaXpvbnRhbF09XCJob3Jpem9udGFsXCJcbiAgICAgKG1vdXNlZG93bik9XCJvbk1vdXNlRG93bigkZXZlbnQpXCJcbiAgICAgKHRvdWNoc3RhcnQpPVwib25Ub3VjaFN0YXJ0KCRldmVudClcIlxuICAgICAodG91Y2htb3ZlKT1cIm9uVG91Y2hNb3ZlKCRldmVudClcIlxuICAgICAodG91Y2hlbmQpPVwib25Ub3VjaEVuZCgkZXZlbnQpXCJcbiAgICAgKHRvdWNoY2FuY2VsKT1cIm9uVG91Y2hFbmQoJGV2ZW50KVwiPlxuICA8ZGl2IGNsYXNzPVwidGh1bWJcIlxuICAgICAgIFtjbGFzcy52ZXJ0aWNhbF09XCJ2ZXJ0aWNhbFwiXG4gICAgICAgW2NsYXNzLmhvcml6b250YWxdPVwiaG9yaXpvbnRhbFwiPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48IS0tIHNjcm9sbHRyYWNrIHRvIG1vdmUgdGhlIHZpZXdwb3J0IGNsaWVudCBkb3dud2FyZHMgKHBhZ2luZykgLS0+XG48ZGl2IGNsYXNzPVwic2Nyb2xsdHJhY2stZW5kXCIgKG1vdXNlZG93bik9XCJvblNjcm9sbFRyYWNrTW91c2VEb3duKCRldmVudCwgJ2Rvd24nKVwiPjwvZGl2PlxuIl19
|