1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = isElementClickable;
|
7 |
|
8 | function isElementClickable(elem) {
|
9 | if (!elem.getBoundingClientRect || !elem.scrollIntoView || !elem.contains || !elem.getClientRects || !document.elementFromPoint) {
|
10 | return false;
|
11 | }
|
12 |
|
13 | const isOldEdge = !!window.StyleMedia;
|
14 | const scrollIntoViewFullSupport = !(window.safari || isOldEdge);
|
15 |
|
16 | function getOverlappingElement(elem, context) {
|
17 | context = context || document;
|
18 | const elemDimension = elem.getBoundingClientRect();
|
19 | const x = elemDimension.left + elem.clientWidth / 2;
|
20 | const y = elemDimension.top + elem.clientHeight / 2;
|
21 | return context.elementFromPoint(x, y);
|
22 | }
|
23 |
|
24 | function getOverlappingRects(elem, context) {
|
25 | context = context || document;
|
26 | const elems = [];
|
27 | const rects = elem.getClientRects();
|
28 | const rect = rects[0];
|
29 | const x = rect.left + rect.width / 2;
|
30 | const y = rect.top + rect.height / 2;
|
31 | elems.push(context.elementFromPoint(x, y));
|
32 | return elems;
|
33 | }
|
34 |
|
35 | function getOverlappingElements(elem, context) {
|
36 | return [getOverlappingElement(elem, context)].concat(getOverlappingRects(elem, context));
|
37 | }
|
38 |
|
39 | function nodeContains(elem, otherNode) {
|
40 | if (isOldEdge) {
|
41 | let tmpElement = otherNode;
|
42 |
|
43 | while (tmpElement) {
|
44 | if (tmpElement === elem) {
|
45 | return true;
|
46 | }
|
47 |
|
48 | tmpElement = tmpElement.parentNode;
|
49 |
|
50 | if (tmpElement && tmpElement.nodeType === 11 && tmpElement.host) {
|
51 | tmpElement = tmpElement.host;
|
52 | }
|
53 | }
|
54 |
|
55 | return false;
|
56 | }
|
57 |
|
58 | return elem.contains(otherNode);
|
59 | }
|
60 |
|
61 | function isOverlappingElementMatch(elementsFromPoint, elem) {
|
62 | if (elementsFromPoint.some(function (elementFromPoint) {
|
63 | return elementFromPoint === elem || nodeContains(elem, elementFromPoint);
|
64 | })) {
|
65 | return true;
|
66 | }
|
67 |
|
68 | let elemsWithShadowRoot = [].concat(elementsFromPoint);
|
69 | elemsWithShadowRoot = elemsWithShadowRoot.filter(function (x) {
|
70 | return x && x.shadowRoot && x.shadowRoot.elementFromPoint;
|
71 | });
|
72 | let shadowElementsFromPoint = [];
|
73 |
|
74 | for (let i = 0; i < elemsWithShadowRoot.length; ++i) {
|
75 | let shadowElement = elemsWithShadowRoot[i];
|
76 | shadowElementsFromPoint = shadowElementsFromPoint.concat(getOverlappingElements(elem, shadowElement.shadowRoot));
|
77 | }
|
78 |
|
79 | shadowElementsFromPoint = [].concat(shadowElementsFromPoint);
|
80 | shadowElementsFromPoint = shadowElementsFromPoint.filter(function (x) {
|
81 | return !elementsFromPoint.includes(x);
|
82 | });
|
83 |
|
84 | if (shadowElementsFromPoint.length === 0) {
|
85 | return false;
|
86 | }
|
87 |
|
88 | return isOverlappingElementMatch(shadowElementsFromPoint, elem);
|
89 | }
|
90 |
|
91 | function isElementInViewport(elem) {
|
92 | if (!elem.getBoundingClientRect) {
|
93 | return false;
|
94 | }
|
95 |
|
96 | const rect = elem.getBoundingClientRect();
|
97 | const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
98 | const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
99 | const vertInView = rect.top <= windowHeight && rect.top + rect.height > 0;
|
100 | const horInView = rect.left <= windowWidth && rect.left + rect.width > 0;
|
101 | return vertInView && horInView;
|
102 | }
|
103 |
|
104 | function isClickable(elem) {
|
105 | return isElementInViewport(elem) && elem.disabled !== true && isOverlappingElementMatch(getOverlappingElements(elem), elem);
|
106 | }
|
107 |
|
108 | if (!isClickable(elem)) {
|
109 | elem.scrollIntoView(scrollIntoViewFullSupport ? {
|
110 | block: 'nearest',
|
111 | inline: 'nearest'
|
112 | } : false);
|
113 |
|
114 | if (!isClickable(elem)) {
|
115 | elem.scrollIntoView(scrollIntoViewFullSupport ? {
|
116 | block: 'center',
|
117 | inline: 'center'
|
118 | } : true);
|
119 | return isClickable(elem);
|
120 | }
|
121 | }
|
122 |
|
123 | return true;
|
124 | } |
\ | No newline at end of file |