d1c1d401d40b69c501330cb974b8aa2d9b820620
[sdc/sdc-workflow-designer.git] /
1 /**
2  * @license
3  * Copyright Google Inc. All Rights Reserved.
4  *
5  * Use of this source code is governed by an MIT-style license that can be
6  * found in the LICENSE file at https://angular.io/license
7  */
8 /* tslint:disable:array-type member-access variable-name typedef
9  only-arrow-functions directive-class-suffix component-class-suffix
10  component-selector*/
11 import {ViewportRuler} from '../position/viewport-ruler';
12
13 import {ScrollStrategy} from './scroll-strategy';
14
15 /**
16  * Strategy that will prevent the user from scrolling while the overlay is
17  * visible.
18  */
19 export class BlockScrollStrategy implements ScrollStrategy {
20   private _previousHTMLStyles = {top: '', left: ''};
21   private _previousScrollPosition: {top: number, left: number};
22   private _isEnabled = false;
23
24   constructor(private _viewportRuler: ViewportRuler) {}
25
26   attach() {
27     //
28   }
29
30   enable() {
31         if (this._canBeEnabled()) {
32                 const root = document.documentElement;
33
34                 this._previousScrollPosition =
35                         this._viewportRuler.getViewportScrollPosition();
36
37       // Cache the previous inline styles in case the user had set them.
38                 this._previousHTMLStyles.left = root.style.left || '';
39                 this._previousHTMLStyles.top = root.style.top || '';
40
41       // Note: we're using the `html` node, instead of the `body`, because the
42       // `body` may have the user agent margin, whereas the `html` is guaranteed
43       // not to have one.
44                 root.style.left = `${- this._previousScrollPosition.left}px`;
45                 root.style.top = `${- this._previousScrollPosition.top}px`;
46                 root.classList.add('cdk-global-scrollblock');
47                 this._isEnabled = true;
48         }
49   }
50
51   disable() {
52         if (this._isEnabled) {
53                 this._isEnabled = false;
54                 document.documentElement.style.left = this._previousHTMLStyles.left;
55                 document.documentElement.style.top = this._previousHTMLStyles.top;
56                 document.documentElement.classList.remove('cdk-global-scrollblock');
57                 window.scroll(
58                         this._previousScrollPosition.left, this._previousScrollPosition.top);
59         }
60   }
61
62   private _canBeEnabled(): boolean {
63     // Since the scroll strategies can't be singletons, we have to use a global
64     // CSS class
65     // (`cdk-global-scrollblock`) to make sure that we don't try to disable
66     // global scrolling multiple times.
67         if (document.documentElement.classList.contains('cdk-global-scrollblock') ||
68                 this._isEnabled) {
69                 return false;
70         }
71
72         const body = document.body;
73         const viewport = this._viewportRuler.getViewportRect();
74         return body.scrollHeight > viewport.height ||
75                 body.scrollWidth > viewport.width;
76   }
77 }