intersection-observer 0.4.1 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +16 -2
- package/border-test.html +47 -0
- package/frame1.html +9 -0
- package/frame2.html +9 -0
- package/frames.html +33 -0
- package/intersection-observer-test.html +3 -11
- package/intersection-observer-test.js +20 -13
- package/intersection-observer.js +26 -25
- package/package.json +4 -4
- package/slot.html +93 -0
- package/.npmignore +0 -3
package/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# `IntersectionObserver` polyfill
|
2
2
|
|
3
|
-
This library polyfills the native [`IntersectionObserver`](http://
|
3
|
+
This library polyfills the native [`IntersectionObserver`](http://w3c.github.io/IntersectionObserver/) API in unsupporting browsers. See the [API documentation](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) for usage information.
|
4
4
|
|
5
5
|
- [Installation](#installation)
|
6
6
|
- [Configuring the polyfill](#configuring-the-polyfill)
|
@@ -9,7 +9,7 @@ This library polyfills the native [`IntersectionObserver`](http://wicg.github.io
|
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
12
|
-
You can install the polyfill via npm or by downloading a [zip](https://github.com/
|
12
|
+
You can install the polyfill via npm or by downloading a [zip](https://github.com/w3c/IntersectionObserver/archive/gh-pages.zip) of this repository:
|
13
13
|
|
14
14
|
```sh
|
15
15
|
npm install intersection-observer
|
@@ -81,6 +81,20 @@ io.observe(someTargetElement);
|
|
81
81
|
|
82
82
|
**Note:** the `POLL_INTERVAL` property must be set prior to calling the `.observe` method, or the default configuration will be used.
|
83
83
|
|
84
|
+
**Ignoring DOM changes**
|
85
|
+
|
86
|
+
You can also choose to not check for intersections when the DOM changes by setting an observer's `USE_MUTATION_OBSERVER` property to `false` (either globally on the prototype or per-instance)
|
87
|
+
|
88
|
+
```js
|
89
|
+
IntersectionObserver.prototype.USE_MUTATION_OBSERVER = false; // Globally
|
90
|
+
|
91
|
+
// for an instance
|
92
|
+
var io = new IntersectionObserver(callback);
|
93
|
+
io.USE_MUTATION_OBSERVER = false;
|
94
|
+
```
|
95
|
+
|
96
|
+
This is recommended in cases where the DOM will update frequently but you know those updates will have no affect on the position or your target elements.
|
97
|
+
|
84
98
|
## Browser support
|
85
99
|
|
86
100
|
The polyfill has been tested and known to work in the latest version of all browsers.
|
package/border-test.html
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<script>
|
6
|
+
// delete window.IntersectionObserver;
|
7
|
+
</script>
|
8
|
+
<script src="intersection-observer.js"></script>
|
9
|
+
<script>
|
10
|
+
function init() {
|
11
|
+
function callback(entries, observer) {
|
12
|
+
Array.prototype.forEach.call(entries, function(entry) {
|
13
|
+
if (entry.intersectionRatio > 0) {
|
14
|
+
entry.target.classList.add('visible');
|
15
|
+
}
|
16
|
+
});
|
17
|
+
}
|
18
|
+
var observer = new IntersectionObserver(callback, { root: document.getElementById('outer') });
|
19
|
+
Array.prototype.forEach.call(document.querySelectorAll('#outer div'), function(el) {
|
20
|
+
observer.observe(el);
|
21
|
+
});
|
22
|
+
}
|
23
|
+
window.addEventListener('load', init);
|
24
|
+
</script>
|
25
|
+
<style>
|
26
|
+
#outer {
|
27
|
+
overflow-y: hidden;
|
28
|
+
height: 2em;
|
29
|
+
border: 10px solid #0000;
|
30
|
+
}
|
31
|
+
#outer div {
|
32
|
+
height: 100%;
|
33
|
+
}
|
34
|
+
#el2 {
|
35
|
+
background: red;
|
36
|
+
}
|
37
|
+
|
38
|
+
</style>
|
39
|
+
</head>
|
40
|
+
<body>
|
41
|
+
<div id="outer">
|
42
|
+
<div id="el1">Element 1</div>
|
43
|
+
<div id="el2">Element 2</div>
|
44
|
+
<div id="el3">Element 3</div>
|
45
|
+
</div>
|
46
|
+
</body>
|
47
|
+
</html>
|
package/frame1.html
ADDED
package/frame2.html
ADDED
package/frames.html
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
<!--
|
2
|
+
Copyright 2016 Google Inc. All Rights Reserved.
|
3
|
+
|
4
|
+
Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
|
5
|
+
|
6
|
+
https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
7
|
+
-->
|
8
|
+
<!DOCTYPE html>
|
9
|
+
<html lang="en">
|
10
|
+
<head>
|
11
|
+
<meta charset="utf-8">
|
12
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
13
|
+
<title>IntersectionObserver Tests</title>
|
14
|
+
|
15
|
+
<!-- Dependencies -->
|
16
|
+
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.5.3/mocha.min.css">
|
17
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.5.3/mocha.min.js"></script>
|
18
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
|
19
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/3.2.1/sinon.min.js"></script>
|
20
|
+
|
21
|
+
-->
|
22
|
+
|
23
|
+
<styles>
|
24
|
+
|
25
|
+
</styles>
|
26
|
+
</head>
|
27
|
+
<body>
|
28
|
+
|
29
|
+
<iframe src="frame1.html"></iframe>
|
30
|
+
<iframe src="frame2.html"></iframe>
|
31
|
+
|
32
|
+
</body>
|
33
|
+
</html>
|
@@ -1,17 +1,9 @@
|
|
1
1
|
<!--
|
2
2
|
Copyright 2016 Google Inc. All Rights Reserved.
|
3
3
|
|
4
|
-
Licensed under the
|
5
|
-
you may not use this file except in compliance with the License.
|
6
|
-
You may obtain a copy of the License at
|
4
|
+
Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
See the License for the specific language governing permissions and
|
14
|
-
limitations under the License.
|
6
|
+
https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
15
7
|
-->
|
16
8
|
<!DOCTYPE html>
|
17
9
|
<html lang="en">
|
@@ -24,7 +16,7 @@ limitations under the License.
|
|
24
16
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.5.3/mocha.min.css">
|
25
17
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.5.3/mocha.min.js"></script>
|
26
18
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect.js/0.2.0/expect.min.js"></script>
|
27
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/
|
19
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/3.2.1/sinon.min.js"></script>
|
28
20
|
|
29
21
|
<!-- Polyfills for IE7-8 -->
|
30
22
|
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es5,getComputedStyle"></script>
|
@@ -1,17 +1,10 @@
|
|
1
1
|
/**
|
2
2
|
* Copyright 2016 Google Inc. All Rights Reserved.
|
3
3
|
*
|
4
|
-
* Licensed under the
|
5
|
-
* you may not use this file except in compliance with the License.
|
6
|
-
* You may obtain a copy of the License at
|
4
|
+
* Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
|
7
5
|
*
|
8
|
-
*
|
6
|
+
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
9
7
|
*
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
* See the License for the specific language governing permissions and
|
14
|
-
* limitations under the License.
|
15
8
|
*/
|
16
9
|
|
17
10
|
|
@@ -142,14 +135,14 @@ describe('IntersectionObserver', function() {
|
|
142
135
|
it('throws when a threshold is not a number', function() {
|
143
136
|
expect(function() {
|
144
137
|
io = new IntersectionObserver(noop, {threshold: ['foo']});
|
145
|
-
}).to.throwException(
|
138
|
+
}).to.throwException();
|
146
139
|
});
|
147
140
|
|
148
141
|
|
149
142
|
it('throws when a threshold value is not between 0 and 1', function() {
|
150
143
|
expect(function() {
|
151
144
|
io = new IntersectionObserver(noop, {threshold: [0, -1]});
|
152
|
-
}).to.throwException(
|
145
|
+
}).to.throwException();
|
153
146
|
});
|
154
147
|
|
155
148
|
});
|
@@ -161,7 +154,7 @@ describe('IntersectionObserver', function() {
|
|
161
154
|
expect(function() {
|
162
155
|
io = new IntersectionObserver(noop);
|
163
156
|
io.observe(null);
|
164
|
-
}).to.throwException(
|
157
|
+
}).to.throwException();
|
165
158
|
});
|
166
159
|
|
167
160
|
|
@@ -178,6 +171,20 @@ describe('IntersectionObserver', function() {
|
|
178
171
|
io.observe(targetEl2);
|
179
172
|
});
|
180
173
|
|
174
|
+
it('triggers for existing targets when observing begins after monitoring has begun', function(done) {
|
175
|
+
var spy = sinon.spy();
|
176
|
+
io = new IntersectionObserver(spy, {root: rootEl});
|
177
|
+
|
178
|
+
io.observe(targetEl1);
|
179
|
+
setTimeout(function() {
|
180
|
+
io.observe(targetEl2);
|
181
|
+
setTimeout(function() {
|
182
|
+
expect(spy.callCount).to.be(2);
|
183
|
+
done();
|
184
|
+
}, ASYNC_TIMEOUT);
|
185
|
+
}, ASYNC_TIMEOUT);
|
186
|
+
});
|
187
|
+
|
181
188
|
|
182
189
|
it('triggers with the correct arguments', function(done) {
|
183
190
|
io = new IntersectionObserver(function(records, observer) {
|
@@ -632,7 +639,7 @@ describe('IntersectionObserver', function() {
|
|
632
639
|
|
633
640
|
// targetEl5 is initially not in the DOM. Note that this element must be
|
634
641
|
// created outside of the addFixtures() function to catch the IE11 error
|
635
|
-
// described here: https://github.com/
|
642
|
+
// described here: https://github.com/w3c/IntersectionObserver/pull/205
|
636
643
|
var targetEl5 = document.createElement('div');
|
637
644
|
targetEl5.setAttribute('id', 'target5');
|
638
645
|
|
package/intersection-observer.js
CHANGED
@@ -1,17 +1,10 @@
|
|
1
1
|
/**
|
2
2
|
* Copyright 2016 Google Inc. All Rights Reserved.
|
3
3
|
*
|
4
|
-
* Licensed under the
|
5
|
-
* you may not use this file except in compliance with the License.
|
6
|
-
* You may obtain a copy of the License at
|
4
|
+
* Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
|
7
5
|
*
|
8
|
-
*
|
6
|
+
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
9
7
|
*
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
* See the License for the specific language governing permissions and
|
14
|
-
* limitations under the License.
|
15
8
|
*/
|
16
9
|
|
17
10
|
(function(window, document) {
|
@@ -25,7 +18,7 @@ if ('IntersectionObserver' in window &&
|
|
25
18
|
'intersectionRatio' in window.IntersectionObserverEntry.prototype) {
|
26
19
|
|
27
20
|
// Minimal polyfill for Edge 15's lack of `isIntersecting`
|
28
|
-
// See: https://github.com/
|
21
|
+
// See: https://github.com/w3c/IntersectionObserver/issues/211
|
29
22
|
if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) {
|
30
23
|
Object.defineProperty(window.IntersectionObserverEntry.prototype,
|
31
24
|
'isIntersecting', {
|
@@ -40,7 +33,7 @@ if ('IntersectionObserver' in window &&
|
|
40
33
|
|
41
34
|
/**
|
42
35
|
* An IntersectionObserver registry. This registry exists to hold a strong
|
43
|
-
* reference to IntersectionObserver instances currently
|
36
|
+
* reference to IntersectionObserver instances currently observing a target
|
44
37
|
* element. Without this registry, instances without another reference may be
|
45
38
|
* garbage collected.
|
46
39
|
*/
|
@@ -49,7 +42,7 @@ var registry = [];
|
|
49
42
|
|
50
43
|
/**
|
51
44
|
* Creates the global IntersectionObserverEntry constructor.
|
52
|
-
* https://
|
45
|
+
* https://w3c.github.io/IntersectionObserver/#intersection-observer-entry
|
53
46
|
* @param {Object} entry A dictionary of instance properties.
|
54
47
|
* @constructor
|
55
48
|
*/
|
@@ -69,7 +62,9 @@ function IntersectionObserverEntry(entry) {
|
|
69
62
|
|
70
63
|
// Sets intersection ratio.
|
71
64
|
if (targetArea) {
|
72
|
-
|
65
|
+
// Round the intersection ratio to avoid floating point math issues:
|
66
|
+
// https://github.com/w3c/IntersectionObserver/issues/324
|
67
|
+
this.intersectionRatio = Number((intersectionArea / targetArea).toFixed(4));
|
73
68
|
} else {
|
74
69
|
// If area is zero and is intersecting, sets to 1, otherwise to 0
|
75
70
|
this.intersectionRatio = this.isIntersecting ? 1 : 0;
|
@@ -79,7 +74,7 @@ function IntersectionObserverEntry(entry) {
|
|
79
74
|
|
80
75
|
/**
|
81
76
|
* Creates the global IntersectionObserver constructor.
|
82
|
-
* https://
|
77
|
+
* https://w3c.github.io/IntersectionObserver/#intersection-observer-interface
|
83
78
|
* @param {Function} callback The function to be invoked after intersection
|
84
79
|
* changes have queued. The function is not invoked if the queue has
|
85
80
|
* been emptied by calling the `takeRecords` method.
|
@@ -131,6 +126,12 @@ IntersectionObserver.prototype.THROTTLE_TIMEOUT = 100;
|
|
131
126
|
*/
|
132
127
|
IntersectionObserver.prototype.POLL_INTERVAL = null;
|
133
128
|
|
129
|
+
/**
|
130
|
+
* Use a mutation observer on the root element
|
131
|
+
* to detect intersection changes.
|
132
|
+
*/
|
133
|
+
IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true;
|
134
|
+
|
134
135
|
|
135
136
|
/**
|
136
137
|
* Starts observing a target element for intersection changes based on
|
@@ -138,10 +139,11 @@ IntersectionObserver.prototype.POLL_INTERVAL = null;
|
|
138
139
|
* @param {Element} target The DOM element to observe.
|
139
140
|
*/
|
140
141
|
IntersectionObserver.prototype.observe = function(target) {
|
141
|
-
|
142
|
-
if (this._observationTargets.some(function(item) {
|
142
|
+
var isTargetAlreadyObserved = this._observationTargets.some(function(item) {
|
143
143
|
return item.element == target;
|
144
|
-
})
|
144
|
+
});
|
145
|
+
|
146
|
+
if (isTargetAlreadyObserved) {
|
145
147
|
return;
|
146
148
|
}
|
147
149
|
|
@@ -152,6 +154,7 @@ IntersectionObserver.prototype.observe = function(target) {
|
|
152
154
|
this._registerInstance();
|
153
155
|
this._observationTargets.push({element: target, entry: null});
|
154
156
|
this._monitorIntersections();
|
157
|
+
this._checkForIntersections();
|
155
158
|
};
|
156
159
|
|
157
160
|
|
@@ -249,15 +252,13 @@ IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) {
|
|
249
252
|
|
250
253
|
/**
|
251
254
|
* Starts polling for intersection changes if the polling is not already
|
252
|
-
* happening, and if the page's
|
255
|
+
* happening, and if the page's visibility state is visible.
|
253
256
|
* @private
|
254
257
|
*/
|
255
258
|
IntersectionObserver.prototype._monitorIntersections = function() {
|
256
259
|
if (!this._monitoringIntersections) {
|
257
260
|
this._monitoringIntersections = true;
|
258
261
|
|
259
|
-
this._checkForIntersections();
|
260
|
-
|
261
262
|
// If a poll interval is set, use polling instead of listening to
|
262
263
|
// resize and scroll events or DOM mutations.
|
263
264
|
if (this.POLL_INTERVAL) {
|
@@ -268,7 +269,7 @@ IntersectionObserver.prototype._monitorIntersections = function() {
|
|
268
269
|
addEvent(window, 'resize', this._checkForIntersections, true);
|
269
270
|
addEvent(document, 'scroll', this._checkForIntersections, true);
|
270
271
|
|
271
|
-
if ('MutationObserver' in window) {
|
272
|
+
if (this.USE_MUTATION_OBSERVER && 'MutationObserver' in window) {
|
272
273
|
this._domObserver = new MutationObserver(this._checkForIntersections);
|
273
274
|
this._domObserver.observe(document, {
|
274
275
|
attributes: true,
|
@@ -358,7 +359,7 @@ IntersectionObserver.prototype._checkForIntersections = function() {
|
|
358
359
|
* Accepts a target and root rect computes the intersection between then
|
359
360
|
* following the algorithm in the spec.
|
360
361
|
* TODO(philipwalton): at this time clip-path is not considered.
|
361
|
-
* https://
|
362
|
+
* https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo
|
362
363
|
* @param {Element} target The target DOM element
|
363
364
|
* @param {Object} rootRect The bounding rect of the root after being
|
364
365
|
* expanded by the rootMargin value.
|
@@ -553,7 +554,7 @@ function now() {
|
|
553
554
|
|
554
555
|
|
555
556
|
/**
|
556
|
-
* Throttles a function and delays its
|
557
|
+
* Throttles a function and delays its execution, so it's only called at most
|
557
558
|
* once within a given time period.
|
558
559
|
* @param {Function} fn The function to throttle.
|
559
560
|
* @param {number} timeout The amount of time that must pass before the
|
@@ -647,7 +648,7 @@ function getBoundingClientRect(el) {
|
|
647
648
|
rect = el.getBoundingClientRect();
|
648
649
|
} catch (err) {
|
649
650
|
// Ignore Windows 7 IE11 "Unspecified error"
|
650
|
-
// https://github.com/
|
651
|
+
// https://github.com/w3c/IntersectionObserver/pull/205
|
651
652
|
}
|
652
653
|
|
653
654
|
if (!rect) return getEmptyRect();
|
@@ -684,7 +685,7 @@ function getEmptyRect() {
|
|
684
685
|
}
|
685
686
|
|
686
687
|
/**
|
687
|
-
* Checks to see if a parent element contains a child
|
688
|
+
* Checks to see if a parent element contains a child element (including inside
|
688
689
|
* shadow DOM).
|
689
690
|
* @param {Node} parent The parent element.
|
690
691
|
* @param {Node} child The child element.
|
package/package.json
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"name": "intersection-observer",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.1",
|
4
4
|
"description": "A polyfill for IntersectionObserver",
|
5
5
|
"main": "intersection-observer",
|
6
6
|
"repository": {
|
7
7
|
"type": "git",
|
8
|
-
"url": "git@github.com:
|
8
|
+
"url": "git@github.com:w3c/IntersectionObserver.git"
|
9
9
|
},
|
10
10
|
"keywords": [
|
11
11
|
"Intersection",
|
@@ -16,8 +16,8 @@
|
|
16
16
|
"email": "philip@philipwalton.com",
|
17
17
|
"url": "http://philipwalton.com"
|
18
18
|
},
|
19
|
-
"license": "
|
19
|
+
"license": "W3C-20150513",
|
20
20
|
"bugs": {
|
21
|
-
"url": "https://github.com/
|
21
|
+
"url": "https://github.com/w3c/IntersectionObserver/issues"
|
22
22
|
}
|
23
23
|
}
|
package/slot.html
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
<template id="slot-test">
|
2
|
+
<style>
|
3
|
+
|
4
|
+
</style>
|
5
|
+
<div>
|
6
|
+
<h3>Title</h3>
|
7
|
+
<aside>
|
8
|
+
<slot name="contents"></slot>
|
9
|
+
</aside>
|
10
|
+
</div>
|
11
|
+
</template>
|
12
|
+
|
13
|
+
|
14
|
+
<my-el>
|
15
|
+
<ul slot="contents">
|
16
|
+
<li>one</li>
|
17
|
+
<li>two</li>
|
18
|
+
<li>three</li>
|
19
|
+
</ul>
|
20
|
+
<ul slot="contents">
|
21
|
+
<li>four</li>
|
22
|
+
<li>five</li>
|
23
|
+
<li>six</li>
|
24
|
+
</ul>
|
25
|
+
</my-el>
|
26
|
+
|
27
|
+
|
28
|
+
<script>
|
29
|
+
class MyEl extends HTMLElement {
|
30
|
+
constructor() {
|
31
|
+
super();
|
32
|
+
|
33
|
+
const shadowRoot = this.attachShadow({mode: 'open'});
|
34
|
+
shadowRoot.innerHTML = `
|
35
|
+
<style>
|
36
|
+
|
37
|
+
</style>
|
38
|
+
<div>
|
39
|
+
<h3>Title</h3>
|
40
|
+
<aside>
|
41
|
+
<slot name="contents"></slot>
|
42
|
+
</aside>
|
43
|
+
</div>
|
44
|
+
`;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
self.customElements.define('my-el', MyEl);
|
49
|
+
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Checks to see if a parent element contains a child elemnt (including inside
|
53
|
+
* shadow DOM).
|
54
|
+
* @param {Node} parent The parent element.
|
55
|
+
* @param {Node} child The child element.
|
56
|
+
* @return {boolean} True if the parent node contains the child node.
|
57
|
+
*/
|
58
|
+
function containsDeep(parent, child) {
|
59
|
+
var node = child;
|
60
|
+
while (node) {
|
61
|
+
if (node == parent) return true;
|
62
|
+
|
63
|
+
node = getParentNode(node);
|
64
|
+
}
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Gets the parent node of an element or its host element if the parent node
|
71
|
+
* is a shadow root.
|
72
|
+
* @param {Node} node The node whose parent to get.
|
73
|
+
* @return {Node|null} The parent node or null if no parent exists.
|
74
|
+
*/
|
75
|
+
function getParentNode(node) {
|
76
|
+
var parent = node.parentNode;
|
77
|
+
|
78
|
+
if (parent) {
|
79
|
+
if (parent.nodeType == 11 && parent.host) {
|
80
|
+
// If the parent is a shadow root, return the host element.
|
81
|
+
return parent.host;
|
82
|
+
}
|
83
|
+
|
84
|
+
if (parent.assignedSlot) {
|
85
|
+
// If the parent is assigned a slot, return the slot's parent.
|
86
|
+
return parent.assignedSlot.parentNode;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
return parent;
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
</script>
|
package/.npmignore
DELETED