-
Notifications
You must be signed in to change notification settings - Fork 659
/
scroll.ts
82 lines (57 loc) · 2.78 KB
/
scroll.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import adapter from './adapter/index';
const SCROLLABLE_OVERFLOW_STYLE_RE = /auto|scroll/i;
function hasBodyScroll (el: HTMLBodyElement): boolean {
const overflowX = adapter.style.get(el, 'overflowX') as string;
const overflowY = adapter.style.get(el, 'overflowY') as string;
const scrollableHorizontally = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowX);
const scrollableVertically = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowY);
const documentElement = adapter.dom.findDocument(el).documentElement;
let bodyScrollHeight = el.scrollHeight;
if (adapter.browser.isChrome || adapter.browser.isFirefox || adapter.browser.isSafari) {
const { top: bodyTop } = el.getBoundingClientRect();
const { top: documentTop } = documentElement.getBoundingClientRect();
bodyScrollHeight = bodyScrollHeight - documentTop + bodyTop;
}
return (scrollableHorizontally || scrollableVertically) &&
bodyScrollHeight > documentElement.scrollHeight;
}
function hasHTMLElementScroll (el: HTMLHtmlElement): boolean {
const overflowX = adapter.style.get(el, 'overflowX') as string;
const overflowY = adapter.style.get(el, 'overflowY') as string;
//T303226
if (overflowX === 'hidden' && overflowY === 'hidden')
return false;
const hasHorizontalScroll = el.scrollHeight > el.clientHeight;
const hasVerticalScroll = el.scrollWidth > el.clientWidth;
if (hasHorizontalScroll || hasVerticalScroll)
return true;
//T174562 - wrong scrolling in iframes without src and others iframes
const body = el.getElementsByTagName('body')[0];
if (!body)
return false;
if (hasBodyScroll(body))
return false;
const clientWidth = Math.min(el.clientWidth, body.clientWidth);
const clientHeight = Math.min(el.clientHeight, body.clientHeight);
return body.scrollHeight > clientHeight || body.scrollWidth > clientWidth;
}
export function hasScroll (el: Element): boolean {
if (adapter.dom.isBodyElement(el))
return hasBodyScroll(el);
if (adapter.dom.isHtmlElement(el))
return hasHTMLElementScroll(el);
const hasVerticalScroll = el.scrollHeight > el.clientHeight;
const hasHorizontalScroll = el.scrollWidth > el.clientWidth;
return hasHorizontalScroll || hasVerticalScroll;
}
export function getScrollableParents (element: Element): Element[] {
const parentsArray = adapter.dom.getParents(element);
if (adapter.dom.isElementInIframe(element)) {
const iframe = adapter.dom.getIframeByElement(element);
if (iframe) {
const iFrameParents = adapter.dom.getParents(iframe);
parentsArray.concat(iFrameParents);
}
}
return adapter.nativeMethods.arrayFilter.call(parentsArray, hasScroll);
}