"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 (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __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 Element_js_1 = __importDefault(require("../element/Element.cjs")); const PropertySymbol = __importStar(require("../../PropertySymbol.cjs")); const Node_js_1 = __importDefault(require("../node/Node.cjs")); const NodeIterator_js_1 = __importDefault(require("../../tree-walker/NodeIterator.cjs")); const TreeWalker_js_1 = __importDefault(require("../../tree-walker/TreeWalker.cjs")); const DocumentFragment_js_1 = __importDefault(require("../document-fragment/DocumentFragment.cjs")); const XMLParser_js_1 = __importDefault(require("../../xml-parser/XMLParser.cjs")); const Event_js_1 = __importDefault(require("../../event/Event.cjs")); const DOMImplementation_js_1 = __importDefault(require("../../dom-implementation/DOMImplementation.cjs")); const NamespaceURI_js_1 = __importDefault(require("../../config/NamespaceURI.cjs")); const DocumentType_js_1 = __importDefault(require("../document-type/DocumentType.cjs")); const ParentNodeUtility_js_1 = __importDefault(require("../parent-node/ParentNodeUtility.cjs")); const QuerySelector_js_1 = __importDefault(require("../../query-selector/QuerySelector.cjs")); const Comment_js_1 = __importDefault(require("../comment/Comment.cjs")); const Text_js_1 = __importDefault(require("../text/Text.cjs")); const HTMLCollection_js_1 = __importDefault(require("../element/HTMLCollection.cjs")); const DocumentReadyStateEnum_js_1 = __importDefault(require("./DocumentReadyStateEnum.cjs")); const Selection_js_1 = __importDefault(require("../../selection/Selection.cjs")); const Attr_js_1 = __importDefault(require("../attr/Attr.cjs")); const ProcessingInstruction_js_1 = __importDefault(require("../processing-instruction/ProcessingInstruction.cjs")); const VisibilityStateEnum_js_1 = __importDefault(require("./VisibilityStateEnum.cjs")); const NodeTypeEnum_js_1 = __importDefault(require("../node/NodeTypeEnum.cjs")); const CookieStringUtility_js_1 = __importDefault(require("../../cookie/urilities/CookieStringUtility.cjs")); const url_1 = require("url"); const HTMLElementConfig_js_1 = __importDefault(require("../../config/HTMLElementConfig.cjs")); const WindowBrowserContext_js_1 = __importDefault(require("../../window/WindowBrowserContext.cjs")); const NodeFactory_js_1 = __importDefault(require("../NodeFactory.cjs")); const SVGElementConfig_js_1 = __importDefault(require("../../config/SVGElementConfig.cjs")); const StringUtility_js_1 = __importDefault(require("../../StringUtility.cjs")); const PROCESSING_INSTRUCTION_TARGET_REGEXP = /^[a-z][a-z0-9-]+$/; /** * Document. */ class Document extends Node_js_1.default { // Internal properties [PropertySymbol.children] = null; [PropertySymbol.activeElement] = null; [PropertySymbol.nextActiveElement] = null; [PropertySymbol.currentScript] = null; [PropertySymbol.rootNode] = this; [PropertySymbol.isFirstWrite] = true; [PropertySymbol.isFirstWriteAfterOpen] = false; [PropertySymbol.nodeType] = NodeTypeEnum_js_1.default.documentNode; [PropertySymbol.isConnected] = true; [PropertySymbol.adoptedStyleSheets] = []; [PropertySymbol.implementation] = new DOMImplementation_js_1.default(this); [PropertySymbol.readyState] = DocumentReadyStateEnum_js_1.default.interactive; [PropertySymbol.referrer] = ''; [PropertySymbol.defaultView] = null; [PropertySymbol.forms] = null; [PropertySymbol.affectsComputedStyleCache] = []; [PropertySymbol.ownerDocument] = null; [PropertySymbol.elementIdMap] = new Map(); // Private properties #selection = null; // Events onreadystatechange = null; onpointerlockchange = null; onpointerlockerror = null; onbeforecopy = null; onbeforecut = null; onbeforepaste = null; onfreeze = null; onresume = null; onsearch = null; onvisibilitychange = null; onfullscreenchange = null; onfullscreenerror = null; onwebkitfullscreenchange = null; onwebkitfullscreenerror = null; onbeforexrselect = null; onabort = null; onbeforeinput = null; onblur = null; oncancel = null; oncanplay = null; oncanplaythrough = null; onchange = null; onclick = null; onclose = null; oncontextlost = null; oncontextmenu = null; oncontextrestored = null; oncuechange = null; ondblclick = null; ondrag = null; ondragend = null; ondragenter = null; ondragleave = null; ondragover = null; ondragstart = null; ondrop = null; ondurationchange = null; onemptied = null; onended = null; onerror = null; onfocus = null; onformdata = null; oninput = null; oninvalid = null; onkeydown = null; onkeypress = null; onkeyup = null; onload = null; onloadeddata = null; onloadedmetadata = null; onloadstart = null; onmousedown = null; onmouseenter = null; onmouseleave = null; onmousemove = null; onmouseout = null; onmouseover = null; onmouseup = null; onmousewheel = null; onpause = null; onplay = null; onplaying = null; onprogress = null; onratechange = null; onreset = null; onresize = null; onscroll = null; onsecuritypolicyviolation = null; onseeked = null; onseeking = null; onselect = null; onslotchange = null; onstalled = null; onsubmit = null; onsuspend = null; ontimeupdate = null; ontoggle = null; onvolumechange = null; onwaiting = null; onwebkitanimationend = null; onwebkitanimationiteration = null; onwebkitanimationstart = null; onwebkittransitionend = null; onwheel = null; onauxclick = null; ongotpointercapture = null; onlostpointercapture = null; onpointerdown = null; onpointermove = null; onpointerrawupdate = null; onpointerup = null; onpointercancel = null; onpointerover = null; onpointerout = null; onpointerenter = null; onpointerleave = null; onselectstart = null; onselectionchange = null; onanimationend = null; onanimationiteration = null; onanimationstart = null; ontransitionrun = null; ontransitionstart = null; ontransitionend = null; ontransitioncancel = null; oncopy = null; oncut = null; onpaste = null; onbeforematch = null; /** * Returns adopted style sheets. * * @returns Adopted style sheets. */ get adoptedStyleSheets() { return this[PropertySymbol.adoptedStyleSheets]; } /** * Sets adopted style sheets. * * @param value Adopted style sheets. */ set adoptedStyleSheets(value) { this[PropertySymbol.adoptedStyleSheets] = value; } /** * Returns DOM implementation. * * @returns DOM implementation. */ get implementation() { return this[PropertySymbol.implementation]; } /** * Returns document ready state. * * @returns Document ready state. */ get readyState() { return this[PropertySymbol.readyState]; } /** * Returns referrer. * * @returns Referrer. */ get referrer() { return this[PropertySymbol.referrer]; } /** * Returns default view. * * @returns Default view. */ get defaultView() { return this[PropertySymbol.defaultView]; } /** * Returns document children. */ get children() { if (!this[PropertySymbol.children]) { const elements = this[PropertySymbol.elementArray]; this[PropertySymbol.children] = new HTMLCollection_js_1.default(PropertySymbol.illegalConstructor, () => elements); } return this[PropertySymbol.children]; } /** * Returns character set. * * @deprecated * @returns Character set. */ get charset() { return this.characterSet; } /** * Returns character set. * * @returns Character set. */ get characterSet() { const charset = QuerySelector_js_1.default.querySelector(this, 'meta[charset]')?.getAttributeNS(null, 'charset'); return charset ? charset : 'UTF-8'; } /** * Returns title. * * @returns Title. */ get title() { const element = ParentNodeUtility_js_1.default.getElementByTagName(this, 'title'); if (element) { return element.text.trim(); } return ''; } /** * Returns set title. * */ set title(title) { const element = ParentNodeUtility_js_1.default.getElementByTagName(this, 'title'); if (element) { element.textContent = title; } else { const newElement = this.createElement('title'); newElement.textContent = title; this.head.appendChild(newElement); } } /** * Returns a collection of all area elements and a elements in a document with a value for the href attribute. */ get links() { return QuerySelector_js_1.default.querySelectorAll(this, 'a[href],area[href]'); } /** * Returns a collection of all form elements in a document. */ get forms() { if (!this[PropertySymbol.forms]) { this[PropertySymbol.forms] = (ParentNodeUtility_js_1.default.getElementsByTagName(this, 'form')); } return this[PropertySymbol.forms]; } /** * Last element child. * * @returns Element. */ get childElementCount() { return this[PropertySymbol.elementArray].length; } /** * First element child. * * @returns Element. */ get firstElementChild() { return this[PropertySymbol.elementArray][0] ?? null; } /** * Last element child. * * @returns Element. */ get lastElementChild() { const children = this[PropertySymbol.elementArray]; return children[children.length - 1] ?? null; } /** * Returns cookie string. * * @returns Cookie. */ get cookie() { const browserFrame = new WindowBrowserContext_js_1.default(this[PropertySymbol.window]).getBrowserFrame(); if (!browserFrame) { return ''; } return CookieStringUtility_js_1.default.cookiesToString(browserFrame.page.context.cookieContainer.getCookies(new url_1.URL(this[PropertySymbol.window].location.href), true)); } /** * Sets a cookie string. * * @param cookie Cookie string. */ set cookie(cookie) { const browserFrame = new WindowBrowserContext_js_1.default(this[PropertySymbol.window]).getBrowserFrame(); if (!browserFrame) { return; } browserFrame.page.context.cookieContainer.addCookies([ CookieStringUtility_js_1.default.stringToCookie(new url_1.URL(this[PropertySymbol.window].location.href), cookie) ]); } /** * Node name. * * @returns Node name. */ get nodeName() { return '#document'; } /** * Returns element. * * @returns Element. */ get documentElement() { return ParentNodeUtility_js_1.default.getElementByTagName(this, 'html'); } /** * Returns document type element. * * @returns Document type. */ get doctype() { for (const node of this[PropertySymbol.nodeArray]) { if (node instanceof DocumentType_js_1.default) { return node; } } return null; } /** * Returns element. * * @returns Element. */ get body() { return ParentNodeUtility_js_1.default.getElementByTagName(this, 'body'); } /** * Returns element. * * @returns Element. */ get head() { return ParentNodeUtility_js_1.default.getElementByTagName(this, 'head'); } /** * Returns CSS style sheets. * * @returns CSS style sheets. */ get styleSheets() { const styles = (QuerySelector_js_1.default.querySelectorAll(this, 'link[rel="stylesheet"][href],style')); const styleSheets = []; for (const style of styles) { const sheet = style.sheet; if (sheet) { styleSheets.push(sheet); } } return styleSheets; } /** * Returns active element. * * @returns Active element. */ get activeElement() { if (this[PropertySymbol.activeElement] && !this[PropertySymbol.activeElement][PropertySymbol.isConnected]) { this[PropertySymbol.activeElement] = null; } if (this[PropertySymbol.activeElement] && this[PropertySymbol.activeElement] instanceof Element_js_1.default) { let rootNode = (this[PropertySymbol.activeElement].getRootNode()); let activeElement = this[PropertySymbol.activeElement]; while (rootNode !== this) { activeElement = rootNode.host; rootNode = activeElement ? activeElement.getRootNode() : this; } return activeElement; } return this[PropertySymbol.activeElement] || this.body || this.documentElement || null; } /** * Returns scrolling element. * * @returns Scrolling element. */ get scrollingElement() { return this.documentElement; } /** * Returns location. * * @returns Location. */ get location() { return this[PropertySymbol.window].location; } /** * Returns scripts. * * @returns Scripts. */ get scripts() { return this.getElementsByTagName('script'); } /** * Returns base URI. * * @override * @returns Base URI. */ get baseURI() { const element = ParentNodeUtility_js_1.default.getElementByTagName(this, 'base'); if (element) { return element.href; } return this[PropertySymbol.window].location.href; } /** * Returns URL. * * @returns URL of the current document. * */ get URL() { return this[PropertySymbol.window].location.href; } /** * Returns document URI. * * @returns URL of the current document. * */ get documentURI() { return this.URL; } /** * Returns domain. * * @returns Domain. * */ get domain() { return this[PropertySymbol.window].location.hostname; } /** * Returns document visibility state. * * @returns the visibility state of the current document. * */ get visibilityState() { if (this.defaultView) { return VisibilityStateEnum_js_1.default.visible; } return VisibilityStateEnum_js_1.default.hidden; } /** * Returns document hidden state. * * @returns the hidden state of the current document. * */ get hidden() { if (this.defaultView) { return false; } return true; } /** * Gets the currently executing script element. * * @returns the currently executing script element. */ get currentScript() { return this[PropertySymbol.currentScript]; } /** * Inserts a set of Node objects or DOMString objects after the last child of the ParentNode. DOMString objects are inserted as equivalent Text nodes. * * @param nodes List of Node or DOMString. */ append(...nodes) { ParentNodeUtility_js_1.default.append(this, ...nodes); } /** * Inserts a set of Node objects or DOMString objects before the first child of the ParentNode. DOMString objects are inserted as equivalent Text nodes. * * @param nodes List of Node or DOMString. */ prepend(...nodes) { ParentNodeUtility_js_1.default.prepend(this, ...nodes); } /** * Replaces the existing children of a node with a specified new set of children. * * @param nodes List of Node or DOMString. */ replaceChildren(...nodes) { ParentNodeUtility_js_1.default.replaceChildren(this, ...nodes); } /** * Query CSS selector to find matching elments. * * @param selector CSS selector. * @returns Matching elements. */ querySelectorAll(selector) { return QuerySelector_js_1.default.querySelectorAll(this, selector); } /** * Query CSS Selector to find matching node. * * @param selector CSS selector. * @returns Matching element. */ querySelector(selector) { return QuerySelector_js_1.default.querySelector(this, selector); } /** * Returns true if the command is supported. * @deprecated * @param _ Command. * @returns True if the command is supported, false otherwise. */ queryCommandSupported(_) { if (!arguments.length) { throw new this[PropertySymbol.window].TypeError("Failed to execute 'queryCommandSupported' on 'Document': 1 argument required, but only 0 present."); } return true; } /** * Returns an elements by class name. * * @param className Tag name. * @returns Matching element. */ getElementsByClassName(className) { return ParentNodeUtility_js_1.default.getElementsByClassName(this, className); } /** * Returns an elements by tag name. * * @param tagName Tag name. * @returns Matching element. */ getElementsByTagName(tagName) { return ParentNodeUtility_js_1.default.getElementsByTagName(this, tagName); } /** * Returns an elements by tag name and namespace. * * @param namespaceURI Namespace URI. * @param tagName Tag name. * @returns Matching element. */ getElementsByTagNameNS(namespaceURI, tagName) { return ParentNodeUtility_js_1.default.getElementsByTagNameNS(this, namespaceURI, tagName); } /** * Returns an element by ID. * * @param id ID. * @returns Matching element. */ getElementById(id) { return ParentNodeUtility_js_1.default.getElementById(this, id); } /** * Returns an element by Name. * * @returns Matching element. * @param name */ getElementsByName(name) { return QuerySelector_js_1.default.querySelectorAll(this, `[name="${name}"]`); } /** * Replaces the document HTML with new HTML. * * @param html HTML. */ write(html) { const root = XMLParser_js_1.default.parse(this, html, { evaluateScripts: true }); if (this[PropertySymbol.isFirstWrite] || this[PropertySymbol.isFirstWriteAfterOpen]) { if (this[PropertySymbol.isFirstWrite]) { if (!this[PropertySymbol.isFirstWriteAfterOpen]) { this.open(); } this[PropertySymbol.isFirstWrite] = false; } this[PropertySymbol.isFirstWriteAfterOpen] = false; let documentElement = null; let documentTypeNode = null; for (const node of root[PropertySymbol.nodeArray]) { if (node['tagName'] === 'HTML') { documentElement = node; } else if (node[PropertySymbol.nodeType] === NodeTypeEnum_js_1.default.documentTypeNode) { documentTypeNode = node; } if (documentElement && documentTypeNode) { break; } } if (documentElement) { if (!this.documentElement) { if (documentTypeNode) { this.appendChild(documentTypeNode); } this.appendChild(documentElement); const head = ParentNodeUtility_js_1.default.getElementByTagName(this, 'head'); let body = ParentNodeUtility_js_1.default.getElementByTagName(this, 'body'); if (!body) { body = this.createElement('body'); documentElement.appendChild(this.createElement('body')); } if (!head) { documentElement.insertBefore(this.createElement('head'), body); } } else { const rootBody = ParentNodeUtility_js_1.default.getElementByTagName(root, 'body'); const body = ParentNodeUtility_js_1.default.getElementByTagName(this, 'body'); if (rootBody && body) { const childNodes = rootBody[PropertySymbol.nodeArray]; while (childNodes.length) { body.appendChild(childNodes[0]); } } } // Remaining nodes outside the element are added to the element. const body = ParentNodeUtility_js_1.default.getElementByTagName(this, 'body'); if (body) { const childNodes = root[PropertySymbol.nodeArray]; while (childNodes.length) { const child = childNodes[0]; if (child['tagName'] !== 'HTML' && child[PropertySymbol.nodeType] !== NodeTypeEnum_js_1.default.documentTypeNode) { body.appendChild(child); } } } } else { const documentElement = this.createElement('html'); const bodyElement = this.createElement('body'); const headElement = this.createElement('head'); const childNodes = root[PropertySymbol.nodeArray]; while (childNodes.length) { bodyElement.appendChild(childNodes[0]); } documentElement.appendChild(headElement); documentElement.appendChild(bodyElement); this.appendChild(documentElement); } } else { const bodyNode = ParentNodeUtility_js_1.default.getElementByTagName(root, 'body'); const body = ParentNodeUtility_js_1.default.getElementByTagName(this, 'body'); const childNodes = (bodyNode || root)[PropertySymbol.nodeArray]; while (childNodes.length) { body.appendChild(childNodes[0]); } } } /** * Opens the document. * * @returns Document. */ open() { this[PropertySymbol.isFirstWriteAfterOpen] = true; for (const eventType of this[PropertySymbol.listeners].bubbling.keys()) { const listeners = this[PropertySymbol.listeners].bubbling.get(eventType); if (listeners) { for (const listener of listeners) { this.removeEventListener(eventType, listener); } } } for (const eventType of this[PropertySymbol.listeners].capturing.keys()) { const listeners = this[PropertySymbol.listeners].capturing.get(eventType); if (listeners) { for (const listener of listeners) { this.removeEventListener(eventType, listener); } } } const childNodes = this[PropertySymbol.nodeArray]; while (childNodes.length) { this.removeChild(childNodes[0]); } return this; } /** * Closes the document. */ close() { } /** * Creates an element. * * @param qualifiedName Tag name. * @param [options] Options. * @param [options.is] Tag name of a custom element previously defined via customElements.define(). * @returns Element. */ createElement(qualifiedName, options) { return (this.createElementNS(NamespaceURI_js_1.default.html, StringUtility_js_1.default.asciiLowerCase(String(qualifiedName)), options)); } /** * Creates an element with the specified namespace URI and qualified name. * * @param namespaceURI Namespace URI. * @param qualifiedName Tag name. * @param [options] Options. * @param [options.is] Tag name of a custom element previously defined via customElements.define(). * @returns Element. */ createElementNS(namespaceURI, qualifiedName, options) { const window = this[PropertySymbol.window]; qualifiedName = String(qualifiedName); if (!qualifiedName) { throw new window.DOMException("Failed to execute 'createElementNS' on 'Document': The qualified name provided is empty."); } // SVG element if (namespaceURI === NamespaceURI_js_1.default.svg) { const config = SVGElementConfig_js_1.default[qualifiedName.toLowerCase()]; const elementClass = config && config.localName === qualifiedName ? window[config.className] : window.SVGElement; const element = NodeFactory_js_1.default.createNode(this, elementClass); element[PropertySymbol.tagName] = qualifiedName; element[PropertySymbol.localName] = qualifiedName; element[PropertySymbol.namespaceURI] = namespaceURI; element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null; return element; } // Custom HTML element const customElement = window.customElements[PropertySymbol.registry]?.[options && options.is ? String(options.is) : qualifiedName]; if (customElement) { const element = new customElement.elementClass(); element[PropertySymbol.tagName] = qualifiedName.toUpperCase(); element[PropertySymbol.localName] = qualifiedName; element[PropertySymbol.namespaceURI] = namespaceURI; element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null; return element; } const elementClass = HTMLElementConfig_js_1.default[qualifiedName] ? window[HTMLElementConfig_js_1.default[qualifiedName].className] : null; // Known HTML element if (elementClass) { const element = NodeFactory_js_1.default.createNode(this, elementClass); element[PropertySymbol.tagName] = qualifiedName.toUpperCase(); element[PropertySymbol.localName] = qualifiedName; element[PropertySymbol.namespaceURI] = namespaceURI; element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null; return element; } // Unknown HTML element (if it has an hyphen in the name, it is a custom element that hasn't been defined yet) const unknownElementClass = qualifiedName.includes('-') ? window.HTMLElement : window.HTMLUnknownElement; const element = NodeFactory_js_1.default.createNode(this, unknownElementClass); element[PropertySymbol.tagName] = qualifiedName.toUpperCase(); element[PropertySymbol.localName] = qualifiedName; element[PropertySymbol.namespaceURI] = namespaceURI; element[PropertySymbol.isValue] = options && options.is ? String(options.is) : null; return element; } /* eslint-enable jsdoc/valid-types */ /** * Creates a text node. * * @param [data] Text data. * @returns Text node. */ createTextNode(data) { if (arguments.length < 1) { throw new this[PropertySymbol.window].TypeError(`Failed to execute 'createTextNode' on 'Document': 1 argument required, but only ${arguments.length} present.`); } // We should use the NodeFactory and not the class constructor, so that owner document will be this document return NodeFactory_js_1.default.createNode(this, Text_js_1.default, String(data)); } /** * Creates a comment node. * * @param [data] Text data. * @returns Text node. */ createComment(data) { if (arguments.length < 1) { throw new this[PropertySymbol.window].TypeError(`Failed to execute 'createComment' on 'Document': 1 argument required, but only ${arguments.length} present.`); } // We should use the NodeFactory and not the class constructor, so that owner document will be this document return NodeFactory_js_1.default.createNode(this, Comment_js_1.default, String(data)); } /** * Creates a document fragment. * * @returns Document fragment. */ createDocumentFragment() { // We should use the NodeFactory and not the class constructor, so that owner document will be this document return NodeFactory_js_1.default.createNode(this, DocumentFragment_js_1.default); } /** * Creates a node iterator. * * @param root Root. * @param [whatToShow] What to show. * @param [filter] Filter. */ createNodeIterator(root, whatToShow = -1, filter = null) { return new NodeIterator_js_1.default(root, whatToShow, filter); } /** * Creates a Tree Walker. * * @param root Root. * @param [whatToShow] What to show. * @param [filter] Filter. */ createTreeWalker(root, whatToShow = -1, filter = null) { return new TreeWalker_js_1.default(root, whatToShow, filter); } /** * Creates an event. * * @deprecated * @param type Type. * @returns Event. */ createEvent(type) { if (typeof this[PropertySymbol.window][type] === 'function') { return new this[PropertySymbol.window][type]('init'); } return new Event_js_1.default('init'); } /** * Creates an Attr node. * * @param qualifiedName Name. * @returns Attribute. */ createAttribute(qualifiedName) { return this.createAttributeNS(null, qualifiedName.toLowerCase()); } /** * Creates a namespaced Attr node. * * @param namespaceURI Namespace URI. * @param qualifiedName Qualified name. * @returns Element. */ createAttributeNS(namespaceURI, qualifiedName) { // We should use the NodeFactory and not the class constructor, so that owner document will be this document const attribute = NodeFactory_js_1.default.createNode(this, Attr_js_1.default); const parts = qualifiedName.split(':'); attribute[PropertySymbol.namespaceURI] = namespaceURI; attribute[PropertySymbol.name] = qualifiedName; attribute[PropertySymbol.localName] = parts[1] ?? qualifiedName; attribute[PropertySymbol.prefix] = parts[0] ?? null; return attribute; } /** * Imports a node. * * @param node Node to import. * @param [deep=false] Set to "true" if the clone should be deep. */ importNode(node, deep = false) { if (!(node instanceof Node_js_1.default)) { throw new this[PropertySymbol.window].DOMException('Parameter 1 was not of type Node.'); } const clone = node.cloneNode(deep); this.#importNode(clone); return clone; } /** * Creates a range. * * @returns Range. */ createRange() { return new this[PropertySymbol.window].Range(); } /** * Adopts a node. * * @param node Node to adopt. * @returns Adopted node. */ adoptNode(node) { if (!(node instanceof Node_js_1.default)) { throw new this[PropertySymbol.window].DOMException('Parameter 1 was not of type Node.'); } const adopted = node[PropertySymbol.parentNode] ? node[PropertySymbol.parentNode].removeChild(node) : node; const document = this; Object.defineProperty(adopted, 'ownerDocument', { value: document }); return adopted; } /** * Returns selection. * * @returns Selection. */ getSelection() { if (!this.#selection) { this.#selection = new Selection_js_1.default(this); } return this.#selection; } /** * Returns a boolean value indicating whether the document or any element inside the document has focus. * * @returns "true" if the document has focus. */ hasFocus() { return !!this.activeElement; } /** * Creates a Processing Instruction node. * * @param target Target. * @param data Data. * @returns ProcessingInstruction. */ createProcessingInstruction(target, data) { if (arguments.length < 2) { throw new this[PropertySymbol.window].TypeError(`Failed to execute 'createProcessingInstruction' on 'Document': 2 arguments required, but only ${arguments.length} present.`); } target = String(target); data = String(data); if (!target || !PROCESSING_INSTRUCTION_TARGET_REGEXP.test(target)) { throw new this[PropertySymbol.window].DOMException(`Failed to execute 'createProcessingInstruction' on 'Document': The target provided ('${target}') is not a valid name.`); } if (data.includes('?>')) { throw new this[PropertySymbol.window].DOMException(`Failed to execute 'createProcessingInstruction' on 'Document': The data provided ('?>') contains '?>'`); } // We should use the NodeFactory and not the class constructor, so that owner document will be this document const element = NodeFactory_js_1.default.createNode(this, ProcessingInstruction_js_1.default); element[PropertySymbol.data] = data; element[PropertySymbol.target] = target; return element; } /** * Get element at a given point. * * @param _x horizontal coordinate * @param _y vertical coordinate * @returns Always returns null since Happy DOM does not render elements. */ elementFromPoint(_x, _y) { return null; } /** * Imports a node. * * @param node Node. */ #importNode(node) { node[PropertySymbol.ownerDocument] = this; for (const child of node[PropertySymbol.nodeArray]) { this.#importNode(child); } } } exports.default = Document; //# sourceMappingURL=Document.cjs.map