@schukai/monster 3.35.4 → 3.36.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/package.json +1 -1
- package/source/dom/util.mjs +46 -1
- package/source/types/version.mjs +1 -1
- package/test/cases/dom/util.mjs +60 -0
- package/test/cases/monster.mjs +1 -1
- package/test/util/jsdom.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +214 -50
package/package.json
CHANGED
package/source/dom/util.mjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { getGlobal } from "../types/global.mjs";
|
|
9
9
|
import { validateString } from "../types/validate.mjs";
|
|
10
10
|
|
|
11
|
-
export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithIdUpwards };
|
|
11
|
+
export { getDocument, getWindow, getDocumentFragmentFromString, findElementWithIdUpwards,getContainingDocument };
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* This method fetches the document object
|
|
@@ -199,3 +199,48 @@ function findElementWithIdUpwards(element, targetId) {
|
|
|
199
199
|
// Otherwise, search the current element's parent
|
|
200
200
|
return findElementWithIdUpwards(element.parentElement, targetId);
|
|
201
201
|
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @private
|
|
205
|
+
* @param {HTMLElement} element
|
|
206
|
+
* @returns {HTMLElement|null}
|
|
207
|
+
*/
|
|
208
|
+
function traverseShadowRoots(element) {
|
|
209
|
+
let currentRoot = element.shadowRoot;
|
|
210
|
+
let currentParent = element.parentNode;
|
|
211
|
+
|
|
212
|
+
while (currentParent && currentParent.nodeType !== Node.DOCUMENT_NODE && currentParent.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
|
213
|
+
if (currentRoot && currentRoot.parentNode) {
|
|
214
|
+
currentParent = currentRoot.parentNode;
|
|
215
|
+
currentRoot = currentParent.shadowRoot;
|
|
216
|
+
} else if (currentParent.parentNode) {
|
|
217
|
+
currentParent = currentParent.parentNode;
|
|
218
|
+
currentRoot = null;
|
|
219
|
+
} else if (currentRoot && currentRoot.host && currentRoot.host.nodeType === Node.DOCUMENT_NODE) {
|
|
220
|
+
currentParent = currentRoot.host;
|
|
221
|
+
currentRoot = null;
|
|
222
|
+
} else {
|
|
223
|
+
currentParent = null;
|
|
224
|
+
currentRoot = null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return currentParent;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Recursively searches upwards from a given element to find an ancestor element
|
|
233
|
+
*
|
|
234
|
+
* @param {HTMLElement} element
|
|
235
|
+
* @returns {*}
|
|
236
|
+
* @throws {Error} Invalid argument. Expected an HTMLElement.
|
|
237
|
+
* @memberOf Monster.DOM
|
|
238
|
+
* @since 3.36.0
|
|
239
|
+
*/
|
|
240
|
+
function getContainingDocument(element) {
|
|
241
|
+
if (!element || !(element instanceof HTMLElement || element instanceof element.ownerDocument.defaultView.HTMLElement)) {
|
|
242
|
+
throw new Error('Invalid argument. Expected an HTMLElement.');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return traverseShadowRoots(element) || null;
|
|
246
|
+
}
|
package/source/types/version.mjs
CHANGED
package/test/cases/dom/util.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
getDocument, getWindow, getDocumentFragmentFromString
|
|
3
3
|
} from "../../../../application/source/dom/util.mjs";
|
|
4
4
|
|
|
5
|
+
import {getContainingDocument} from "../../../../application/source/dom/util.mjs";
|
|
5
6
|
|
|
6
7
|
import {initJSDOM} from "../../util/jsdom.mjs";
|
|
7
8
|
|
|
@@ -52,4 +53,63 @@ describe('DOM', function () {
|
|
|
52
53
|
});
|
|
53
54
|
|
|
54
55
|
});
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
describe('getContainingDocument', () => {
|
|
59
|
+
let jsDomDocument;
|
|
60
|
+
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
jsDomDocument = getDocument();
|
|
63
|
+
});
|
|
64
|
+
//
|
|
65
|
+
// afterEach(() => {
|
|
66
|
+
// dom.window.close();
|
|
67
|
+
// });
|
|
68
|
+
|
|
69
|
+
it('should throw an error when called with an invalid argument', () => {
|
|
70
|
+
expect(() => getContainingDocument(null)).to.throw('Invalid argument. Expected an HTMLElement.');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should return the correct containing document for an element in the main document', () => {
|
|
74
|
+
const element = jsDomDocument.createElement('div');
|
|
75
|
+
const containingDocument = getContainingDocument(element);
|
|
76
|
+
|
|
77
|
+
expect(containingDocument).to.null;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should return the correct containing document for an element inside a shadow root', () => {
|
|
81
|
+
const host = jsDomDocument.createElement('div');
|
|
82
|
+
const shadowRoot = host.attachShadow({ mode: 'open' });
|
|
83
|
+
const element = jsDomDocument.createElement('span');
|
|
84
|
+
shadowRoot.appendChild(element);
|
|
85
|
+
|
|
86
|
+
const containingDocument = getContainingDocument(element);
|
|
87
|
+
expect(containingDocument).to.not.null;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should return the correct containing document for an element inside a nested shadow root', () => {
|
|
91
|
+
const outerHost = jsDomDocument.createElement('div');
|
|
92
|
+
const outerShadowRoot = outerHost.attachShadow({ mode: 'open' });
|
|
93
|
+
|
|
94
|
+
const innerHost = jsDomDocument.createElement('div');
|
|
95
|
+
outerShadowRoot.appendChild(innerHost);
|
|
96
|
+
|
|
97
|
+
const innerShadowRoot = innerHost.attachShadow({ mode: 'open' });
|
|
98
|
+
|
|
99
|
+
const element = jsDomDocument.createElement('span');
|
|
100
|
+
innerShadowRoot.appendChild(element);
|
|
101
|
+
|
|
102
|
+
const containingDocument = getContainingDocument(element);
|
|
103
|
+
expect(containingDocument).to.not.null;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should return null when the element is not attached to any document', () => {
|
|
107
|
+
const detachedElement = jsDomDocument.createElement('div');
|
|
108
|
+
detachedElement.remove();
|
|
109
|
+
|
|
110
|
+
const containingDocument = getContainingDocument(detachedElement);
|
|
111
|
+
expect(containingDocument).to.be.null;
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
55
115
|
});
|
package/test/cases/monster.mjs
CHANGED
package/test/util/jsdom.mjs
CHANGED
package/test/web/test.html
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
|
16
16
|
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
|
|
17
|
-
<h1 style='margin-bottom: 0.1em;'>Monster 3.
|
|
18
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
|
17
|
+
<h1 style='margin-bottom: 0.1em;'>Monster 3.35.4</h1>
|
|
18
|
+
<div id="lastupdate" style='font-size:0.7em'>last update Sa 1. Apr 17:29:43 CEST 2023</div>
|
|
19
19
|
</div>
|
|
20
20
|
<div id="mocks"></div>
|
|
21
21
|
<div id="mocha"></div>
|