svgdom
Version:
Straightforward DOM implementation for SVG, HTML and XML
1,449 lines (1,124 loc) • 401 kB
JavaScript
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "fontkit":
/*!**************************!*\
!*** external "fontkit" ***!
\**************************/
/***/ ((module) => {
module.exports = require("fontkit");
/***/ }),
/***/ "image-size":
/*!*****************************!*\
!*** external "image-size" ***!
\*****************************/
/***/ ((module) => {
module.exports = require("image-size");
/***/ }),
/***/ "sax":
/*!**********************!*\
!*** external "sax" ***!
\**********************/
/***/ ((module) => {
module.exports = require("sax");
/***/ }),
/***/ "node:path":
/*!****************************!*\
!*** external "node:path" ***!
\****************************/
/***/ ((module) => {
module.exports = require("node:path");
/***/ }),
/***/ "node:url":
/*!***************************!*\
!*** external "node:url" ***!
\***************************/
/***/ ((module) => {
module.exports = require("node:url");
/***/ }),
/***/ "path":
/*!***********************!*\
!*** external "path" ***!
\***********************/
/***/ ((module) => {
module.exports = require("path");
/***/ }),
/***/ "./src/config.js":
/*!***********************!*\
!*** ./src/config.js ***!
\***********************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "config": () => (/* binding */ config),
/* harmony export */ "getConfig": () => (/* binding */ getConfig),
/* harmony export */ "getFonts": () => (/* binding */ getFonts),
/* harmony export */ "preloadFonts": () => (/* binding */ preloadFonts),
/* harmony export */ "setFontDir": () => (/* binding */ setFontDir),
/* harmony export */ "setFontFamilyMappings": () => (/* binding */ setFontFamilyMappings)
/* harmony export */ });
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! path */ "path");
/* harmony import */ var fontkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fontkit */ "fontkit");
const _config = {}
const fonts = {}
const setFontDir = function (dir) {
_config.fontDir = dir
return this
}
const setFontFamilyMappings = function (map) {
_config.fontFamilyMappings = map
return this
}
// TODO: make async
const preloadFonts = () => {
const map = _config.fontFamilyMappings
for (const [ font, file ] of Object.entries(map)) {
const filename = path__WEBPACK_IMPORTED_MODULE_0__.join(_config.fontDir, file)
try {
fonts[font] = (0,fontkit__WEBPACK_IMPORTED_MODULE_1__.openSync)(filename)
} catch (e) {
console.warn(`Could not load font file for ${font}`, e)
}
}
return undefined
}
const getConfig = () => _config
const getFonts = () => fonts
const config = {
setFontDir,
setFontFamilyMappings,
preloadFonts,
getConfig,
getFonts
}
/***/ }),
/***/ "./src/dom/Attr.js":
/*!*************************!*\
!*** ./src/dom/Attr.js ***!
\*************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Attr": () => (/* binding */ Attr)
/* harmony export */ });
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
/* harmony import */ var _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/namespaces.js */ "./src/utils/namespaces.js");
class Attr extends _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node {
constructor (name, props, ns) {
super(name, { nodeValue: '', ...props }, ns)
// Follow spec and lowercase nodeName for html
this.nodeName = ns === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_1__.html ? name.toLowerCase() : name
this.nodeType = _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.ATTRIBUTE_NODE
this.ownerElement = null
}
get value () {
return this.nodeValue
}
set value (val) {
this.nodeValue = val
}
get name () {
return this.nodeName
}
}
/***/ }),
/***/ "./src/dom/CharacterData.js":
/*!**********************************!*\
!*** ./src/dom/CharacterData.js ***!
\**********************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "CharacterData": () => (/* binding */ CharacterData)
/* harmony export */ });
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
/* harmony import */ var _mixins_NonDocumentTypeChildNode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mixins/NonDocumentTypeChildNode.js */ "./src/dom/mixins/NonDocumentTypeChildNode.js");
/* harmony import */ var _mixins_ChildNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mixins/ChildNode.js */ "./src/dom/mixins/ChildNode.js");
class CharacterData extends _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node {
constructor (name, props) {
super(name, props)
this.data = this.nodeValue
}
appendData (data) {
this.data += data
}
deleteData (offset, count) {
this.data = this.data.slice(0, offset) + this.data.slice(0, offset + count)
}
insertData (offset, data) {
this.data = this.data.slice(0, offset) + data + this.data.slice(offset)
}
replaceData (offset, count, data) {
this.deleteData(offset, count)
this.insertData(offset, data)
}
substringData (offset, count) {
this.data = this.data.substr(offset, count)
}
get length () {
return this.data.length
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__.mixin)(_mixins_NonDocumentTypeChildNode_js__WEBPACK_IMPORTED_MODULE_2__.NonDocumentTypeChildNode, CharacterData)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__.mixin)(_mixins_ChildNode_js__WEBPACK_IMPORTED_MODULE_3__.ChildNode, CharacterData)
/***/ }),
/***/ "./src/dom/Comment.js":
/*!****************************!*\
!*** ./src/dom/Comment.js ***!
\****************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Comment": () => (/* binding */ Comment)
/* harmony export */ });
/* harmony import */ var _CharacterData_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./CharacterData.js */ "./src/dom/CharacterData.js");
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
class Comment extends _CharacterData_js__WEBPACK_IMPORTED_MODULE_0__.CharacterData {
constructor (name, props) {
super(name, props)
this.nodeType = _Node_js__WEBPACK_IMPORTED_MODULE_1__.Node.COMMENT_NODE
}
}
/***/ }),
/***/ "./src/dom/CustomEvent.js":
/*!********************************!*\
!*** ./src/dom/CustomEvent.js ***!
\********************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "CustomEvent": () => (/* binding */ CustomEvent)
/* harmony export */ });
/* harmony import */ var _Event_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Event.js */ "./src/dom/Event.js");
class CustomEvent extends _Event_js__WEBPACK_IMPORTED_MODULE_0__.Event {
constructor (name, props = {}) {
super(name)
this.detail = props.detail || null
this.cancelable = props.cancelable || false
}
}
/***/ }),
/***/ "./src/dom/Document.js":
/*!*****************************!*\
!*** ./src/dom/Document.js ***!
\*****************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DOMImplementation": () => (/* binding */ DOMImplementation),
/* harmony export */ "Document": () => (/* binding */ Document)
/* harmony export */ });
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
/* harmony import */ var _Comment_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Comment.js */ "./src/dom/Comment.js");
/* harmony import */ var _Text_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Text.js */ "./src/dom/Text.js");
/* harmony import */ var _Attr_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Attr.js */ "./src/dom/Attr.js");
/* harmony import */ var _DocumentFragment_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./DocumentFragment.js */ "./src/dom/DocumentFragment.js");
/* harmony import */ var _html_HTMLLinkElement_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./html/HTMLLinkElement.js */ "./src/dom/html/HTMLLinkElement.js");
/* harmony import */ var _html_HTMLScriptElement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./html/HTMLScriptElement.js */ "./src/dom/html/HTMLScriptElement.js");
/* harmony import */ var _html_HTMLImageElement_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./html/HTMLImageElement.js */ "./src/dom/html/HTMLImageElement.js");
/* harmony import */ var _html_HTMLElement_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./html/HTMLElement.js */ "./src/dom/html/HTMLElement.js");
/* harmony import */ var _mixins_elementAccess_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./mixins/elementAccess.js */ "./src/dom/mixins/elementAccess.js");
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
/* harmony import */ var _svg_SVGSVGElement_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./svg/SVGSVGElement.js */ "./src/dom/svg/SVGSVGElement.js");
/* harmony import */ var _svg_SVGPathElement_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./svg/SVGPathElement.js */ "./src/dom/svg/SVGPathElement.js");
/* harmony import */ var _svg_SVGTextContentElement_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./svg/SVGTextContentElement.js */ "./src/dom/svg/SVGTextContentElement.js");
/* harmony import */ var _svg_SVGGraphicsElement_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./svg/SVGGraphicsElement.js */ "./src/dom/svg/SVGGraphicsElement.js");
/* harmony import */ var _mixins_ParentNode_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./mixins/ParentNode.js */ "./src/dom/mixins/ParentNode.js");
/* harmony import */ var _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../utils/namespaces.js */ "./src/utils/namespaces.js");
/* harmony import */ var _DocumentType_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./DocumentType.js */ "./src/dom/DocumentType.js");
/* harmony import */ var _mixins_NonElementParentNode_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./mixins/NonElementParentNode.js */ "./src/dom/mixins/NonElementParentNode.js");
/* harmony import */ var _svg_SVGRectElement_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./svg/SVGRectElement.js */ "./src/dom/svg/SVGRectElement.js");
/* harmony import */ var _svg_SVGCircleElement_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./svg/SVGCircleElement.js */ "./src/dom/svg/SVGCircleElement.js");
/* harmony import */ var _svg_SVGLineElement_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./svg/SVGLineElement.js */ "./src/dom/svg/SVGLineElement.js");
/* harmony import */ var _svg_SVGEllipseElement_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./svg/SVGEllipseElement.js */ "./src/dom/svg/SVGEllipseElement.js");
/* harmony import */ var _svg_SVGForeignObjectElement_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./svg/SVGForeignObjectElement.js */ "./src/dom/svg/SVGForeignObjectElement.js");
/* harmony import */ var _svg_SVGImageElement_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./svg/SVGImageElement.js */ "./src/dom/svg/SVGImageElement.js");
function getChildByTagName (parent, name) {
for (let child = parent.firstChild; child != null; child = child.nextSibling) {
if (child.nodeType === _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.ELEMENT_NODE && child.nodeName === name) {
return child
}
}
return null
}
const getSVGElementForName = (name) => {
switch (name.toLowerCase()) {
case 'svg':
return _svg_SVGSVGElement_js__WEBPACK_IMPORTED_MODULE_11__.SVGSVGElement
case 'path':
return _svg_SVGPathElement_js__WEBPACK_IMPORTED_MODULE_12__.SVGPathElement
case 'circle':
return _svg_SVGCircleElement_js__WEBPACK_IMPORTED_MODULE_20__.SVGCircleElement
case 'ellipse':
return _svg_SVGEllipseElement_js__WEBPACK_IMPORTED_MODULE_22__.SVGEllipseElement
case 'line':
return _svg_SVGLineElement_js__WEBPACK_IMPORTED_MODULE_21__.SVGLineElement
case 'rect':
return _svg_SVGRectElement_js__WEBPACK_IMPORTED_MODULE_19__.SVGRectElement
case 'foreignObject':
return _svg_SVGForeignObjectElement_js__WEBPACK_IMPORTED_MODULE_23__.SVGForeignObjectElement
case 'image':
return _svg_SVGImageElement_js__WEBPACK_IMPORTED_MODULE_24__.SVGImageElement
case 'text':
case 'tspan':
case 'tref':
case 'altglyph':
case 'textpath':
return _svg_SVGTextContentElement_js__WEBPACK_IMPORTED_MODULE_13__.SVGTextContentElement
default:
return _svg_SVGGraphicsElement_js__WEBPACK_IMPORTED_MODULE_14__.SVGGraphicsElement
}
}
const getHTMLElementForName = (name) => {
switch (name.toLowerCase()) {
case 'img':
return _html_HTMLImageElement_js__WEBPACK_IMPORTED_MODULE_7__.HTMLImageElement
case 'link':
return _html_HTMLLinkElement_js__WEBPACK_IMPORTED_MODULE_5__.HTMLLinkElement
case 'script':
return _html_HTMLScriptElement_js__WEBPACK_IMPORTED_MODULE_6__.HTMLScriptElement
default:
return _html_HTMLElement_js__WEBPACK_IMPORTED_MODULE_8__.HTMLElement
}
}
const getElementForNamespace = (ns, name) => {
switch (ns) {
case _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_16__.svg:
return getSVGElementForName(name)
case _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_16__.html:
case null:
case '':
default:
return getHTMLElementForName(name)
}
}
// Feature/version pairs that DOMImplementation.hasFeature() returns true for. It returns false for anything else.
const supportedFeatures = {
xml: { '': true, '1.0': true, '2.0': true },
core: { '': true, '2.0': true },
html: { '': true, '1.0': true, '2.0': true },
xhtml: { '': true, '1.0': true, '2.0': true } // HTML
}
const DOMImplementation = {
hasFeature (feature, version) {
const f = supportedFeatures[(feature || '').toLowerCase()]
return (f && f[version || '']) || false
},
createDocumentType (qualifiedName, publicId, systemId) {
return new _DocumentType_js__WEBPACK_IMPORTED_MODULE_17__.DocumentType(qualifiedName, { publicId, systemId, ownerDocument: this })
},
createDocument (namespace, qualifiedName, doctype) {
const doc = new Document(namespace)
if (doctype) {
if (doctype.ownerDocument) {
throw new Error('the object is in the wrong Document, a call to importNode is required')
}
doctype.ownerDocument = doc
doc.appendChild(doctype)
}
if (qualifiedName) {
doc.appendChild(doc.createElementNS(namespace, qualifiedName))
}
return doc
},
createHTMLDocument (titleText = '') {
const d = new Document(_utils_namespaces_js__WEBPACK_IMPORTED_MODULE_16__.html)
const root = d.createElement('html')
const head = d.createElement('head')
const title = d.createElement('title')
title.appendChild(d.createTextNode(titleText))
head.appendChild(title)
root.appendChild(head)
root.appendChild(d.createElement('body'))
d.appendChild(root)
return d
}
}
class Document extends _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node {
constructor (ns) {
super('#document', {}, ns)
this.nodeType = _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.DOCUMENT_NODE
this.implementation = DOMImplementation
this.defaultView = null
}
// https://dom.spec.whatwg.org/#dom-document-createattribute
createAttribute (localName) {
if (this.namespaceURI === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_16__.html) {
localName = localName.toLowerCase()
}
return this.createAttributeNS(null, localName, true)
}
createAttributeNS (ns, qualifiedName, local = false) {
return new _Attr_js__WEBPACK_IMPORTED_MODULE_3__.Attr(qualifiedName, { ownerDocument: this, local }, ns)
}
createComment (text) {
return new _Comment_js__WEBPACK_IMPORTED_MODULE_1__.Comment('#comment', { nodeValue: text, ownerDocument: this })
}
createDocumentFragment (name) {
return new _DocumentFragment_js__WEBPACK_IMPORTED_MODULE_4__.DocumentFragment('#document-fragment', { ownerDocument: this })
}
createElement (localName) {
return this.createElementNS(this.namespaceURI, localName, true)
}
createElementNS (ns, qualifiedName, local = false) {
const Element = getElementForNamespace(ns, qualifiedName)
return new Element(qualifiedName, {
ownerDocument: this,
local
}, ns)
}
createTextNode (text) {
return new _Text_js__WEBPACK_IMPORTED_MODULE_2__.Text('#text', { nodeValue: text, ownerDocument: this })
}
get compatMode () {
return 'CSS1Compat' // always be in standards-mode
}
get body () {
return getChildByTagName(this.documentElement, 'BODY')
}
get head () {
return getChildByTagName(this.documentElement, 'HEAD')
}
get documentElement () {
return this.lastChild
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_10__.mixin)(_mixins_elementAccess_js__WEBPACK_IMPORTED_MODULE_9__.elementAccess, Document)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_10__.mixin)(_mixins_ParentNode_js__WEBPACK_IMPORTED_MODULE_15__.ParentNode, Document)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_10__.mixin)(_mixins_NonElementParentNode_js__WEBPACK_IMPORTED_MODULE_18__.NonElementParentNode, Document)
/***/ }),
/***/ "./src/dom/DocumentFragment.js":
/*!*************************************!*\
!*** ./src/dom/DocumentFragment.js ***!
\*************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DocumentFragment": () => (/* binding */ DocumentFragment)
/* harmony export */ });
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
/* harmony import */ var _mixins_elementAccess_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mixins/elementAccess.js */ "./src/dom/mixins/elementAccess.js");
/* harmony import */ var _mixins_ParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mixins/ParentNode.js */ "./src/dom/mixins/ParentNode.js");
/* harmony import */ var _mixins_NonElementParentNode_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./mixins/NonElementParentNode.js */ "./src/dom/mixins/NonElementParentNode.js");
class DocumentFragment extends _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node {
constructor (name, props) {
super(name, props)
this.nodeType = _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.DOCUMENT_FRAGMENT_NODE
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__.mixin)(_mixins_elementAccess_js__WEBPACK_IMPORTED_MODULE_2__.elementAccess, DocumentFragment)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__.mixin)(_mixins_ParentNode_js__WEBPACK_IMPORTED_MODULE_3__.ParentNode, DocumentFragment)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__.mixin)(_mixins_NonElementParentNode_js__WEBPACK_IMPORTED_MODULE_4__.NonElementParentNode, DocumentFragment)
/***/ }),
/***/ "./src/dom/DocumentType.js":
/*!*********************************!*\
!*** ./src/dom/DocumentType.js ***!
\*********************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DocumentType": () => (/* binding */ DocumentType)
/* harmony export */ });
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
/* harmony import */ var _mixins_ChildNode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mixins/ChildNode.js */ "./src/dom/mixins/ChildNode.js");
class DocumentType extends _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node {
constructor (name, props) {
super(name, props)
this.nodeType = _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.DOCUMENT_TYPE_NODE
this.name = name
const { publicId, systemId } = props
this.publicId = publicId || ''
this.systemId = systemId || ''
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_1__.mixin)(_mixins_ChildNode_js__WEBPACK_IMPORTED_MODULE_2__.ChildNode, DocumentType)
/***/ }),
/***/ "./src/dom/Element.js":
/*!****************************!*\
!*** ./src/dom/Element.js ***!
\****************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Element": () => (/* binding */ Element)
/* harmony export */ });
/* harmony import */ var _Node_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Node.js */ "./src/dom/Node.js");
/* harmony import */ var _mixins_ParentNode_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mixins/ParentNode.js */ "./src/dom/mixins/ParentNode.js");
/* harmony import */ var _mixins_elementAccess_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mixins/elementAccess.js */ "./src/dom/mixins/elementAccess.js");
/* harmony import */ var _html_HTMLParser_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./html/HTMLParser.js */ "./src/dom/html/HTMLParser.js");
/* harmony import */ var _DocumentFragment_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./DocumentFragment.js */ "./src/dom/DocumentFragment.js");
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
/* harmony import */ var _utils_tagUtils_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/tagUtils.js */ "./src/utils/tagUtils.js");
/* harmony import */ var _utils_mapUtils_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/mapUtils.js */ "./src/utils/mapUtils.js");
/* harmony import */ var _utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/strUtils.js */ "./src/utils/strUtils.js");
/* harmony import */ var _mixins_NonDocumentTypeChildNode_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./mixins/NonDocumentTypeChildNode.js */ "./src/dom/mixins/NonDocumentTypeChildNode.js");
/* harmony import */ var _mixins_ChildNode_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./mixins/ChildNode.js */ "./src/dom/mixins/ChildNode.js");
/* harmony import */ var _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../utils/namespaces.js */ "./src/utils/namespaces.js");
const validateAndExtract = (ns, name) => {
let prefix = null
let localname = name
if (!ns) ns = null
if (name.includes(':')) {
[ prefix, localname ] = name.split(':')
}
if (!ns && prefix) {
throw new Error('Namespace Error')
}
if (prefix === 'xml' && ns !== _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.xml) {
throw new Error('Namespace Error')
}
if ((prefix === 'xmlns' || name === 'xmlns') && ns !== _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.xmlns) {
throw new Error('Namespace Error')
}
if (prefix !== 'xmlns' && name !== 'xmlns' && ns === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.xmlns) {
throw new Error('Namespace Error')
}
return [ ns, prefix, localname ]
}
const getAttributeByNsAndLocalName = (el, ns, localName) => {
if (!ns) ns = null
return [ ...el.attrs ].find((node) => node.localName === localName && node.namespaceURI === ns)
}
const getAttributeByQualifiedName = (el, qualifiedName) => {
if (el.namespaceURI === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.html && el.ownerDocument.namespaceURI === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.html) {
qualifiedName = qualifiedName.toLowerCase()
}
return [ ...el.attrs ].find((node) => node.name === qualifiedName)
}
// This Proxy proxies all access to node.style to the css saved in the attribute
const getStyleProxy = (node) => {
return new Proxy(node, {
get (target, key) {
const styles = target.getAttribute('style') || ''
const styleMap = (0,_utils_mapUtils_js__WEBPACK_IMPORTED_MODULE_7__.cssToMap)(styles)
if (key === 'cssText') {
return styles
}
if (key === 'setProperty') {
return function (propertyName, value = '', priority = '') {
node.style[propertyName] = value + (priority ? ` !${priority}` : '')
}
}
if (key === 'getPropertyValue') {
return function (propertyName) {
return node.style[propertyName] ?? ''
}
}
key = (0,_utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__.decamelize)(key)
if (!styleMap.has(key)) return ''
return styleMap.get(key)
},
set (target, key, value) {
key = (0,_utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__.decamelize)(key)
if (key === 'css-text') {
// ensure correct spacing and syntax by converting back and forth
target.setAttribute('style', (0,_utils_mapUtils_js__WEBPACK_IMPORTED_MODULE_7__.mapToCss)((0,_utils_mapUtils_js__WEBPACK_IMPORTED_MODULE_7__.cssToMap)(value)))
return true
} else {
value = (0,_utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__.hexToRGB)(value.toString())
const styles = target.getAttribute('style') || ''
const styleMap = (0,_utils_mapUtils_js__WEBPACK_IMPORTED_MODULE_7__.cssToMap)(styles)
styleMap.set(key, value)
target.setAttribute('style', (0,_utils_mapUtils_js__WEBPACK_IMPORTED_MODULE_7__.mapToCss)(styleMap))
return true
}
}
})
}
// https://dom.spec.whatwg.org/#dom-element-setattributens
class Element extends _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node {
constructor (name, props, ns) {
super(name, props, ns)
this.style = getStyleProxy(this)
this.tagName = this.nodeName
}
getAttribute (qualifiedName) {
const attr = this.getAttributeNode(qualifiedName)
return attr ? attr.value : null
}
getAttributeNode (qualifiedName) {
return getAttributeByQualifiedName(this, qualifiedName)
}
getAttributeNodeNS (ns, localName) {
return getAttributeByNsAndLocalName(this, ns, localName)
}
getAttributeNS (ns, localName) {
const attr = this.getAttributeNodeNS(ns, localName)
return attr ? attr.value : null
}
getBoundingClientRect () {
throw new Error('Only implemented for SVG Elements')
}
hasAttribute (qualifiedName) {
const attr = this.getAttributeNode(qualifiedName)
return !!attr
}
hasAttributeNS (ns, localName) {
const attr = this.getAttributeNodeNS(ns, localName)
return !!attr
}
matches (query) {
return this.matchWithScope(query, this)
}
removeAttribute (qualifiedName) {
const attr = this.getAttributeNode(qualifiedName)
if (attr) {
this.removeAttributeNode(attr)
}
return attr
}
removeAttributeNode (node) {
if (!this.attrs.delete(node)) throw new Error('Attribute cannot be removed because it was not found on the element')
return node
}
// call is: d.removeAttributeNS('http://www.mozilla.org/ns/specialspace', 'align', 'center');
removeAttributeNS (ns, localName) {
const attr = this.getAttributeNodeNS(ns, localName)
if (attr) {
this.removeAttributeNode(attr)
}
return attr
}
/* The setAttribute(qualifiedName, value) method, when invoked, must run these steps:
If qualifiedName does not match the Name production in XML, then throw an "InvalidCharacterError" DOMException.
If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
Let attribute be the first attribute in this’s attribute list whose qualified name is qualifiedName, and null otherwise.
If attribute is null, create an attribute whose local name is qualifiedName, value is value, and node document is this’s node document, then append this attribute to this, and then return.
Change attribute to value.
*/
setAttribute (qualifiedName, value) {
// We have to do that here because we cannot check if `this` is in the correct namespace
// when doing it in createAttribute
if (this.namespaceURI === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.html && this.ownerDocument.namespaceURI === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_11__.html) {
qualifiedName = qualifiedName.toLowerCase()
}
let attr = this.getAttributeNode(qualifiedName)
if (!attr) {
// Because createAttribute lowercases the attribute in an html doc we have to use createAttributeNS
attr = this.ownerDocument.createAttributeNS(null, qualifiedName, true)
this.setAttributeNode(attr)
}
attr.value = value
}
/*
Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract.
Set an attribute value for this using localName, value, and also prefix and namespace.
If prefix is not given, set it to null.
If namespace is not given, set it to null.
Let attribute be the result of getting an attribute given namespace, localName, and element.
If attribute is null, create an attribute whose namespace is namespace, namespace prefix is prefix, local name is localName, value is value, and node document is element’s node document, then append this attribute to element, and then return.
Change attribute to value.
*/
setAttributeNode (node) {
this.attrs.add(node)
node.ownerElement = this
}
// call is: d.setAttributeNS('http://www.mozilla.org/ns/specialspace', 'spec:align', 'center');
setAttributeNS (namespace, name, value) {
// eslint-disable-next-line
const [ ns, prefix, localName ] = validateAndExtract(namespace, name)
let attr = this.getAttributeNodeNS(ns, localName)
if (!attr) {
attr = this.ownerDocument.createAttributeNS(ns, name)
this.setAttributeNode(attr) // setAttributeNodeNS is a synonym of setAttributeNode
}
attr.value = value
this.attrs.add(attr)
}
get attributes () {
return [ ...this.attrs ]
}
get className () {
return this.getAttribute('class')
}
set className (c) {
this.setAttribute('class', c)
}
get id () {
return this.getAttribute('id') || ''
}
set id (id) {
return this.setAttribute('id', id)
}
get innerHTML () {
return this.childNodes.map(node => {
if (node.nodeType === _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.TEXT_NODE) return (0,_utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__.htmlEntities)(node.data)
if (node.nodeType === _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.CDATA_SECTION_NODE) return (0,_utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__.cdata)(node.data)
if (node.nodeType === _Node_js__WEBPACK_IMPORTED_MODULE_0__.Node.COMMENT_NODE) return (0,_utils_strUtils_js__WEBPACK_IMPORTED_MODULE_8__.comment)(node.data)
return node.outerHTML
}).join('')
}
set innerHTML (str) {
while (this.firstChild) {
this.removeChild(this.firstChild)
}
// The parser adds the html to this
(0,_html_HTMLParser_js__WEBPACK_IMPORTED_MODULE_3__.HTMLParser)(str, this)
}
get outerHTML () {
return (0,_utils_tagUtils_js__WEBPACK_IMPORTED_MODULE_6__.tag)(this)
}
set outerHTML (str) {
const well = new _DocumentFragment_js__WEBPACK_IMPORTED_MODULE_4__.DocumentFragment()
;(0,_html_HTMLParser_js__WEBPACK_IMPORTED_MODULE_3__.HTMLParser)(str, well)
this.parentNode.insertBefore(well, this)
this.parentNode.removeChild(this)
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_5__.mixin)(_mixins_ParentNode_js__WEBPACK_IMPORTED_MODULE_1__.ParentNode, Element)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_5__.mixin)(_mixins_elementAccess_js__WEBPACK_IMPORTED_MODULE_2__.elementAccess, Element)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_5__.mixin)(_mixins_NonDocumentTypeChildNode_js__WEBPACK_IMPORTED_MODULE_9__.NonDocumentTypeChildNode, Element)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_5__.mixin)(_mixins_ChildNode_js__WEBPACK_IMPORTED_MODULE_10__.ChildNode, Element)
/***/ }),
/***/ "./src/dom/Event.js":
/*!**************************!*\
!*** ./src/dom/Event.js ***!
\**************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Event": () => (/* binding */ Event)
/* harmony export */ });
class Event {
constructor (type) {
this.type = type
this.cancelable = false
this.defaultPrevented = false
this.target = null
}
preventDefault () {
if (this.cancelable) {
this.defaultPrevented = true
}
}
}
/***/ }),
/***/ "./src/dom/EventTarget.js":
/*!********************************!*\
!*** ./src/dom/EventTarget.js ***!
\********************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "EventTarget": () => (/* binding */ EventTarget)
/* harmony export */ });
const $ = Symbol('private properties')
class EventTarget {
constructor () {
this[$] = {}
this[$].listeners = {}
}
addEventListener (type, callback) {
if (!(type in this[$].listeners)) {
this[$].listeners[type] = []
}
this[$].listeners[type].push(callback)
}
dispatchEvent (event) {
if (!(event.type in this[$].listeners)) { return true }
var stack = this[$].listeners[event.type]
event.target = this
stack.forEach(function (el) {
el(event)
})
return !event.defaultPrevented
}
removeEventListener (type, callback) {
if (!(type in this[$].listeners)) {
return
}
var stack = this[$].listeners[type]
for (var i = 0, il = stack.length; i < il; i++) {
if (stack[i] === callback) {
stack.splice(i, 1)
return
}
}
}
}
/***/ }),
/***/ "./src/dom/Node.js":
/*!*************************!*\
!*** ./src/dom/Node.js ***!
\*************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Node": () => (/* binding */ Node)
/* harmony export */ });
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
/* harmony import */ var _EventTarget_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./EventTarget.js */ "./src/dom/EventTarget.js");
/* harmony import */ var _utils_tagUtils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/tagUtils.js */ "./src/utils/tagUtils.js");
/* harmony import */ var _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/namespaces.js */ "./src/utils/namespaces.js");
const nodeTypes = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12
}
class Node extends _EventTarget_js__WEBPACK_IMPORTED_MODULE_1__.EventTarget {
constructor (name = '', props = {}, ns = null) {
super()
// If props.local is true, the element was Node was created with the non-namespace function
// that means whatever was passed as name is the local name even though it might look like a prefix
if (name.includes(':') && !props.local) {
;[ this.prefix, this.localName ] = name.split(':')
} else {
this.localName = name
this.prefix = null
}
// Follow spec and uppercase nodeName for html
this.nodeName = ns === _utils_namespaces_js__WEBPACK_IMPORTED_MODULE_3__.html ? name.toUpperCase() : name
this.namespaceURI = ns
this.nodeType = Node.ELEMENT_NODE
this.nodeValue = props.nodeValue != null ? props.nodeValue : null
this.childNodes = []
this.attrs = props.attrs || new Set()
this.ownerDocument = props.ownerDocument || null
this.parentNode = null
// this.namespaces = {}
// if (this.prefix) {
// this.namespaces[this.prefix] = ns
// } else {
// this.namespaces.default = ns
// }
if (props.childNodes) {
for (let i = 0, il = props.childNodes.length; i < il; ++i) {
this.appendChild(props.childNodes[i])
}
}
}
appendChild (node) {
return this.insertBefore(node)
}
cloneNode (deep = false) {
const clone = (0,_utils_tagUtils_js__WEBPACK_IMPORTED_MODULE_2__.cloneNode)(this)
if (deep) {
this.childNodes.forEach(function (el) {
const node = el.cloneNode(deep)
clone.appendChild(node)
})
}
return clone
}
contains (node) {
if (node === this) return false
while (node.parentNode) {
if (node === this) return true
node = node.parentNode
}
return false
}
getRootNode () {
if (!this.parentNode || this.nodeType === Node.DOCUMENT_NODE) return this
return this.parentNode.getRootNode()
}
hasChildNodes () {
return !!this.childNodes.length
}
insertBefore (node, before) {
let index = this.childNodes.indexOf(before)
if (index === -1) {
index = this.childNodes.length
}
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
let child
let oldChild = before
while ((child = node.childNodes.pop())) {
this.insertBefore(child, oldChild)
oldChild = child
}
return node
}
if (node.parentNode) {
node.parentNode.removeChild(node)
}
node.parentNode = this
// Object.setPrototypeOf(node.namespaces.prototype, this.namespaces.prototype)
this.childNodes.splice(index, 0, node)
return node
}
isDefaultNamespace (namespaceURI) {
switch (this.nodeType) {
case Node.ELEMENT_NODE:
if (!this.prefix) {
return this.namespaceURI === namespaceURI
}
if (this.hasAttribute('xmlns')) {
return this.getAttribute('xmlns')
}
// EntityReferences may have to be skipped to get to it
if (this.parentNode) {
return this.parentNode.isDefaultNamespace(namespaceURI)
}
return false
case Node.DOCUMENT_NODE:
return this.documentElement.isDefaultNamespace(namespaceURI)
case Node.ENTITY_NODE:
case Node.NOTATION_NODE:
case Node.DOCUMENT_TYPE_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
return false
case Node.ATTRIBUTE_NODE:
if (this.ownerElement) {
return this.ownerElement.isDefaultNamespace(namespaceURI)
}
return false
default:
// EntityReferences may have to be skipped to get to it
if (this.parentNode) {
return this.parentNode.isDefaultNamespace(namespaceURI)
}
return false
}
}
isEqualNode (node) {
this.normalize()
node.normalize()
let bool = this.nodeName === node.nodeName
bool = bool && this.localName === node.localName
bool = bool && this.namespaceURI === node.namespaceURI
bool = bool && this.prefix === node.prefix
bool = bool && this.nodeValue === node.nodeValue
bool = bool && this.childNodes.length === node.childNodes.length
// dont check children recursively when the count doesnt event add up
if (!bool) return false
bool = bool && !this.childNodes.reduce((last, curr, index) => {
return last && curr.isEqualNode(node.childNodes[index])
}, true)
// FIXME: Use attr nodes
/* bool = bool && ![ ...this.attrs.entries() ].reduce((last, curr, index) => {
const [ key, val ] = node.attrs.entries()
return last && curr[0] === key && curr[1] === val
}, true) */
/*
TODO:
For two DocumentType nodes to be equal, the following conditions must also be satisfied:
The following string attributes are equal: publicId, systemId, internalSubset.
The entities NamedNodeMaps are equal.
The notations NamedNodeMaps are equal.
*/
if (this.nodeType === Node.DOCUMENT_TYPE_NODE && node.nodeType === Node.DOCUMENT_TYPE_NODE) {
bool = bool && this.publicId === node.publicId
bool = bool && this.systemId === node.systemId
bool = bool && this.internalSubset === node.internalSubset
}
return bool
}
isSameNode (node) {
return this === node
}
lookupNamespacePrefix (namespaceURI, originalElement) {
if (this.namespaceURI && this.namespaceURI === namespaceURI && this.prefix
&& originalElement.lookupNamespaceURI(this.prefix) === namespaceURI) {
return this.prefix
}
for (const [ key, val ] of this.attrs.entries()) {
if (!key.includes(':')) continue
const [ attrPrefix, name ] = key.split(':')
if (attrPrefix === 'xmlns' && val === namespaceURI && originalElement.lookupNamespaceURI(name) === namespaceURI) {
return name
}
}
// EntityReferences may have to be skipped to get to it
if (this.parentNode) {
return this.parentNode.lookupNamespacePrefix(namespaceURI, originalElement)
}
return null
}
lookupNamespaceURI (prefix) {
switch (this.nodeType) {
case Node.ELEMENT_NODE:
if (this.namespaceURI != null && this.prefix === prefix) {
// Note: prefix could be "null" in this case we are looking for default namespace
return this.namespaceURI
}
for (const [ key, val ] of this.attrs.entries()) {
if (!key.includes(':')) continue
const [ attrPrefix, name ] = key.split(':')
if (attrPrefix === 'xmlns' && name === prefix) {
if (val != null) {
return val
}
return null
// FIXME: Look up if prefix or attrPrefix
} else if (name === 'xmlns' && prefix == null) {
if (val != null) {
return val
}
return null
}
}
// EntityReferences may have to be skipped to get to it
if (this.parentNode) {
return this.parentNode.lookupNamespaceURI(prefix)
}
return null
case Node.DOCUMENT_NODE:
return this.documentElement.lookupNamespaceURI(prefix)
case Node.ENTITY_NODE:
case Node.NOTATION_NODE:
case Node.DOCUMENT_TYPE_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
return null
case Node.ATTRIBUTE_NODE:
if (this.ownerElement) {
return this.ownerElement.lookupNamespaceURI(prefix)
}
return null
default:
// EntityReferences may have to be skipped to get to it
if (this.parentNode) {
return this.parentNode.lookupNamespaceURI(prefix)
}
return null
}
}
lookupPrefix (namespaceURI) {
if (!namespaceURI) {
return null
}
const type = this.nodeType
switch (type) {
case Node.ELEMENT_NODE:
return this.lookupNamespacePrefix(namespaceURI, this)
case Node.DOCUMENT_NODE:
return this.documentElement.lookupNamespacePrefix(namespaceURI)
case Node.ENTITY_NODE :
case Node.NOTATION_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
case Node.DOCUMENT_TYPE_NODE:
return null // type is unknown
case Node.ATTRIBUTE_NODE:
if (this.ownerElement) {
return this.ownerElement.lookupNamespacePrefix(namespaceURI)
}
return null
default:
// EntityReferences may have to be skipped to get to it
if (this.parentNode) {
return this.parentNode.lookupNamespacePrefix(namespaceURI)
}
return null
}
}
normalize () {
const childNodes = []
for (const node of this.childNodes) {
const last = childNodes.shift()
if (!last) {
if (node.data) {
childNodes.unshift(node)
}
continue
}
if (node.nodeType === Node.TEXT_NODE) {
if (!node.data) {
childNodes.unshift(last)
continue
}
if (last.nodeType === Node.TEXT_NODE) {
const merged = this.ownerDocument.createTextNode(last.data + node.data)
childNodes.push(merged)
continue
}
childNodes.push(last, node)
}
}
childNodes.forEach(node => {
node.parentNode = this
})
this.childNodes = childNodes
// this.childNodes = this.childNodes.forEach((textNodes, node) => {
// // FIXME: If first node is an empty textnode, what do we do? -> spec
// if (!textNodes) return [ node ]
// var last = textNodes.pop()
// if (node.nodeType === Node.TEXT_NODE) {
// if (!node.data) return textNodes
// if (last.nodeType === Node.TEXT_NODE) {
// const merged = this.ownerDocument.createTextNode(last.data + ' ' + node.data)
// textNodes.push(merged)
// return textNodes.concat(merged)
// }
// } else {
// textNodes.push(last, node)
// }
// return textNodes
// }, null)
}
removeChild (node) {
node.parentNode = null
// Object.setPrototypeOf(node, null)
const index = this.childNodes.indexOf(node)
if (index === -1) return node
this.childNodes.splice(index, 1)
return node
}
replaceChild (newChild, oldChild) {
const before = oldChild.nextSibling
this.removeChild(oldChild)
this.insertBefore(newChild, before)
return oldChild
}
get nextSibling () {
const child = this.parentNode && this.parentNode.childNodes[this.parentNode.childNodes.indexOf(this) + 1]
return child || null
}
get previousSibling () {
const child = this.parentNode && this.parentNode.childNodes[this.parentNode.childNodes.indexOf(this) - 1]
return child || null
}
get textContent () {
if (this.nodeType === Node.TEXT_NODE) return this.data
if (this.nodeType === Node.CDATA_SECTION_NODE) return this.data
if (this.nodeType === Node.COMMENT_NODE) return this.data
return this.childNodes.reduce(function (last, current) {
return last + current.textContent
}, '')
}
set textContent (text) {
if (this.nodeType === Node.TEXT_NODE || this.nodeType === Node.CDATA_SECTION_NODE || this.nodeType === Node.COMMENT_NODE) {
this.data = text
return
}
this.childNodes = []
this.appendChild(this.ownerDocument.createTextNode(text))
}
get lastChild () {
return this.childNodes[this.childNodes.length - 1] || null
}
get firstChild () {
return this.childNodes[0] || null
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_0__.extendStatic)(Node, nodeTypes)
;(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_0__.extend)(Node, nodeTypes)
/***/ }),
/***/ "./src/dom/NodeFilter.js":
/*!*******************************!*\
!*** ./src/dom/NodeFilter.js ***!
\*******************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "NodeFilter": () => (/* binding */ NodeFilter)
/* harmony export */ });
/* harmony import */ var _utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/objectCreationUtils.js */ "./src/utils/objectCreationUtils.js");
class NodeFilter {
acceptNode () {
return NodeFilter.FILTER_ACCEPT
}
}
(0,_utils_objectCreationUtils_js__WEBPACK_IMPORTED_MODULE_0__.extendStatic)(NodeFilter, {
FILTER_