UNPKG

uhtml

Version:
134 lines (111 loc) • 3.43 kB
'use strict'; const { DOCUMENT_NODE } = require('domconstants/constants'); const { setParentNode } = require('./utils.js'); const { childNodes, documentElement, nodeName, ownerDocument } = require('./symbols.js'); const Attribute = (require('./attribute.js')); const Comment = (require('./comment.js')); const DocumentFragment = (require('./document-fragment.js')); const DocumentType = (require('./document-type.js')); const Element = (require('./element.js')); const Event = (require('./event.js')); const SVGElement = (require('./svg-element.js')); const Parent = (require('./parent.js')); const Range = (require('./range.js')); const Text = (require('./text.js')); const TreeWalker = (require('./tree-walker.js')); const doctype = Symbol('doctype'); const head = Symbol('head'); const body = Symbol('body'); const defaultView = Object.create(globalThis, { Event: { value: Event }, }); /** @typedef {import("./attribute.js").Attribute} Attribute */ module.exports = class Document extends Parent { constructor(type = 'html') { super(DOCUMENT_NODE, null)[nodeName] = '#document'; this[documentElement] = null; this[doctype] = null; this[head] = null; this[body] = null; if (type === 'html') { const html = (this[documentElement] = new Element(type, this)); this[childNodes] = [ (this[doctype] = new DocumentType(type, this)), html ].map(setParentNode, this) html[childNodes] = [ (this[head] = new Element('head', this)), (this[body] = new Element('body', this)), ].map(setParentNode, html); } } /** @type {globalThis} */ get defaultView() { return defaultView; } /** @type {import("./document-type.js").default?} */ get doctype() { return this[doctype]; } /** @type {import("./element.js").default?} */ get documentElement() { return this[documentElement]; } /** @type {import("./element.js").default?} */ get head() { return this[head]; } /** @type {import("./element.js").default?} */ get body() { return this[body]; } /** @type {Attribute} */ createAttribute(name) { const attribute = new Attribute(name); attribute[ownerDocument] = this; return attribute; } /** @type {import("./comment.js").default} */ createComment(data) { return new Comment(data, this); } /** @type {import("./document-fragment.js").default} */ createDocumentFragment() { return new DocumentFragment(this); } /** @type {import("./element.js").default} */ createElement(name, options = null) { const element = new Element(name, this); if (options?.is) element.setAttribute('is', options.is); return element; } /** @type {import("./svg-element.js").default} */ createElementNS(_, name) { return new SVGElement(name, this); } /** @type {globalThis.Range} */ createRange() { return new Range; } /** @type {import("./text.js").default} */ createTextNode(data) { return new Text(data, this); } /** @type {globalThis.TreeWalker} */ createTreeWalker(parent, accept) { return new TreeWalker(parent, accept); } /** * Same as `document.importNode` * @template T * @param {T} externalNode * @param {boolean} deep * @returns {T} */ importNode(externalNode, deep = false) { return externalNode.cloneNode(deep); } toString() { return this[childNodes].join(''); } }