@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
132 lines (113 loc) • 3.52 kB
JavaScript
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*
* SPDX-License-Identifier: AGPL-3.0
*/
import { isString } from "../types/is.mjs";
import { validateString } from "../types/validate.mjs";
export { getSlottedElements, getSlottedNodes };
/**
* @private
* @param {String|undefined} query
* @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.)
* @return {*}
* @this CustomElement
* @license AGPLv3
* @since 3.33.0
* @throws {Error} query must be a string
*/
function getSlottedNodes(query, name) {
const result = new Set();
if (!this.shadowRoot) {
return result;
}
let selector = "slot";
if (name !== undefined) {
if (name === null) {
selector += ":not([name])";
} else {
selector += `[name=${validateString(name)}]`;
}
}
const slots = this.shadowRoot.querySelectorAll(selector);
for (const [, slot] of Object.entries(slots)) {
slot.assignedNodes().forEach(function (node) {
if (node === null || node === undefined) {
return;
}
if (isString(query)) {
node.querySelectorAll(query).forEach(function (n) {
result.add(n);
});
if (node.matches(query)) {
result.add(node);
}
} else if (query !== undefined) {
throw new Error("query must be a string");
} else {
result.add(node);
}
});
}
return result;
}
/**
* @private
* @param {String|undefined} query
* @param {String|undefined|null} name name of the slot (if the parameter is undefined, all slots are searched, if the parameter has the value null, all slots without a name are searched. if a string is specified, the slots with this name are searched.)
* @return {*}
* @this CustomElement
* @license AGPLv3
* @since 1.23.0
* @throws {Error} query must be a string
*/
function getSlottedElements(query, name) {
const result = new Set();
if (!(this.shadowRoot instanceof ShadowRoot)) {
return result;
}
let selector = "slot";
if (name !== undefined) {
if (name === null) {
selector += ":not([name])";
} else {
selector += `[name=${validateString(name)}]`;
}
}
const slots = this.shadowRoot.querySelectorAll(selector);
for (const [, slot] of Object.entries(slots)) {
slot.assignedElements().forEach(function (node) {
if (
!(node instanceof HTMLElement) &&
!(node instanceof SVGElement) &&
!(node instanceof MathMLElement)
)
return;
if (isString(query)) {
if (query.length > 0) {
node.querySelectorAll(query).forEach(function (n) {
result.add(n);
});
if (node.matches(query)) {
result.add(node);
}
} else {
result.add(node);
}
} else if (query !== undefined) {
throw new Error("query must be a string and not empty");
} else {
result.add(node);
}
});
}
return result;
}