Files
headroom/frontend/node_modules/happy-dom/cjs/nodes/node/Node.cjs
Santhosh Janardhanan de2d83092e feat: Reinitialize frontend with SvelteKit and TypeScript
- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
2026-02-17 16:19:59 -05:00

1090 lines
42 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const EventTarget_js_1 = __importDefault(require("../../event/EventTarget.cjs"));
const PropertySymbol = __importStar(require("../../PropertySymbol.cjs"));
const NodeTypeEnum_js_1 = __importDefault(require("./NodeTypeEnum.cjs"));
const NodeDocumentPositionEnum_js_1 = __importDefault(require("./NodeDocumentPositionEnum.cjs"));
const NodeUtility_js_1 = __importDefault(require("./NodeUtility.cjs"));
const NodeList_js_1 = __importDefault(require("./NodeList.cjs"));
const MutationRecord_js_1 = __importDefault(require("../../mutation-observer/MutationRecord.cjs"));
const MutationTypeEnum_js_1 = __importDefault(require("../../mutation-observer/MutationTypeEnum.cjs"));
const DOMExceptionNameEnum_js_1 = __importDefault(require("../../exception/DOMExceptionNameEnum.cjs"));
const NodeFactory_js_1 = __importDefault(require("../NodeFactory.cjs"));
/**
* Node.
*/
class Node extends EventTarget_js_1.default {
// Public properties
static ELEMENT_NODE = NodeTypeEnum_js_1.default.elementNode;
static ATTRIBUTE_NODE = NodeTypeEnum_js_1.default.attributeNode;
static TEXT_NODE = NodeTypeEnum_js_1.default.textNode;
static CDATA_SECTION_NODE = NodeTypeEnum_js_1.default.cdataSectionNode;
static COMMENT_NODE = NodeTypeEnum_js_1.default.commentNode;
static DOCUMENT_NODE = NodeTypeEnum_js_1.default.documentNode;
static DOCUMENT_TYPE_NODE = NodeTypeEnum_js_1.default.documentTypeNode;
static DOCUMENT_FRAGMENT_NODE = NodeTypeEnum_js_1.default.documentFragmentNode;
static PROCESSING_INSTRUCTION_NODE = NodeTypeEnum_js_1.default.processingInstructionNode;
static DOCUMENT_POSITION_CONTAINED_BY = NodeDocumentPositionEnum_js_1.default.containedBy;
static DOCUMENT_POSITION_CONTAINS = NodeDocumentPositionEnum_js_1.default.contains;
static DOCUMENT_POSITION_DISCONNECTED = NodeDocumentPositionEnum_js_1.default.disconnect;
static DOCUMENT_POSITION_FOLLOWING = NodeDocumentPositionEnum_js_1.default.following;
static DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = NodeDocumentPositionEnum_js_1.default.implementationSpecific;
static DOCUMENT_POSITION_PRECEDING = NodeDocumentPositionEnum_js_1.default.preceding;
// Internal properties
[PropertySymbol.isConnected] = false;
[PropertySymbol.parentNode] = null;
[PropertySymbol.nodeType];
[PropertySymbol.rootNode] = null;
[PropertySymbol.styleNode] = null;
[PropertySymbol.textAreaNode] = null;
[PropertySymbol.formNode] = null;
[PropertySymbol.selectNode] = null;
[PropertySymbol.mutationListeners] = [];
[PropertySymbol.nodeArray] = [];
[PropertySymbol.elementArray] = [];
[PropertySymbol.childNodes] = null;
[PropertySymbol.assignedToSlot] = null;
[PropertySymbol.cache] = {
querySelector: new Map(),
querySelectorAll: new Map(),
matches: new Map(),
elementsByTagName: new Map(),
elementsByTagNameNS: new Map(),
elementByTagName: new Map(),
elementById: new Map(),
computedStyle: null
};
[PropertySymbol.affectsCache] = [];
/**
* Constructor.
*/
constructor() {
super();
// Window injected by WindowContextClassExtender (used when the Node can be created using "new" keyword)
if (this[PropertySymbol.window]) {
this[PropertySymbol.ownerDocument] = this[PropertySymbol.window].document;
}
else {
const ownerDocument = NodeFactory_js_1.default.pullOwnerDocument();
if (!ownerDocument) {
throw new TypeError('Illegal constructor');
}
this[PropertySymbol.ownerDocument] = ownerDocument;
this[PropertySymbol.window] = ownerDocument[PropertySymbol.window];
}
}
/**
* Returns `Symbol.toStringTag`.
*
* @returns `Symbol.toStringTag`.
*/
get [Symbol.toStringTag]() {
return this.constructor.name;
}
/**
* Returns connected state.
*
* @returns Connected state.
*/
get isConnected() {
return this[PropertySymbol.isConnected];
}
/**
* Returns owner document.
*
* @returns Owner document.
*/
get ownerDocument() {
return this[PropertySymbol.ownerDocument];
}
/**
* Returns parent node.
*
* @returns Parent node.
*/
get parentNode() {
return this[PropertySymbol.parentNode];
}
/**
* Returns node type.
*
* @returns Node type.
*/
get nodeType() {
return this[PropertySymbol.nodeType];
}
/**
* Get child nodes.
*
* @returns Child nodes list.
*/
get childNodes() {
if (!this[PropertySymbol.childNodes]) {
this[PropertySymbol.childNodes] = new NodeList_js_1.default(PropertySymbol.illegalConstructor, this[PropertySymbol.nodeArray]);
}
return this[PropertySymbol.childNodes];
}
/**
* Get text value of children.
*
* @returns Text content.
*/
get textContent() {
// Sub-classes should implement this method.
return null;
}
/**
* Sets text content.
*
* @param _textContent Text content.
*/
set textContent(_textContent) {
// Do nothing.
// Sub-classes should implement this method.
}
/**
* Node value.
*
* @returns Node value.
*/
get nodeValue() {
return null;
}
/**
* Sets node value.
*/
set nodeValue(_nodeValue) {
// Do nothing
}
/**
* Node name.
*
* @returns Node name.
*/
get nodeName() {
return '';
}
/**
* Previous sibling.
*
* @returns Node.
*/
get previousSibling() {
if (this[PropertySymbol.parentNode]) {
const nodeArray = this[PropertySymbol.parentNode][PropertySymbol.nodeArray];
const index = nodeArray.indexOf(this);
if (index > 0) {
return nodeArray[index - 1];
}
}
return null;
}
/**
* Next sibling.
*
* @returns Node.
*/
get nextSibling() {
if (this[PropertySymbol.parentNode]) {
const nodeArray = this[PropertySymbol.parentNode][PropertySymbol.nodeArray];
const index = nodeArray.indexOf(this);
if (index > -1 && index + 1 < nodeArray.length) {
return nodeArray[index + 1];
}
}
return null;
}
/**
* First child.
*
* @returns Node.
*/
get firstChild() {
const nodeArray = this[PropertySymbol.nodeArray];
if (nodeArray.length > 0) {
return nodeArray[0];
}
return null;
}
/**
* Last child.
*
* @returns Node.
*/
get lastChild() {
const nodeArray = this[PropertySymbol.nodeArray];
if (nodeArray.length > 0) {
return nodeArray[nodeArray.length - 1];
}
return null;
}
/**
* Returns parent element.
*
* @returns Element.
*/
get parentElement() {
let parent = this[PropertySymbol.parentNode];
while (parent && parent[PropertySymbol.nodeType] !== NodeTypeEnum_js_1.default.elementNode) {
parent = parent[PropertySymbol.parentNode];
}
return parent;
}
/**
* Returns base URI.
*
* @returns Base URI.
*/
get baseURI() {
const base = this[PropertySymbol.ownerDocument].querySelector('base');
if (base) {
return base.href;
}
return this[PropertySymbol.window].location.href;
}
/**
* Returns "true" if the node has child nodes.
*
* @returns "true" if the node has child nodes.
*/
hasChildNodes() {
return this[PropertySymbol.nodeArray].length > 0;
}
/**
* Returns "true" if this node contains the other node.
*
* @param otherNode Node to test with.
* @returns "true" if this node contains the other node.
*/
contains(otherNode) {
if (otherNode === undefined) {
return false;
}
return NodeUtility_js_1.default.isInclusiveAncestor(this, otherNode);
}
/**
* Returns closest root node (Document or ShadowRoot).
*
* @param options Options.
* @param options.composed A Boolean that indicates whether the shadow root should be returned (false, the default), or a root node beyond shadow root (true).
* @returns Node.
*/
getRootNode(options) {
if (!this[PropertySymbol.isConnected]) {
return this;
}
if (this[PropertySymbol.rootNode] && !options?.composed) {
return this[PropertySymbol.rootNode];
}
return this[PropertySymbol.ownerDocument];
}
/**
* Clones a node.
*
* @param [deep=false] "true" to clone deep.
* @returns Cloned node.
*/
cloneNode(deep = false) {
return this[PropertySymbol.cloneNode](deep);
}
/**
* Append a child node to childNodes.
*
* @param node Node to append.
* @returns Appended node.
*/
appendChild(node) {
if (arguments.length < 1) {
throw new this[PropertySymbol.window].TypeError(`Failed to execute 'appendChild' on 'Node': 1 argument required, but only 0 present`);
}
return this[PropertySymbol.appendChild](node);
}
/**
* Remove Child element from childNodes array.
*
* @param node Node to remove.
* @returns Removed node.
*/
removeChild(node) {
if (arguments.length < 1) {
throw new this[PropertySymbol.window].TypeError(`Failed to execute 'removeChild' on 'Node': 1 argument required, but only 0 present`);
}
return this[PropertySymbol.removeChild](node);
}
/**
* Inserts a node before another.
*
* @param newNode Node to insert.
* @param referenceNode Node to insert before.
* @returns Inserted node.
*/
insertBefore(newNode, referenceNode) {
if (arguments.length < 2) {
throw new this[PropertySymbol.window].TypeError(`Failed to execute 'insertBefore' on 'Node': 2 arguments required, but only ${arguments.length} present.`);
}
return this[PropertySymbol.insertBefore](newNode, referenceNode);
}
/**
* Replaces a node with another.
*
* @param newChild New child.
* @param oldChild Old child.
* @returns Replaced node.
*/
replaceChild(newChild, oldChild) {
if (arguments.length < 2) {
throw new this[PropertySymbol.window].TypeError(`Failed to execute 'replaceChild' on 'Node': 2 arguments required, but only ${arguments.length} present.`);
}
return this[PropertySymbol.replaceChild](newChild, oldChild);
}
/**
* Clones a node.
*
* @param [deep=false] "true" to clone deep.
* @returns Cloned node.
*/
[PropertySymbol.cloneNode](deep = false) {
const clone = NodeFactory_js_1.default.createNode(this[PropertySymbol.ownerDocument], this.constructor);
// Document has childNodes directly when it is created
// We need to remove them
if (clone[PropertySymbol.nodeArray].length) {
const childNodes = clone[PropertySymbol.nodeArray];
while (childNodes.length) {
clone.removeChild(childNodes[0]);
}
}
if (deep) {
for (const childNode of this[PropertySymbol.nodeArray]) {
const childClone = childNode.cloneNode(true);
childClone[PropertySymbol.parentNode] = clone;
clone[PropertySymbol.nodeArray].push(childClone);
if (childClone[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.elementNode) {
clone[PropertySymbol.elementArray].push(childClone);
}
}
}
return clone;
}
/**
* Append a child node to childNodes.
*
* @param node Node to append.
* @param [disableValidations=false] "true" to disable validations.
* @returns Appended node.
*/
[PropertySymbol.appendChild](node, disableValidations = false) {
if (node[PropertySymbol.proxy]) {
node = node[PropertySymbol.proxy];
}
const self = this[PropertySymbol.proxy] || this;
if (!disableValidations) {
if (node === self) {
throw new this[PropertySymbol.window].DOMException("Failed to execute 'appendChild' on 'Node': Not possible to append a node as a child of itself.");
}
if (NodeUtility_js_1.default.isInclusiveAncestor(node, self, true)) {
throw new this[PropertySymbol.window].DOMException("Failed to execute 'appendChild' on 'Node': The new node is a parent of the node to insert to.", DOMExceptionNameEnum_js_1.default.domException);
}
}
// If the type is DocumentFragment, then the child nodes of if it should be moved instead of the actual node.
// See: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment
if (node[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.documentFragmentNode) {
const childNodes = node[PropertySymbol.nodeArray];
while (childNodes.length) {
this.appendChild(childNodes[0]);
}
return node;
}
// Remove the node from its previous parent if it has any.
if (node[PropertySymbol.parentNode]) {
node[PropertySymbol.parentNode][PropertySymbol.removeChild](node);
}
node[PropertySymbol.parentNode] = self;
node[PropertySymbol.clearCache]();
this[PropertySymbol.nodeArray].push(node);
if (node[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.elementNode) {
this[PropertySymbol.elementArray].push(node);
}
node[PropertySymbol.connectedToNode]();
// Mutation listeners
for (const mutationListener of this[PropertySymbol.mutationListeners]) {
if (mutationListener.options?.subtree && mutationListener.callback.deref()) {
node[PropertySymbol.observeMutations](mutationListener);
}
}
this[PropertySymbol.reportMutation](new MutationRecord_js_1.default({
target: self,
type: MutationTypeEnum_js_1.default.childList,
addedNodes: [node]
}));
return node;
}
/**
* Remove Child element from childNodes array.
*
* @param node Node to remove.
* @returns Removed node.
*/
[PropertySymbol.removeChild](node) {
if (node[PropertySymbol.proxy]) {
node = node[PropertySymbol.proxy];
}
const index = this[PropertySymbol.nodeArray].indexOf(node);
if (index === -1) {
throw new this[PropertySymbol.window].DOMException(`Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.`);
}
const previousSibling = node.previousSibling;
const nextSibling = node.nextSibling;
node[PropertySymbol.parentNode] = null;
node[PropertySymbol.clearCache]();
this[PropertySymbol.nodeArray].splice(index, 1);
if (node[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.elementNode) {
const index = this[PropertySymbol.elementArray].indexOf(node);
if (index !== -1) {
this[PropertySymbol.elementArray].splice(index, 1);
}
}
if (node[PropertySymbol.assignedToSlot]) {
const index = node[PropertySymbol.assignedToSlot][PropertySymbol.assignedNodes].indexOf(node);
if (index !== -1) {
node[PropertySymbol.assignedToSlot][PropertySymbol.assignedNodes].splice(index, 1);
}
node[PropertySymbol.assignedToSlot] = null;
}
node[PropertySymbol.disconnectedFromNode]();
// Mutation listeners
for (const mutationListener of this[PropertySymbol.mutationListeners]) {
if (mutationListener.options?.subtree && mutationListener.callback.deref()) {
node[PropertySymbol.unobserveMutations](mutationListener);
}
}
this[PropertySymbol.reportMutation](new MutationRecord_js_1.default({
target: this[PropertySymbol.proxy] || this,
type: MutationTypeEnum_js_1.default.childList,
removedNodes: [node],
previousSibling,
nextSibling
}));
return node;
}
/**
* Inserts a node before another.
*
* @param newNode Node to insert.
* @param referenceNode Node to insert before.
* @param [disableValidations=false] "true" to disable validations.
* @returns Inserted node.
*/
[PropertySymbol.insertBefore](newNode, referenceNode, disableValidations = false) {
if (newNode[PropertySymbol.proxy]) {
newNode = newNode[PropertySymbol.proxy];
}
if (referenceNode && referenceNode[PropertySymbol.proxy]) {
referenceNode = referenceNode[PropertySymbol.proxy];
}
if (newNode === referenceNode) {
return newNode;
}
const self = this[PropertySymbol.proxy] || this;
if (!disableValidations) {
if (newNode === self) {
throw new this[PropertySymbol.window].DOMException("Failed to execute 'insertBefore' on 'Node': Not possible to insert a node as a child of itself.");
}
if (NodeUtility_js_1.default.isInclusiveAncestor(newNode, self, true)) {
throw new this[PropertySymbol.window].DOMException("Failed to execute 'insertBefore' on 'Node': The new node is a parent of the node to insert to.", DOMExceptionNameEnum_js_1.default.domException);
}
}
// If the type is DocumentFragment, then the child nodes of if it should be moved instead of the actual node.
// See: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment
if (newNode[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.documentFragmentNode) {
const childNodes = newNode[PropertySymbol.nodeArray];
while (childNodes.length > 0) {
this[PropertySymbol.insertBefore](childNodes[0], referenceNode, true);
}
return newNode;
}
// If the referenceNode is null or undefined, then the newNode should be appended to the ancestorNode.
// According to spec only null is valid, but browsers support undefined as well.
if (!referenceNode) {
this[PropertySymbol.appendChild](newNode, true);
return newNode;
}
const nodeArray = this[PropertySymbol.nodeArray];
// We need to check if the referenceNode is a child of this node before removing it from its parent, as the parent may be the same node and the index would be wrong.
if (!nodeArray.includes(referenceNode)) {
throw new this[PropertySymbol.window].DOMException("Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.");
}
if (newNode[PropertySymbol.parentNode]) {
newNode[PropertySymbol.parentNode][PropertySymbol.removeChild](newNode);
}
newNode[PropertySymbol.parentNode] = self;
newNode[PropertySymbol.clearCache]();
const index = nodeArray.indexOf(referenceNode);
if (newNode[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.elementNode) {
const elementArray = this[PropertySymbol.elementArray];
if (referenceNode[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.elementNode) {
elementArray.splice(elementArray.indexOf(referenceNode), 0, newNode);
}
else {
let isInserted = false;
for (let i = index, max = nodeArray.length; i < max; i++) {
if (nodeArray[i][PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.elementNode) {
elementArray.splice(elementArray.indexOf(nodeArray[i]), 0, newNode);
isInserted = true;
break;
}
}
if (!isInserted) {
elementArray.push(newNode);
}
}
}
nodeArray.splice(index, 0, newNode);
newNode[PropertySymbol.connectedToNode]();
// Mutation listeners
for (const mutationListener of this[PropertySymbol.mutationListeners]) {
if (mutationListener.options?.subtree && mutationListener.callback.deref()) {
newNode[PropertySymbol.observeMutations](mutationListener);
}
}
this[PropertySymbol.reportMutation](new MutationRecord_js_1.default({
target: self,
type: MutationTypeEnum_js_1.default.childList,
addedNodes: [newNode]
}));
return newNode;
}
/**
* Replaces a node with another.
*
* @param newChild New child.
* @param oldChild Old child.
* @returns Replaced node.
*/
[PropertySymbol.replaceChild](newChild, oldChild) {
this.insertBefore(newChild, oldChild);
this.removeChild(oldChild);
return oldChild;
}
/**
* Compares two nodes.
* Two nodes are equal if they have the same type, defining the same attributes, and so on.
*
* @param node Node to compare.
* @returns boolean - `true` if two nodes are equal.
*/
isEqualNode(node) {
return NodeUtility_js_1.default.isEqualNode(this, node);
}
/**
* Converts the node to a string.
*
* @param listener Listener.
*/
toString() {
return `[object ${this.constructor.name}]`;
}
/**
* Observeres mutations on the node.
*
* Used by MutationObserver and internal logic.
*
* @param listener Listener.
*/
[PropertySymbol.observeMutations](listener) {
this[PropertySymbol.mutationListeners].push(listener);
if (listener.options.subtree) {
for (const node of this[PropertySymbol.nodeArray]) {
node[PropertySymbol.observeMutations](listener);
}
}
}
/**
* Stops observing mutations on the node.
*
* Used by MutationObserver and internal logic.
*
* @param listener Listener.
*/
[PropertySymbol.unobserveMutations](listener) {
const index = this[PropertySymbol.mutationListeners].indexOf(listener);
if (index !== -1) {
this[PropertySymbol.mutationListeners].splice(index, 1);
}
if (listener.options.subtree) {
for (const node of this[PropertySymbol.nodeArray]) {
node[PropertySymbol.unobserveMutations](listener);
}
}
}
/**
* Reports a mutation on the node.
*
* Used by MutationObserver and internal logic.
*
* @param record Mutation record.
*/
[PropertySymbol.reportMutation](record) {
this[PropertySymbol.clearCache]();
const mutationListeners = this[PropertySymbol.mutationListeners];
if (!mutationListeners.length) {
return;
}
for (let i = 0, max = mutationListeners.length; i < max; i++) {
const mutationListener = mutationListeners[i];
const callback = mutationListener.callback.deref();
if (callback) {
switch (record.type) {
case MutationTypeEnum_js_1.default.childList:
if (mutationListener.options.childList) {
callback(record);
}
break;
case MutationTypeEnum_js_1.default.attributes:
if (mutationListener.options.attributes &&
(!mutationListener.options.attributeFilter ||
mutationListener.options.attributeFilter.includes(record.attributeName))) {
callback(record);
}
break;
case MutationTypeEnum_js_1.default.characterData:
if (mutationListener.options?.characterData) {
callback(record);
}
break;
}
}
else {
mutationListeners.splice(i, 1);
i--;
max--;
}
}
}
/**
* Clears query selector cache.
*/
[PropertySymbol.clearCache]() {
const cache = this[PropertySymbol.cache];
if (cache.querySelector.size) {
for (const item of cache.querySelector.values()) {
if (item.result) {
item.result = null;
}
}
cache.querySelector = new Map();
}
if (cache.querySelectorAll.size) {
for (const item of cache.querySelectorAll.values()) {
if (item.result) {
item.result = null;
}
}
cache.querySelectorAll = new Map();
}
if (cache.matches.size) {
for (const item of cache.matches.values()) {
if (item.result) {
item.result = null;
}
}
cache.matches = new Map();
}
if (cache.elementsByTagName.size) {
for (const item of cache.elementsByTagName.values()) {
if (item.result) {
item.result = null;
}
}
cache.elementsByTagName = new Map();
}
if (cache.elementsByTagNameNS.size) {
for (const item of cache.elementsByTagNameNS.values()) {
if (item.result) {
item.result = null;
}
}
cache.elementsByTagNameNS = new Map();
}
if (cache.elementByTagName.size) {
for (const item of cache.elementByTagName.values()) {
if (item.result) {
item.result = null;
}
}
cache.elementByTagName = new Map();
}
if (cache.elementById.size) {
for (const item of cache.elementById.values()) {
if (item.result) {
item.result = null;
}
}
cache.elementById = new Map();
}
const affectsCache = this[PropertySymbol.affectsCache];
if (affectsCache.length) {
for (const item of affectsCache) {
item.result = null;
}
this[PropertySymbol.affectsCache] = [];
}
// Computed style cache is affected by all mutations.
const document = this[PropertySymbol.ownerDocument];
if (document && document[PropertySymbol.affectsComputedStyleCache].length) {
for (const item of document[PropertySymbol.affectsComputedStyleCache]) {
item.result = null;
}
document[PropertySymbol.affectsComputedStyleCache] = [];
}
}
/**
* Called when connected to a node.
*/
[PropertySymbol.connectedToNode]() {
const parentNode = this[PropertySymbol.parentNode];
const parent = parentNode || this[PropertySymbol.host];
let isConnected = false;
let isDisconnected = false;
if (!this[PropertySymbol.isConnected] && parent[PropertySymbol.isConnected]) {
this[PropertySymbol.isConnected] = true;
isConnected = true;
}
else if (this[PropertySymbol.isConnected] && !parent[PropertySymbol.isConnected]) {
this[PropertySymbol.isConnected] = false;
isDisconnected = true;
}
this[PropertySymbol.ownerDocument] = parent[PropertySymbol.ownerDocument] || parent;
this[PropertySymbol.window] =
parent[PropertySymbol.window] || parent[PropertySymbol.defaultView];
if (parentNode) {
if (this[PropertySymbol.nodeType] !== NodeTypeEnum_js_1.default.documentFragmentNode) {
this[PropertySymbol.rootNode] = parentNode[PropertySymbol.rootNode];
}
if (parentNode[PropertySymbol.styleNode] && this[PropertySymbol.tagName] !== 'STYLE') {
this[PropertySymbol.styleNode] = parentNode[PropertySymbol.styleNode];
}
if (parentNode[PropertySymbol.textAreaNode] && this[PropertySymbol.tagName] !== 'TEXTAREA') {
this[PropertySymbol.textAreaNode] = parentNode[PropertySymbol.textAreaNode];
}
if (parentNode[PropertySymbol.formNode] && this[PropertySymbol.tagName] !== 'FORM') {
this[PropertySymbol.formNode] = parentNode[PropertySymbol.formNode];
}
if (parentNode[PropertySymbol.selectNode] && this[PropertySymbol.tagName] !== 'SELECT') {
this[PropertySymbol.selectNode] = parentNode[PropertySymbol.selectNode];
}
}
const childNodes = this[PropertySymbol.nodeArray];
for (let i = 0, max = childNodes.length; i < max; i++) {
childNodes[i][PropertySymbol.parentNode] = this;
childNodes[i][PropertySymbol.connectedToNode]();
}
// eslint-disable-next-line
if (this[PropertySymbol.shadowRoot]) {
// eslint-disable-next-line
this[PropertySymbol.shadowRoot][PropertySymbol.connectedToNode]();
}
if (isConnected) {
this[PropertySymbol.connectedToDocument]();
}
else if (isDisconnected) {
this[PropertySymbol.disconnectedFromDocument]();
}
}
/**
* Called when disconnected from a node.
*/
[PropertySymbol.disconnectedFromNode]() {
if (this[PropertySymbol.nodeType] !== NodeTypeEnum_js_1.default.documentFragmentNode) {
this[PropertySymbol.rootNode] = null;
}
if (this[PropertySymbol.tagName] !== 'STYLE') {
this[PropertySymbol.styleNode] = null;
}
if (this[PropertySymbol.tagName] !== 'TEXTAREA') {
this[PropertySymbol.textAreaNode] = null;
}
if (this[PropertySymbol.tagName] !== 'FORM') {
this[PropertySymbol.formNode] = null;
}
if (this[PropertySymbol.tagName] !== 'SELECT') {
this[PropertySymbol.selectNode] = null;
}
if (this[PropertySymbol.isConnected]) {
this[PropertySymbol.isConnected] = false;
this[PropertySymbol.disconnectedFromDocument]();
}
const childNodes = this[PropertySymbol.nodeArray];
for (let i = 0, max = childNodes.length; i < max; i++) {
childNodes[i][PropertySymbol.connectedToNode]();
}
// eslint-disable-next-line
if (this[PropertySymbol.shadowRoot]) {
// eslint-disable-next-line
this[PropertySymbol.shadowRoot][PropertySymbol.disconnectedFromNode]();
}
}
/**
* Called when connected to document.
*/
[PropertySymbol.connectedToDocument]() {
// eslint-disable-next-line
if (this[PropertySymbol.shadowRoot]) {
// eslint-disable-next-line
this[PropertySymbol.shadowRoot][PropertySymbol.connectedToDocument]();
}
}
/**
* Called when disconnected from document.
*/
[PropertySymbol.disconnectedFromDocument]() {
if (this[PropertySymbol.ownerDocument][PropertySymbol.activeElement] === this) {
this[PropertySymbol.ownerDocument][PropertySymbol.clearCache]();
this[PropertySymbol.ownerDocument][PropertySymbol.activeElement] = null;
}
// eslint-disable-next-line
if (this[PropertySymbol.shadowRoot]) {
// eslint-disable-next-line
this[PropertySymbol.shadowRoot][PropertySymbol.disconnectedFromDocument]();
}
}
/**
* Reports the position of its argument node relative to the node on which it is called.
*
* @see https://dom.spec.whatwg.org/#dom-node-comparedocumentposition
* @param otherNode Other node.
*/
compareDocumentPosition(otherNode) {
/**
* 1. If this is other, then return zero.
*/
if (this === otherNode) {
return 0;
}
/**
* 2. Let node1 be other and node2 be this.
*/
let node1 = otherNode;
let node2 = this[PropertySymbol.proxy] || this;
/**
* 3. Let attr1 and attr2 be null.
*/
let attr1 = null;
let attr2 = null;
/**
* 4. If node1 is an attribute, then set attr1 to node1 and node1 to attr1s element.
*/
if (node1[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.attributeNode) {
attr1 = node1;
node1 = attr1[PropertySymbol.ownerElement];
}
/**
* 5. If node2 is an attribute, then:
* 5.1. Set attr2 to node2 and node2 to attr2s element.
*/
if (node2[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.attributeNode) {
attr2 = node2;
node2 = attr2[PropertySymbol.ownerElement];
/**
* 5.2. If attr1 and node1 are non-null, and node2 is node1, then:
*/
if (attr1 !== null && node1 !== null && node2 === node1) {
/**
* 5.2.1. For each attr in node2s attribute list:
*/
for (const attribute of node2[PropertySymbol.attributes][PropertySymbol.items].values()) {
/**
* 5.2.1.1. If attr equals attr1, then return the result of adding DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC and DOCUMENT_POSITION_PRECEDING.
*/
if (NodeUtility_js_1.default.isEqualNode(attribute, attr1)) {
return (Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | Node.DOCUMENT_POSITION_PRECEDING);
}
/**
* 5.2.1.2. If attr equals attr2, then return the result of adding DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC and DOCUMENT_POSITION_FOLLOWING.
*/
if (NodeUtility_js_1.default.isEqualNode(attribute, attr2)) {
return (Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | Node.DOCUMENT_POSITION_FOLLOWING);
}
}
}
}
const node2Ancestors = [];
let node2Ancestor = node2;
while (node2Ancestor) {
/**
* 7. If node1 is an ancestor of node2 […] then return the result of adding DOCUMENT_POSITION_CONTAINS to DOCUMENT_POSITION_PRECEDING.
*/
if (node2Ancestor === node1) {
return Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING;
}
node2Ancestors.push(node2Ancestor);
node2Ancestor = node2Ancestor[PropertySymbol.parentNode];
}
const node1Ancestors = [];
let node1Ancestor = node1;
while (node1Ancestor) {
/**
* 8. If node1 is a descendant of node2 […] then return the result of adding DOCUMENT_POSITION_CONTAINED_BY to DOCUMENT_POSITION_FOLLOWING.
*/
if (node1Ancestor === node2) {
return Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING;
}
node1Ancestors.push(node1Ancestor);
node1Ancestor = node1Ancestor[PropertySymbol.parentNode];
}
const reverseArrayIndex = (array, reverseIndex) => {
return array[array.length - 1 - reverseIndex];
};
const root = reverseArrayIndex(node2Ancestors, 0);
/**
* 6. If node1 or node2 is null, or node1s root is not node2s root, then return the result of adding
* DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either
* DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING, with the constraint that this is to be consistent, together.
*/
if (!root || root !== reverseArrayIndex(node1Ancestors, 0)) {
return (Node.DOCUMENT_POSITION_DISCONNECTED |
Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
Node.DOCUMENT_POSITION_FOLLOWING);
}
// Find the lowest common ancestor
let commonAncestorIndex = 0;
const ancestorsMinLength = Math.min(node2Ancestors.length, node1Ancestors.length);
for (let i = 0; i < ancestorsMinLength; ++i) {
const node2Ancestor = reverseArrayIndex(node2Ancestors, i);
const node1Ancestor = reverseArrayIndex(node1Ancestors, i);
if (node2Ancestor !== node1Ancestor) {
break;
}
commonAncestorIndex = i;
}
const commonAncestor = reverseArrayIndex(node2Ancestors, commonAncestorIndex);
// Indexes within the common ancestor
let indexes = 0;
let node2Index = -1;
let node1Index = -1;
const node2Node = reverseArrayIndex(node2Ancestors, commonAncestorIndex + 1);
const node1Node = reverseArrayIndex(node1Ancestors, commonAncestorIndex + 1);
const computeNodeIndexes = (nodes) => {
for (const childNode of nodes) {
computeNodeIndexes(childNode[PropertySymbol.nodeArray]);
if (childNode === node2Node) {
node2Index = indexes;
}
else if (childNode === node1Node) {
node1Index = indexes;
}
if (node2Index !== -1 && node1Index !== -1) {
break;
}
indexes++;
}
};
computeNodeIndexes(commonAncestor[PropertySymbol.nodeArray]);
/**
* 9. If node1 is preceding node2, then return DOCUMENT_POSITION_PRECEDING.
* 10. Return DOCUMENT_POSITION_FOLLOWING.
*/
return node1Index < node2Index
? Node.DOCUMENT_POSITION_PRECEDING
: Node.DOCUMENT_POSITION_FOLLOWING;
}
/**
* Normalizes the sub-tree of the node, i.e. joins adjacent text nodes, and
* removes all empty text nodes.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize
*/
normalize() {
let child = this.firstChild;
while (child) {
if (NodeUtility_js_1.default.isTextNode(child)) {
// Append text of all following text nodes, and remove them.
while (NodeUtility_js_1.default.isTextNode(child.nextSibling)) {
child.data += child.nextSibling.data;
child.nextSibling.remove();
}
// Remove text node if it is still empty.
if (!child.data.length) {
const node = child;
child = child.nextSibling;
node.remove();
continue;
}
}
else {
// Normalize child nodes recursively.
child.normalize();
}
child = child.nextSibling;
}
}
/**
* Determines whether the given node is equal to the current node.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/isSameNode
* @param node Node to check.
* @returns True if the given node is equal to the current node, otherwise false.
*/
isSameNode(node) {
return this === node;
}
}
exports.default = Node;
// According to the spec, these properties should be on the prototype.
Node.prototype.ELEMENT_NODE = NodeTypeEnum_js_1.default.elementNode;
Node.prototype.ATTRIBUTE_NODE = NodeTypeEnum_js_1.default.attributeNode;
Node.prototype.TEXT_NODE = NodeTypeEnum_js_1.default.textNode;
Node.prototype.CDATA_SECTION_NODE = NodeTypeEnum_js_1.default.cdataSectionNode;
Node.prototype.COMMENT_NODE = NodeTypeEnum_js_1.default.commentNode;
Node.prototype.DOCUMENT_NODE = NodeTypeEnum_js_1.default.documentNode;
Node.prototype.DOCUMENT_TYPE_NODE = NodeTypeEnum_js_1.default.documentTypeNode;
Node.prototype.DOCUMENT_FRAGMENT_NODE = NodeTypeEnum_js_1.default.documentFragmentNode;
Node.prototype.PROCESSING_INSTRUCTION_NODE = NodeTypeEnum_js_1.default.processingInstructionNode;
Node.prototype.DOCUMENT_POSITION_CONTAINED_BY =
NodeDocumentPositionEnum_js_1.default.containedBy;
Node.prototype.DOCUMENT_POSITION_CONTAINS =
NodeDocumentPositionEnum_js_1.default.contains;
Node.prototype.DOCUMENT_POSITION_DISCONNECTED =
NodeDocumentPositionEnum_js_1.default.disconnect;
Node.prototype.DOCUMENT_POSITION_FOLLOWING =
NodeDocumentPositionEnum_js_1.default.following;
Node.prototype.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC =
NodeDocumentPositionEnum_js_1.default.implementationSpecific;
Node.prototype.DOCUMENT_POSITION_PRECEDING =
NodeDocumentPositionEnum_js_1.default.preceding;
//# sourceMappingURL=Node.cjs.map