diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7f2af3f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "prettier.printWidth": 120, + "prettier.singleQuote": true, + "prettier.useTabs": true +} diff --git a/package.json b/package.json index 3f8bb4d..ab07905 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "lolex": "^1.6.0", "mocha": "^3.3.0", "parse5": "^3.0.2", + "prettier": "^1.4.4", "rimraf": "^2.6.1", "rollup": "^0.41.6", "rollup-plugin-babili": "^3.0.0", diff --git a/rollup.config.js b/rollup.config.js index 704092a..60d6813 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,14 +4,11 @@ const { main: MAIN_DEST_FILE, module: MODULE_DEST_FILE } = require('./package.js export default { entry: 'lib/index.js', - targets: [ - { dest: MAIN_DEST_FILE, format: 'umd' }, - { dest: MODULE_DEST_FILE, format: 'es' }, - ], + targets: [{ dest: MAIN_DEST_FILE, format: 'umd' }, { dest: MODULE_DEST_FILE, format: 'es' }], moduleName: 'slimdom', exports: 'named', sourceMap: true, - onwarn (warning) { + onwarn(warning) { // Ignore "this is undefined" warning triggered by typescript's __extends helper if (warning.code === 'THIS_IS_UNDEFINED') { return; @@ -25,4 +22,4 @@ export default { sourceMap: true }) ] -} +}; diff --git a/src/Attr.ts b/src/Attr.ts index 7c26f20..cefcad2 100644 --- a/src/Attr.ts +++ b/src/Attr.ts @@ -10,20 +10,20 @@ import { NodeType } from './util/NodeType'; export default class Attr extends Node { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.ATTRIBUTE_NODE; } - public get nodeName (): string { + public get nodeName(): string { // Return the qualified name return this.name; } - public get nodeValue (): string | null { + public get nodeValue(): string | null { return this._value; } - public set nodeValue (newValue: string | null) { + public set nodeValue(newValue: string | null) { // if the new value is null, act as if it was the empty string instead if (newValue === null) { newValue = ''; @@ -42,11 +42,11 @@ export default class Attr extends Node { private _value: string; - public get value (): string { + public get value(): string { return this._value; } - public set value (value: string) { + public set value(value: string) { setExistingAttributeValue(this, value); } @@ -62,7 +62,14 @@ export default class Attr extends Node { * @param value The value for the attribute * @param element The element for the attribute, or null if the attribute is not attached to an element */ - constructor (document: Document, namespace: string | null, prefix: string | null, localName: string, value: string, element: Element | null) { + constructor( + document: Document, + namespace: string | null, + prefix: string | null, + localName: string, + value: string, + element: Element | null + ) { super(document); this.namespaceURI = namespace; this.prefix = prefix; @@ -80,7 +87,7 @@ export default class Attr extends Node { * * @return A shallow copy of the context object */ - public _copy (document: Document): Attr { + public _copy(document: Document): Attr { // Set copy’s namespace, namespace prefix, local name, and value, to those of node. return new Attr(document, this.namespaceURI, this.prefix, this.localName, this.value, null); } @@ -92,14 +99,13 @@ export default class Attr extends Node { * @param attribute The attribute to set the value of * @param value The new value for attribute */ -function setExistingAttributeValue (attribute: Attr, value: string) { +function setExistingAttributeValue(attribute: Attr, value: string) { // 1. If attribute’s element is null, then set attribute’s value to value. const element = attribute.ownerElement; if (element === null) { (attribute as any)._value = value; - } - // 2. Otherwise, change attribute from attribute’s element to value. - else { + } else { + // 2. Otherwise, change attribute from attribute’s element to value. changeAttribute(attribute, element, value); } } diff --git a/src/CDATASection.ts b/src/CDATASection.ts index 7d24cc4..330c89e 100644 --- a/src/CDATASection.ts +++ b/src/CDATASection.ts @@ -5,11 +5,11 @@ import { NodeType } from './util/NodeType'; export default class CDATASection extends Text { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.CDATA_SECTION_NODE; } - public get nodeName (): string { + public get nodeName(): string { return '#cdata-section'; } @@ -21,7 +21,7 @@ export default class CDATASection extends Text { * @param document (non-standard) The node document to associate with the node * @param data The data for the node */ - constructor (document: Document, data: string) { + constructor(document: Document, data: string) { super(document, data); } @@ -32,7 +32,7 @@ export default class CDATASection extends Text { * * @return A shallow copy of the context object */ - public _copy (document: Document): CDATASection { + public _copy(document: Document): CDATASection { // Set copy’s data, to that of node. return new CDATASection(document, this.data); } diff --git a/src/CharacterData.ts b/src/CharacterData.ts index 40c3b59..7b2ea7c 100644 --- a/src/CharacterData.ts +++ b/src/CharacterData.ts @@ -13,11 +13,11 @@ import { asUnsignedLong, treatNullAsEmptyString } from './util/typeHelpers'; export default abstract class CharacterData extends Node implements NonDocumentTypeChildNode, ChildNode { // Node - public get nodeValue (): string | null { + public get nodeValue(): string | null { return this._data; } - public set nodeValue (newValue: string | null) { + public set nodeValue(newValue: string | null) { // if the new value is null, act as if it was the empty string instead if (newValue === null) { newValue = ''; @@ -39,11 +39,11 @@ export default abstract class CharacterData extends Node implements NonDocumentT */ protected _data: string; - public get data (): string { + public get data(): string { return this._data; } - public set data (newValue: string) { + public set data(newValue: string) { // [TreatNullAs=EmptyString] newValue = treatNullAsEmptyString(newValue); @@ -51,7 +51,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT replaceData(this, 0, this.length, newValue); } - public get length (): number { + public get length(): number { return this.data.length; } @@ -59,7 +59,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * @param document The node document to associate with the node * @param data The data to associate with the node */ - protected constructor (document: Document, data: string) { + protected constructor(document: Document, data: string) { super(document); this._data = data; } @@ -72,7 +72,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * * @return The specified substring */ - public substringData (offset: number, count: number): string { + public substringData(offset: number, count: number): string { expectArity(arguments, 2); return substringData(this, offset, count); } @@ -82,7 +82,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * * @param data Data to append */ - public appendData (data: string): void { + public appendData(data: string): void { expectArity(arguments, 1); replaceData(this, this.length, 0, data); } @@ -93,7 +93,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * @param offset Offset at which to insert * @param data Data to insert */ - public insertData (offset: number, data: string): void { + public insertData(offset: number, data: string): void { expectArity(arguments, 1); replaceData(this, offset, 0, data); } @@ -104,7 +104,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * @param offset Offset at which to delete * @param count Number of code units to delete */ - public deleteData (offset: number, count: number): void { + public deleteData(offset: number, count: number): void { expectArity(arguments, 2); replaceData(this, offset, count, ''); } @@ -116,7 +116,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * @param count Number of code units to remove * @param data Data to insert */ - public replaceData (offset: number, count: number, data: string): void { + public replaceData(offset: number, count: number, data: string): void { expectArity(arguments, 3); replaceData(this, offset, count, data); } @@ -130,7 +130,7 @@ export default abstract class CharacterData extends Node implements NonDocumentT * @param count The number of code units to replace * @param data The data to insert in place of the removed data */ -export function replaceData (node: CharacterData, offset: number, count: number, data: string): void { +export function replaceData(node: CharacterData, offset: number, count: number, data: string): void { // Match spec data types offset = asUnsignedLong(offset); count = asUnsignedLong(count); @@ -140,7 +140,7 @@ export function replaceData (node: CharacterData, offset: number, count: number, // 2. If offset is greater than length, then throw an IndexSizeError. if (offset > length) { - throwIndexSizeError('can not replace data past the node\'s length'); + throwIndexSizeError("can not replace data past the node's length"); } // 3. If offset plus count is greater than length, then set count to length minus offset. @@ -196,7 +196,7 @@ export function replaceData (node: CharacterData, offset: number, count: number, * * @return The requested substring */ -export function substringData (node: CharacterData, offset: number, count: number): string { +export function substringData(node: CharacterData, offset: number, count: number): string { // Match spec data types offset = asUnsignedLong(offset); count = asUnsignedLong(count); @@ -206,7 +206,7 @@ export function substringData (node: CharacterData, offset: number, count: numbe // 2. If offset is greater than length, then throw an IndexSizeError. if (offset > length) { - throwIndexSizeError('can not substring data past the node\'s length'); + throwIndexSizeError("can not substring data past the node's length"); } // 3. If offset plus count is greater than length, return a string whose value is the code units from the offsetth diff --git a/src/Comment.ts b/src/Comment.ts index fc2849b..f0522cc 100644 --- a/src/Comment.ts +++ b/src/Comment.ts @@ -5,11 +5,11 @@ import { NodeType } from './util/NodeType'; export default class Comment extends CharacterData { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.COMMENT_NODE; } - public get nodeName (): string { + public get nodeName(): string { return '#comment'; } @@ -24,7 +24,7 @@ export default class Comment extends CharacterData { * @param document (non-standard) The node document to associate with the new comment * @param data The data for the new comment */ - constructor (document: Document, data: string = '') { + constructor(document: Document, data: string = '') { super(document, data); } @@ -35,7 +35,7 @@ export default class Comment extends CharacterData { * * @return A shallow copy of the context object */ - public _copy (document: Document): Comment { + public _copy(document: Document): Comment { // Set copy’s data, to that of node. return new Comment(document, this.data); } diff --git a/src/DOMImplementation.ts b/src/DOMImplementation.ts index 8295e53..d863bb3 100644 --- a/src/DOMImplementation.ts +++ b/src/DOMImplementation.ts @@ -18,7 +18,7 @@ export default class DOMImplementation { * * @param document The document to associate with this instance */ - constructor (document: Document) { + constructor(document: Document) { this._document = document; } @@ -31,7 +31,7 @@ export default class DOMImplementation { * * @return The new doctype node */ - createDocumentType (qualifiedName: string, publicId: string, systemId: string): DocumentType { + createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType { // 1. Validate qualifiedName. validateQualifiedName(qualifiedName); @@ -50,7 +50,11 @@ export default class DOMImplementation { * * @return The new XMLDocument */ - createDocument (namespace: string | null, qualifiedName: string | null, doctype: DocumentType | null = null): XMLDocument { + createDocument( + namespace: string | null, + qualifiedName: string | null, + doctype: DocumentType | null = null + ): XMLDocument { expectArity(arguments, 2); namespace = asNullableString(namespace); // [TreatNullAs=EmptyString] for qualifiedName @@ -99,7 +103,7 @@ export default class DOMImplementation { * * @return The new document */ - createHTMLDocument (title?: string | null): Document { + createHTMLDocument(title?: string | null): Document { title = asNullableString(title); // 1. Let doc be a new document that is an HTML document. diff --git a/src/Document.ts b/src/Document.ts index b266e17..15a4456 100644 --- a/src/Document.ts +++ b/src/Document.ts @@ -25,25 +25,25 @@ import { asNullableString } from './util/typeHelpers'; export default class Document extends Node implements NonElementParentNode, ParentNode { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.DOCUMENT_NODE; } - public get nodeName (): string { + public get nodeName(): string { return '#document'; } - public get nodeValue (): string | null { + public get nodeValue(): string | null { return null; } - public set nodeValue (newValue: string | null) { + public set nodeValue(newValue: string | null) { // Do nothing. } // ParentNode - public get children (): Element[] { + public get children(): Element[] { return getChildren(this); } @@ -85,7 +85,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new element */ - public createElement (localName: string): Element { + public createElement(localName: string): Element { localName = String(localName); // 1. If localName does not match the Name production, then throw an InvalidCharacterError. @@ -123,7 +123,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new element */ - public createElementNS (namespace: string | null, qualifiedName: string): Element { + public createElementNS(namespace: string | null, qualifiedName: string): Element { namespace = asNullableString(namespace); qualifiedName = String(qualifiedName); @@ -137,7 +137,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new document fragment */ - public createDocumentFragment (): DocumentFragment { + public createDocumentFragment(): DocumentFragment { return new DocumentFragment(this); } @@ -148,7 +148,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new text node */ - public createTextNode (data: string): Text { + public createTextNode(data: string): Text { data = String(data); return new Text(this, data); @@ -161,7 +161,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new CDATA section */ - public createCDATASection (data: string): CDATASection { + public createCDATASection(data: string): CDATASection { data = String(data); // 1. If context object is an HTML document, then throw a NotSupportedError. @@ -183,7 +183,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new comment node */ - public createComment (data: string): Comment { + public createComment(data: string): Comment { data = String(data); return new Comment(this, data); @@ -197,7 +197,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new processing instruction */ - public createProcessingInstruction (target: string, data: string): ProcessingInstruction { + public createProcessingInstruction(target: string, data: string): ProcessingInstruction { target = String(target); data = String(data); @@ -225,7 +225,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * @param node The node to import * @param deep Whether to also import node's children */ - public importNode (node: Node, deep: boolean = false): Node { + public importNode(node: Node, deep: boolean = false): Node { // 1. If node is a document or shadow root, then throw a NotSupportedError. if (isNodeOfType(node, NodeType.DOCUMENT_NODE)) { throwNotSupportedError('importing a Document node is not supported'); @@ -241,7 +241,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @param node The node to adopt */ - public adoptNode (node: Node): Node { + public adoptNode(node: Node): Node { // 1. If node is a document, then throw a NotSupportedError. if (isNodeOfType(node, NodeType.DOCUMENT_NODE)) { throwNotSupportedError('adopting a Document node is not supported'); @@ -264,7 +264,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new attribute node */ - public createAttribute (localName: string): Attr { + public createAttribute(localName: string): Attr { localName = String(localName); // 1. If localName does not match the Name production in XML, then throw an InvalidCharacterError. @@ -287,7 +287,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new attribute node */ - public createAttributeNS (namespace: string | null, qualifiedName: string): Attr { + public createAttributeNS(namespace: string | null, qualifiedName: string): Attr { namespace = asNullableString(namespace); qualifiedName = String(qualifiedName); @@ -308,7 +308,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return The new Range */ - public createRange (): Range { + public createRange(): Range { return new Range(this); } @@ -319,7 +319,7 @@ export default class Document extends Node implements NonElementParentNode, Pare * * @return A shallow copy of the context object */ - public _copy (document: Document): Document { + public _copy(document: Document): Document { // Set copy’s encoding, content type, URL, origin, type, and mode, to those of node. // (properties not implemented) diff --git a/src/DocumentFragment.ts b/src/DocumentFragment.ts index dbe6f06..a74d380 100644 --- a/src/DocumentFragment.ts +++ b/src/DocumentFragment.ts @@ -7,26 +7,25 @@ import { NodeType } from './util/NodeType'; export default class DocumentFragment extends Node implements NonElementParentNode, ParentNode { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.DOCUMENT_FRAGMENT_NODE; } - public get nodeName (): string { + public get nodeName(): string { return '#document-fragment'; } - public get nodeValue (): string | null { + public get nodeValue(): string | null { return null; } - public set nodeValue (newValue: string | null) { + public set nodeValue(newValue: string | null) { // Do nothing. } - // ParentNode - public get children (): Element[] { + public get children(): Element[] { return getChildren(this); } @@ -42,7 +41,7 @@ export default class DocumentFragment extends Node implements NonElementParentNo * * @param document (non-standard) The node document to associate with the new document fragment */ - constructor (document: Document) { + constructor(document: Document) { super(document); } @@ -53,7 +52,7 @@ export default class DocumentFragment extends Node implements NonElementParentNo * * @return A shallow copy of the context object */ - public _copy (document: Document): DocumentFragment { + public _copy(document: Document): DocumentFragment { return new DocumentFragment(document); } } diff --git a/src/DocumentType.ts b/src/DocumentType.ts index c5b31e6..b5be0cf 100644 --- a/src/DocumentType.ts +++ b/src/DocumentType.ts @@ -6,19 +6,19 @@ import { NodeType } from './util/NodeType'; export default class DocumentType extends Node implements ChildNode { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.DOCUMENT_TYPE_NODE; } - public get nodeName (): string { + public get nodeName(): string { return this.name; } - public get nodeValue (): string | null { + public get nodeValue(): string | null { return null; } - public set nodeValue (newValue: string | null) { + public set nodeValue(newValue: string | null) { // Do nothing. } @@ -46,8 +46,11 @@ export default class DocumentType extends Node implements ChildNode { * @param publicId The public ID of the doctype * @param systemId The system ID of the doctype */ - constructor (document: Document, name: string, publicId: string = '', systemId: string = '') { + constructor(document: Document, name: string, publicId: string = '', systemId: string = '') { super(document); + if (name == 'bla') { + name = 'blup'; + } this.name = name; this.publicId = publicId; @@ -61,7 +64,7 @@ export default class DocumentType extends Node implements ChildNode { * * @return A shallow copy of the context object */ - public _copy (document: Document): DocumentType { + public _copy(document: Document): DocumentType { // Set copy’s name, public ID, and system ID, to those of node. return new DocumentType(document, this.name, this.publicId, this.systemId); } diff --git a/src/Element.ts b/src/Element.ts index 6fc4701..5031098 100644 --- a/src/Element.ts +++ b/src/Element.ts @@ -16,25 +16,25 @@ import { asNullableString } from './util/typeHelpers'; export default class Element extends Node implements ParentNode, NonDocumentTypeChildNode, ChildNode { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.ELEMENT_NODE; } - public get nodeName (): string { + public get nodeName(): string { return this.tagName; } - public get nodeValue (): string | null { + public get nodeValue(): string | null { return null; } - public set nodeValue (newValue: string | null) { + public set nodeValue(newValue: string | null) { // Do nothing. } // ParentNode - public get children (): Element[] { + public get children(): Element[] { return getChildren(this); } @@ -44,11 +44,11 @@ export default class Element extends Node implements ParentNode, NonDocumentType // NonDocumentTypeChildNode - public get previousElementSibling (): Element | null { + public get previousElementSibling(): Element | null { return getPreviousElementSibling(this); } - public get nextElementSibling (): Element | null { + public get nextElementSibling(): Element | null { return getNextElementSibling(this); } @@ -67,7 +67,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * @param prefix Prefix for the element * @param localName Local name for the element */ - constructor (document: Document, namespace: string | null, prefix: string | null, localName: string) { + constructor(document: Document, namespace: string | null, prefix: string | null, localName: string) { super(document); this.namespaceURI = namespace; this.prefix = prefix; @@ -80,7 +80,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return True if the element has attributes, otherwise false */ - public hasAttributes (): boolean { + public hasAttributes(): boolean { return this.attributes.length > 0; } @@ -98,7 +98,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The value of the attribute, or null if no such attribute exists */ - public getAttribute (qualifiedName: string): string | null { + public getAttribute(qualifiedName: string): string | null { // 1. Let attr be the result of getting an attribute given qualifiedName and the context object. const attr = getAttributeByName(qualifiedName, this); @@ -119,7 +119,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The value of the attribute, or null if no such attribute exists */ - public getAttributeNS (namespace: string | null, localName: string): string | null { + public getAttributeNS(namespace: string | null, localName: string): string | null { namespace = asNullableString(namespace); // 1. Let attr be the result of getting an attribute given namespace, localName, and the context object. @@ -140,7 +140,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * @param qualifiedName The qualified name of the attribute * @param value The new value for the attribute */ - public setAttribute (qualifiedName: string, value: string): void { + public setAttribute(qualifiedName: string, value: string): void { // 1. If qualifiedName does not match the Name production in XML, then throw an InvalidCharacterError. if (!matchesNameProduction(qualifiedName)) { throwInvalidCharacterError('The qualified name does not match the Name production'); @@ -173,7 +173,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * @param qualifiedName The qualified name of the attribute * @param value The value for the attribute */ - public setAttributeNS (namespace: string | null, qualifiedName: string, value: string): void { + public setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void { namespace = asNullableString(namespace); // 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and @@ -189,7 +189,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @param qualifiedName The qualified name of the attribute */ - public removeAttribute (qualifiedName: string): void { + public removeAttribute(qualifiedName: string): void { removeAttributeByName(qualifiedName, this); } @@ -199,7 +199,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * @param namespace The namespace of the attribute * @param localName The local name of the attribute */ - public removeAttributeNS (namespace: string | null, localName: string): void { + public removeAttributeNS(namespace: string | null, localName: string): void { namespace = asNullableString(namespace); removeAttributeByNamespaceAndLocalName(namespace, localName, this); @@ -210,7 +210,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @param qualifiedName The qualified name of the attribute */ - public hasAttribute (qualifiedName: string): boolean { + public hasAttribute(qualifiedName: string): boolean { // 1. If the context object is in the HTML namespace and its node document is an HTML document, then set // qualifiedName to qualifiedName in ASCII lowercase. // (html documents not implemented) @@ -226,7 +226,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * @param namespace The namespace of the attribute * @param localName The local name of the attribute */ - public hasAttributeNS (namespace: string | null, localName: string): boolean { + public hasAttributeNS(namespace: string | null, localName: string): boolean { namespace = asNullableString(namespace); // 1. If namespace is the empty string, set it to null. @@ -243,7 +243,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The attribute, or null if no such attribute exists */ - public getAttributeNode (qualifiedName: string): Attr | null { + public getAttributeNode(qualifiedName: string): Attr | null { return getAttributeByName(qualifiedName, this); } @@ -255,7 +255,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The attribute, or null if no such attribute exists */ - public getAttributeNodeNS (namespace: string | null, localName: string): Attr | null { + public getAttributeNodeNS(namespace: string | null, localName: string): Attr | null { namespace = asNullableString(namespace); return getAttributeByNamespaceAndLocalName(namespace, localName, this); @@ -268,7 +268,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The previous attribute node for the attribute */ - public setAttributeNode (attr: Attr): Attr | null { + public setAttributeNode(attr: Attr): Attr | null { return setAttribute(attr, this); } @@ -279,7 +279,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The previous attribute node for the attribute */ - public setAttributeNodeNS (attr: Attr): Attr | null { + public setAttributeNodeNS(attr: Attr): Attr | null { return setAttribute(attr, this); } @@ -290,10 +290,10 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The removed attribute node */ - public removeAttributeNode (attr: Attr): Attr { + public removeAttributeNode(attr: Attr): Attr { // 1. If context object’s attribute list does not contain attr, then throw a NotFoundError. if (this.attributes.indexOf(attr) < 0) { - throwNotFoundError('the specified attribute does not exist') + throwNotFoundError('the specified attribute does not exist'); } // 2. Remove attr from context object. @@ -311,7 +311,7 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return A shallow copy of the node */ - public _copy (document: Document): Element { + public _copy(document: Document): Element { // 2.1. Let copy be the result of creating an element, given document, node’s local name, node’s namespace, // node’s namespace prefix, and the value of node’s is attribute if present (or null if not). The synchronous // custom elements flag should be unset. @@ -341,7 +341,12 @@ export default class Element extends Node implements ParentNode, NonDocumentType * * @return The new element */ -export function createElement (document: Document, localName: string, namespace: string | null, prefix: string | null = null): Element { +export function createElement( + document: Document, + localName: string, + namespace: string | null, + prefix: string | null = null +): Element { // 1. If prefix was not given, let prefix be null. // (handled by default) @@ -423,7 +428,7 @@ export function createElement (document: Document, localName: string, namespace: * * @return The first matching attribute, or null otherwise */ -function getAttributeByName (qualifiedName: string, element: Element): Attr | null { +function getAttributeByName(qualifiedName: string, element: Element): Attr | null { // 1. If element is in the HTML namespace and its node document is an HTML document, then set qualifiedName to // qualifiedName in ASCII lowercase. // (html documents not implemented) @@ -442,7 +447,11 @@ function getAttributeByName (qualifiedName: string, element: Element): Attr | nu * * @return The first matching attribute, or null otherwise */ -function getAttributeByNamespaceAndLocalName (namespace: string | null, localName: string, element: Element): Attr | null { +function getAttributeByNamespaceAndLocalName( + namespace: string | null, + localName: string, + element: Element +): Attr | null { // 1. If namespace is the empty string, set it to null. if (namespace === '') { namespace = null; @@ -463,7 +472,7 @@ function getAttributeByNamespaceAndLocalName (namespace: string | null, localNam * * @return The value of the first matching attribute, or the empty string if no such attribute exists */ -function getAttributeValue (element: Element, localName: string, namespace: string | null = null): string { +function getAttributeValue(element: Element, localName: string, namespace: string | null = null): string { // 1. Let attr be the result of getting an attribute given namespace, localName, and element. const attr = getAttributeByNamespaceAndLocalName(namespace, localName, element); @@ -484,7 +493,7 @@ function getAttributeValue (element: Element, localName: string, namespace: stri * * @return The previous attribute with attr's namespace and local name, or null if there was no such attribute */ -function setAttribute (attr: Attr, element: Element): Attr | null { +function setAttribute(attr: Attr, element: Element): Attr | null { // 1. If attr’s element is neither null nor element, throw an InUseAttributeError. if (attr.ownerElement !== null && attr.ownerElement !== element) { throwInUseAttributeError('attribute is in use by another element'); @@ -501,9 +510,8 @@ function setAttribute (attr: Attr, element: Element): Attr | null { // 4. If oldAttr is non-null, replace it by attr in element. if (oldAttr !== null) { replaceAttribute(oldAttr, attr, element); - } - // 5. Otherwise, append attr to element. - else { + } else { + // 5. Otherwise, append attr to element. appendAttribute(attr, element); } @@ -521,7 +529,13 @@ function setAttribute (attr: Attr, element: Element): Attr | null { * @param prefix Prefix of the attribute * @param namespace Namespace of the attribute */ -function setAttributeValue (element: Element, localName: string, value: string, prefix: string | null = null, namespace: string | null = null): void { +function setAttributeValue( + element: Element, + localName: string, + value: string, + prefix: string | null = null, + namespace: string | null = null +): void { // 1. If prefix is not given, set it to null. // 2. If namespace is not given, set it to null. // (handled by default values) @@ -550,7 +564,7 @@ function setAttributeValue (element: Element, localName: string, value: string, * * @return The removed attribute, or null if no matching attribute exists */ -function removeAttributeByName (qualifiedName: string, element: Element): Attr | null { +function removeAttributeByName(qualifiedName: string, element: Element): Attr | null { // 1. Let attr be the result of getting an attribute given qualifiedName and element. const attr = getAttributeByName(qualifiedName, element); @@ -573,7 +587,11 @@ function removeAttributeByName (qualifiedName: string, element: Element): Attr | * * @return The removed attribute, or null if no matching attribute exists */ -function removeAttributeByNamespaceAndLocalName (namespace: string | null, localName: string, element: Element): Attr | null { +function removeAttributeByNamespaceAndLocalName( + namespace: string | null, + localName: string, + element: Element +): Attr | null { // 1. Let attr be the result of getting an attribute given namespace, localName, and element. const attr = getAttributeByNamespaceAndLocalName(namespace, localName, element); diff --git a/src/Node.ts b/src/Node.ts index cffe5d7..ffb0af4 100644 --- a/src/Node.ts +++ b/src/Node.ts @@ -30,12 +30,12 @@ export default abstract class Node { /** * Returns the type of node, represented by a number. */ - public abstract get nodeType (): number; + public abstract get nodeType(): number; /** * Returns a string appropriate for the type of node. */ - public abstract get nodeName (): string; + public abstract get nodeName(): string; /** * A reference to the Document node in which the current node resides. @@ -50,14 +50,14 @@ export default abstract class Node { /** * The parent if it is an element, or null otherwise. */ - public get parentElement (): Element | null { + public get parentElement(): Element | null { return this.parentNode && isNodeOfType(this.parentNode, NodeType.ELEMENT_NODE) ? this.parentNode as Element : null; } /** * Returns true if the context object has children, and false otherwise. */ - public hasChildNodes (): boolean { + public hasChildNodes(): boolean { return !!this.childNodes.length; } @@ -91,8 +91,8 @@ export default abstract class Node { /** * The value of the node. */ - public abstract get nodeValue (): string | null; - public abstract set nodeValue (value: string | null); + public abstract get nodeValue(): string | null; + public abstract set nodeValue(value: string | null); /** * (non-standard) Each node has an associated list of registered observers. @@ -104,7 +104,7 @@ export default abstract class Node { * * @param document The node document to associate with the node */ - constructor (document: Document | null) { + constructor(document: Document | null) { this.ownerDocument = document; } @@ -112,7 +112,7 @@ export default abstract class Node { * Puts the specified node and all of its subtree into a "normalized" form. In a normalized subtree, no text nodes * in the subtree are empty and there are no adjacent text nodes. */ - public normalize (): void { + public normalize(): void { // for each descendant exclusive Text node node of context object: let node = this.firstChild; let index = 0; @@ -142,7 +142,8 @@ export default abstract class Node { // itself), in tree order. let data = ''; const siblingsToRemove = []; - for (let sibling = textNode.nextSibling; + for ( + let sibling = textNode.nextSibling; sibling && isNodeOfType(sibling, NodeType.TEXT_NODE); sibling = sibling.nextSibling ) { @@ -216,7 +217,7 @@ export default abstract class Node { * * @return A copy of the current node */ - public cloneNode (deep: boolean = false): Node { + public cloneNode(deep: boolean = false): Node { return cloneNode(this, deep); } @@ -228,7 +229,7 @@ export default abstract class Node { * * @return Whether childNode is an inclusive descendant of the current node */ - public contains (other: Node | null): boolean { + public contains(other: Node | null): boolean { while (other && other != this) { other = other.parentNode; } @@ -245,7 +246,7 @@ export default abstract class Node { * * @return The node that was inserted */ - public insertBefore (node: Node, child: Node | null): Node { + public insertBefore(node: Node, child: Node | null): Node { expectArity(arguments, 2); node = asObject(node, Node); child = asNullableObject(child, Node); @@ -262,7 +263,7 @@ export default abstract class Node { * * @return The node that was inserted */ - public appendChild (node: Node): Node { + public appendChild(node: Node): Node { expectArity(arguments, 1); node = asObject(node, Node); @@ -277,7 +278,7 @@ export default abstract class Node { * * @return The node that was removed */ - public replaceChild (node: Node, child: Node): Node { + public replaceChild(node: Node, child: Node): Node { expectArity(arguments, 2); node = asObject(node, Node); child = asObject(child, Node); @@ -292,7 +293,7 @@ export default abstract class Node { * * @return The node that was removed */ - public removeChild (child: Node): Node { + public removeChild(child: Node): Node { expectArity(arguments, 1); child = asObject(child, Node); @@ -306,7 +307,7 @@ export default abstract class Node { * * @return A shallow copy of the context object */ - public abstract _copy (document: Document): Node; + public abstract _copy(document: Document): Node; } (Node.prototype as any).ELEMENT_NODE = NodeType.ELEMENT_NODE; diff --git a/src/ProcessingInstruction.ts b/src/ProcessingInstruction.ts index bcbd4b7..c7b80a1 100644 --- a/src/ProcessingInstruction.ts +++ b/src/ProcessingInstruction.ts @@ -8,11 +8,11 @@ import { NodeType } from './util/NodeType'; export default class ProcessingInstruction extends CharacterData { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.PROCESSING_INSTRUCTION_NODE; } - public get nodeName (): string { + public get nodeName(): string { return this.target; } @@ -26,7 +26,7 @@ export default class ProcessingInstruction extends CharacterData { * @param document The node document to associate with the processing instruction * @param target The target of the processing instruction */ - constructor (document: Document, target: string, data: string) { + constructor(document: Document, target: string, data: string) { super(document, data); this.target = target; } @@ -38,7 +38,7 @@ export default class ProcessingInstruction extends CharacterData { * * @return A shallow copy of the context object */ - public _copy (document: Document): ProcessingInstruction { + public _copy(document: Document): ProcessingInstruction { // Set copy’s target and data to those of node. return new ProcessingInstruction(document, this.target, this.data); } diff --git a/src/Range.ts b/src/Range.ts index 3ee8590..72925ee 100644 --- a/src/Range.ts +++ b/src/Range.ts @@ -1,8 +1,19 @@ import Document from './Document'; import Node from './Node'; -import { throwIndexSizeError, throwInvalidNodeTypeError, throwNotSupportedError, throwWrongDocumentError } from './util/errorHelpers'; +import { + throwIndexSizeError, + throwInvalidNodeTypeError, + throwNotSupportedError, + throwWrongDocumentError +} from './util/errorHelpers'; import { NodeType, isNodeOfType } from './util/NodeType'; -import { determineLengthOfNode, getInclusiveAncestors, getNodeDocument, getNodeIndex, getRootOfNode } from './util/treeHelpers'; +import { + determineLengthOfNode, + getInclusiveAncestors, + getNodeDocument, + getNodeIndex, + getRootOfNode +} from './util/treeHelpers'; import { asObject, asUnsignedLong } from './util/typeHelpers'; export const ranges: Range[] = []; @@ -16,7 +27,7 @@ export default class Range { public endContainer: Node; public endOffset: number; - public get collapsed (): boolean { + public get collapsed(): boolean { return this.startContainer === this.endContainer && this.startOffset === this.endOffset; } @@ -25,7 +36,7 @@ export default class Range { * * Note: for efficiency reasons, this implementation deviates from the algorithm given in 4.2. */ - public get commonAncestorContainer (): Node { + public get commonAncestorContainer(): Node { const ancestors1 = getInclusiveAncestors(this.startContainer); const ancestors2 = getInclusiveAncestors(this.endContainer); let commonAncestorContainer = ancestors1[0]; @@ -50,7 +61,7 @@ export default class Range { * * @param document The document in which to initialize the Range */ - constructor (document: Document) { + constructor(document: Document) { this.startContainer = document; this.startOffset = 0; this.endContainer = document; @@ -64,7 +75,7 @@ export default class Range { * @param node The new start container * @param offset The new start offset */ - setStart (node: Node, offset: number): void { + setStart(node: Node, offset: number): void { node = asObject(node, Node); offset = asUnsignedLong(offset); @@ -107,7 +118,7 @@ export default class Range { * @param node The new end container * @param offset The new end offset */ - setEnd (node: Node, offset: number): void { + setEnd(node: Node, offset: number): void { node = asObject(node, Node); offset = asUnsignedLong(offset); @@ -149,7 +160,7 @@ export default class Range { * * @param node The node to set the range's start before */ - setStartBefore (node: Node): void { + setStartBefore(node: Node): void { node = asObject(node, Node); // 1. Let parent be node’s parent. @@ -169,7 +180,7 @@ export default class Range { * * @param node The node to set the range's start before */ - setStartAfter (node: Node): void { + setStartAfter(node: Node): void { node = asObject(node, Node); // 1. Let parent be node’s parent. @@ -189,7 +200,7 @@ export default class Range { * * @param node The node to set the range's end before */ - setEndBefore (node: Node): void { + setEndBefore(node: Node): void { node = asObject(node, Node); // 1. Let parent be node’s parent. @@ -204,13 +215,12 @@ export default class Range { this.setEnd(parent, getNodeIndex(node)); } - /** * Sets the end boundary point of the range to the position just after the given node. * * @param node The node to set the range's end before */ - setEndAfter (node: Node): void { + setEndAfter(node: Node): void { node = asObject(node, Node); // 1. Let parent be node’s parent. @@ -225,24 +235,22 @@ export default class Range { this.setEnd(parent, getNodeIndex(node) + 1); } - /** * Sets the range's boundary points to the same position. * * @param toStart If true, set both points to the start of the range, otherwise set them to the end */ - collapse (toStart: boolean = false): void { + collapse(toStart: boolean = false): void { if (toStart) { this.endContainer = this.startContainer; this.endOffset = this.startOffset; - } - else { + } else { this.startContainer = this.endContainer; this.startOffset = this.endOffset; } } - selectNode (node: Node): void { + selectNode(node: Node): void { node = asObject(node, Node); // 1. Let parent be node’s parent. @@ -265,7 +273,7 @@ export default class Range { this.endOffset = index + 1; } - selectNodeContents (node: Node): void { + selectNodeContents(node: Node): void { node = asObject(node, Node); // 1. If node is a doctype, throw an InvalidNodeTypeError. @@ -290,7 +298,7 @@ export default class Range { static END_TO_END = 2; static END_TO_START = 3; - compareBoundaryPoints (how: number, sourceRange: Range): number { + compareBoundaryPoints(how: number, sourceRange: Range): number { sourceRange = asObject(sourceRange, Range); // 1. If how is not one of START_TO_START, START_TO_END, END_TO_END, and END_TO_START, then throw a @@ -349,7 +357,7 @@ export default class Range { // END_TO_START: default: - // unreachable, fall through for type check + // unreachable, fall through for type check case Range.END_TO_START: // Let this point be the context object’s start. Let other point be sourceRange’s end. return compareBoundaryPointPositions( @@ -374,7 +382,7 @@ export default class Range { * * @return A copy of the context object */ - cloneRange (): Range { + cloneRange(): Range { const range = new Range(getNodeDocument(this.startContainer)); range.startContainer = this.startContainer; range.startOffset = this.startOffset; @@ -390,7 +398,7 @@ export default class Range { * garbage collection to determine when to stop updating a range for node mutations, this implementation requires * calling detach to stop such updates from affecting the range. */ - detach (): void { + detach(): void { const index = ranges.indexOf(this); if (index >= 0) { ranges.splice(index, 1); @@ -406,7 +414,7 @@ export default class Range { * * @return Whether the point is in the range */ - isPointInRange (node: Node, offset: number): boolean { + isPointInRange(node: Node, offset: number): boolean { node = asObject(node, Node); offset = asUnsignedLong(offset); @@ -445,7 +453,7 @@ export default class Range { * * @return -1, 0 or 1 depending on whether the point is before, inside or after the range, respectively */ - comparePoint (node: Node, offset: number): number { + comparePoint(node: Node, offset: number): number { node = asObject(node, Node); offset = asUnsignedLong(offset); @@ -485,7 +493,7 @@ export default class Range { * * @return Whether the range intersects node */ - intersectsNode (node: Node): boolean { + intersectsNode(node: Node): boolean { node = asObject(node, Node); // 1. If node’s root is different from the context object’s root, return false. @@ -506,8 +514,10 @@ export default class Range { // 5. If (parent, offset) is before end and (parent, offset + 1) is after start, return true. // 6. Return false. - return compareBoundaryPointPositions(parent, offset, this.endContainer, this.endOffset) === POSITION_BEFORE && - compareBoundaryPointPositions(parent, offset + 1, this.startContainer, this.startOffset) === POSITION_AFTER; + return ( + compareBoundaryPointPositions(parent, offset, this.endContainer, this.endOffset) === POSITION_BEFORE && + compareBoundaryPointPositions(parent, offset + 1, this.startContainer, this.startOffset) === POSITION_AFTER + ); } } @@ -528,13 +538,13 @@ const POSITION_AFTER = 1; * * @return -1, 0 or 1, depending on the boundary points' relative positions */ -function compareBoundaryPointPositions (nodeA: Node, offsetA: number, nodeB: Node, offsetB: number): number { +function compareBoundaryPointPositions(nodeA: Node, offsetA: number, nodeB: Node, offsetB: number): number { if (nodeA !== nodeB) { const ancestors1 = getInclusiveAncestors(nodeA); const ancestors2 = getInclusiveAncestors(nodeB); // This should not be called on nodes from different trees if (ancestors1[0] !== ancestors2[0]) { - throw new Error('Can not compare positions of nodes from different trees.') + throw new Error('Can not compare positions of nodes from different trees.'); } // Skip common parents @@ -567,6 +577,6 @@ function compareBoundaryPointPositions (nodeA: Node, offsetA: number, nodeB: Nod * * @return The root of range */ -function getRootOfRange (range: Range): Node { +function getRootOfRange(range: Range): Node { return getRootOfNode(range.startContainer); } diff --git a/src/Text.ts b/src/Text.ts index ad9f2db..1099413 100644 --- a/src/Text.ts +++ b/src/Text.ts @@ -12,11 +12,11 @@ import { getNodeIndex } from './util/treeHelpers'; export default class Text extends CharacterData { // Node - public get nodeType (): number { + public get nodeType(): number { return NodeType.TEXT_NODE; } - public get nodeName (): string { + public get nodeName(): string { return '#text'; } @@ -31,7 +31,7 @@ export default class Text extends CharacterData { * @param document (non-standard) The node document for the new node * @param data The data for the new text node */ - constructor (document: Document, data: string = '') { + constructor(document: Document, data: string = '') { super(document, data); } @@ -42,7 +42,7 @@ export default class Text extends CharacterData { * * @return a text node containing the second half of the split node's data */ - public splitText (offset: number): Text { + public splitText(offset: number): Text { return splitText(this, offset); } @@ -53,7 +53,7 @@ export default class Text extends CharacterData { * * @return A shallow copy of the context object */ - public _copy (document: Document): Text { + public _copy(document: Document): Text { // Set copy’s data, to that of node. return new Text(document, this.data); } @@ -67,13 +67,13 @@ export default class Text extends CharacterData { * * @return a text node containing the second half of the split node's data */ -function splitText (node: Text, offset: number): Text { +function splitText(node: Text, offset: number): Text { // 1. Let length be node’s length. const length = node.length; // 2. If offset is greater than length, then throw an IndexSizeError. if (offset > length) { - throwIndexSizeError('can not split past the node\'s length'); + throwIndexSizeError("can not split past the node's length"); } // 3. Let count be length minus offset. @@ -120,7 +120,7 @@ function splitText (node: Text, offset: number): Text { if (range.endContainer === parent && range.endOffset === indexOfNodePlusOne) { range.endOffset += 1; } - }) + }); } // 8. Replace data with node node, offset offset, count count, and data the empty string. diff --git a/src/XMLDocument.ts b/src/XMLDocument.ts index 058af97..d7e5962 100644 --- a/src/XMLDocument.ts +++ b/src/XMLDocument.ts @@ -8,7 +8,7 @@ export default class XMLDocument extends Document { * * @return A shallow copy of the context object */ - public _copy (document: Document): XMLDocument { + public _copy(document: Document): XMLDocument { // Set copy’s encoding, content type, URL, origin, type, and mode, to those of node. // (properties not implemented) diff --git a/src/index.ts b/src/index.ts index 3950cef..40df935 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,6 +15,6 @@ export { default as Text } from './Text'; export { default as XMLDocument } from './XMLDocument'; export { default as MutationObserver } from './mutation-observer/MutationObserver'; -export function createDocument (): XMLDocument { +export function createDocument(): XMLDocument { return new XMLDocument(); } diff --git a/src/mixins.ts b/src/mixins.ts index 563bc45..95d3935 100644 --- a/src/mixins.ts +++ b/src/mixins.ts @@ -9,8 +9,7 @@ import { NodeType, isNodeOfType } from './util/NodeType'; /** * 3.2.4. Mixin NonElementParentNode */ -export interface NonElementParentNode { -} +export interface NonElementParentNode {} // Document implements NonElementParentNode; // DocumentFragment implements NonElementParentNode; @@ -28,7 +27,7 @@ export interface ParentNode { // DocumentFragment implements ParentNode; // Element implements ParentNode; -export function asParentNode (node: Node): ParentNode | null { +export function asParentNode(node: Node): ParentNode | null { if (isNodeOfType(node, NodeType.ELEMENT_NODE, NodeType.DOCUMENT_NODE, NodeType.DOCUMENT_FRAGMENT_NODE)) { return node as Element | Document | DocumentFragment; } @@ -46,7 +45,7 @@ export function asParentNode (node: Node): ParentNode | null { * * @return The */ -export function getChildren (node: ParentNode): Element[] { +export function getChildren(node: ParentNode): Element[] { const elements: Element[] = []; for (let child = node.firstElementChild; child; child = child.nextElementSibling) { elements.push(child); @@ -64,22 +63,24 @@ export interface NonDocumentTypeChildNode { // Element implements NonDocumentTypeChildNode; // CharacterData implements NonDocumentTypeChildNode; -export function asNonDocumentTypeChildNode (node: Node): NonDocumentTypeChildNode | null { - if (isNodeOfType( - node, - NodeType.ELEMENT_NODE, - NodeType.COMMENT_NODE, - NodeType.PROCESSING_INSTRUCTION_NODE, - NodeType.TEXT_NODE, - NodeType.CDATA_SECTION_NODE - )) { +export function asNonDocumentTypeChildNode(node: Node): NonDocumentTypeChildNode | null { + if ( + isNodeOfType( + node, + NodeType.ELEMENT_NODE, + NodeType.COMMENT_NODE, + NodeType.PROCESSING_INSTRUCTION_NODE, + NodeType.TEXT_NODE, + NodeType.CDATA_SECTION_NODE + ) + ) { return node as Element | CharacterData; } return null; } -export function getPreviousElementSibling (node: Node): Element | null { +export function getPreviousElementSibling(node: Node): Element | null { for (let sibling = node.previousSibling; sibling; sibling = sibling.previousSibling) { if (isNodeOfType(sibling, NodeType.ELEMENT_NODE)) { return sibling as Element; @@ -89,7 +90,7 @@ export function getPreviousElementSibling (node: Node): Element | null { return null; } -export function getNextElementSibling (node: Node): Element | null { +export function getNextElementSibling(node: Node): Element | null { for (let sibling = node.nextSibling; sibling; sibling = sibling.nextSibling) { if (isNodeOfType(sibling, NodeType.ELEMENT_NODE)) { return sibling as Element; @@ -102,8 +103,7 @@ export function getNextElementSibling (node: Node): Element | null { /** * 3.2.8. Mixin ChildNode */ -export interface ChildNode { -} +export interface ChildNode {} // DocumentType implements ChildNode; // Element implements ChildNode; // CharacterData implements ChildNode; diff --git a/src/mutation-observer/MutationObserver.ts b/src/mutation-observer/MutationObserver.ts index 809cf3d..88f97f0 100644 --- a/src/mutation-observer/MutationObserver.ts +++ b/src/mutation-observer/MutationObserver.ts @@ -78,7 +78,7 @@ export default class MutationObserver { * * @param callback Function called after mutations have been observed. */ - constructor (callback: MutationCallback) { + constructor(callback: MutationCallback) { // create a new MutationObserver object with callback set to callback this._callback = callback; @@ -99,7 +99,7 @@ export default class MutationObserver { * @param target Node (or root of subtree) to observe * @param options Determines which types of mutations to observe */ - observe (target: Node, options: MutationObserverInit) { + observe(target: Node, options: MutationObserverInit) { // Defaults from IDL options.childList = !!options.childList; options.subtree = !!options.subtree; @@ -136,7 +136,7 @@ export default class MutationObserver { if (options.characterDataOldValue && !options.characterData) { throw new TypeError( 'The options object may only set "characterDataOldValue" to true when "characterData" is true or not ' + - 'present.' + 'present.' ); } @@ -154,7 +154,7 @@ export default class MutationObserver { * Stops the MutationObserver instance from receiving notifications of DOM mutations. Until the observe() method * is used again, observer's callback will not be invoked. */ - disconnect () { + disconnect() { // for each node node in context object’s list of nodes, remove any registered observer on node for which // context object is the observer, this._nodes.forEach(node => node._registeredObservers.removeForObserver(this)); @@ -169,7 +169,7 @@ export default class MutationObserver { * * @return An Array of MutationRecord objects that were recorded. */ - takeRecords (): MutationRecord[] { + takeRecords(): MutationRecord[] { // return a copy of the record queue const recordQueue = this._recordQueue.concat(); // and then empty the record queue diff --git a/src/mutation-observer/MutationRecord.ts b/src/mutation-observer/MutationRecord.ts index e099757..b421263 100644 --- a/src/mutation-observer/MutationRecord.ts +++ b/src/mutation-observer/MutationRecord.ts @@ -1,13 +1,13 @@ import Node from '../Node'; export interface MutationRecordInit { - name?: string, - namespace?: string | null, - oldValue?: string | null, - addedNodes?: Node[], - removedNodes?: Node[], - previousSibling?: Node | null, - nextSibling?: Node | null + name?: string; + namespace?: string | null; + oldValue?: string | null; + addedNodes?: Node[]; + removedNodes?: Node[]; + previousSibling?: Node | null; + nextSibling?: Node | null; } /** @@ -75,7 +75,7 @@ export default class MutationRecord { * @param type The value for the type property * @param target The value for the target property */ - constructor (type: string, target: Node) { + constructor(type: string, target: Node) { this.type = type; this.target = target; } diff --git a/src/mutation-observer/NotifyList.ts b/src/mutation-observer/NotifyList.ts index fd5cbe4..aeebaf9 100644 --- a/src/mutation-observer/NotifyList.ts +++ b/src/mutation-observer/NotifyList.ts @@ -3,12 +3,12 @@ import MutationRecord from './MutationRecord'; import { removeTransientRegisteredObserversForObserver } from './RegisteredObservers'; // Declare functions without having to bring in the entire DOM lib -declare function setImmediate (handler: (...args: any[]) => void): number; -declare function setTimeout (handler: (...args: any[]) => void, timeout: number): number; +declare function setImmediate(handler: (...args: any[]) => void): number +declare function setTimeout(handler: (...args: any[]) => void, timeout: number): number -const hasSetImmediate = (typeof setImmediate === 'function'); +const hasSetImmediate = typeof setImmediate === 'function'; -function queueCompoundMicrotask (callback: (...args: any[]) => void, thisArg: NotifyList, ...args: any[]): number { +function queueCompoundMicrotask(callback: (...args: any[]) => void, thisArg: NotifyList, ...args: any[]): number { return (hasSetImmediate ? setImmediate : setTimeout)(() => { callback.apply(thisArg, args); }, 0); @@ -29,7 +29,7 @@ export default class NotifyList { * @param observer The observer for which to enqueue the record * @param record The record to enqueue */ - appendRecord (observer: MutationObserver, record: MutationRecord) { + appendRecord(observer: MutationObserver, record: MutationRecord) { observer._recordQueue.push(record); this._notifyList.push(observer); } @@ -37,7 +37,7 @@ export default class NotifyList { /** * To queue a mutation observer compound microtask, run these steps: */ - public queueMutationObserverCompoundMicrotask () { + public queueMutationObserverCompoundMicrotask() { // 1. If mutation observer compound microtask queued flag is set, then return. if (this._compoundMicrotaskQueued) { return; @@ -53,7 +53,7 @@ export default class NotifyList { /** * To notify mutation observers, run these steps: */ - private _notifyMutationObservers () { + private _notifyMutationObservers() { // 1. Unset mutation observer compound microtask queued flag. this._compoundMicrotaskQueued = null; @@ -70,21 +70,24 @@ export default class NotifyList { // 5. For each MutationObserver object mo in notify list, execute a compound microtask subtask to run these // steps: [HTML] notifyList.forEach(mo => { - queueCompoundMicrotask((mo: MutationObserver) => { - // 5.1. Let queue be a copy of mo’s record queue. - // 5.2. Empty mo’s record queue. - const queue = mo.takeRecords(); + queueCompoundMicrotask( + (mo: MutationObserver) => { + // 5.1. Let queue be a copy of mo’s record queue. + // 5.2. Empty mo’s record queue. + const queue = mo.takeRecords(); - // 5.3. Remove all transient registered observers whose observer is mo. - removeTransientRegisteredObserversForObserver(mo); + // 5.3. Remove all transient registered observers whose observer is mo. + removeTransientRegisteredObserversForObserver(mo); - // 5.4. If queue is non-empty, invoke mo’s callback with a list of arguments consisting of queue and mo, - // and mo as the callback this value. If this throws an exception, report the exception. - if (queue.length) { - mo._callback(queue, mo); - } - - }, this, mo); + // 5.4. If queue is non-empty, invoke mo’s callback with a list of arguments consisting of queue and mo, + // and mo as the callback this value. If this throws an exception, report the exception. + if (queue.length) { + mo._callback(queue, mo); + } + }, + this, + mo + ); }); // 6. For each slot slot in signalList, in order, fire an event named slotchange, with its bubbles diff --git a/src/mutation-observer/RegisteredObserver.ts b/src/mutation-observer/RegisteredObserver.ts index 1cac4b0..1c87216 100644 --- a/src/mutation-observer/RegisteredObserver.ts +++ b/src/mutation-observer/RegisteredObserver.ts @@ -37,7 +37,7 @@ export default class RegisteredObserver { * @param options Options for the registration * @param source If not null, creates a transient registered observer for the given registered observer */ - constructor (observer: MutationObserver, node: Node, options: MutationObserverInit, source?: RegisteredObserver) { + constructor(observer: MutationObserver, node: Node, options: MutationObserverInit, source?: RegisteredObserver) { this.observer = observer; this.node = node; this.options = options; @@ -58,7 +58,13 @@ export default class RegisteredObserver { * @param interestedObservers Array of mutation observer objects to append to * @param pairedStrings Paired strings for the mutation observer objects */ - public collectInterestedObservers (type: string, target: Node, data: MutationRecordInit, interestedObservers: MutationObserver[], pairedStrings: (string | null | undefined)[]) { + public collectInterestedObservers( + type: string, + target: Node, + data: MutationRecordInit, + interestedObservers: MutationObserver[], + pairedStrings: (string | null | undefined)[] + ) { // (continued from RegisteredObservers#queueMutationRecord) // 3.1. If none of the following are true diff --git a/src/mutation-observer/RegisteredObservers.ts b/src/mutation-observer/RegisteredObservers.ts index a67b41e..1cbf1b4 100644 --- a/src/mutation-observer/RegisteredObservers.ts +++ b/src/mutation-observer/RegisteredObservers.ts @@ -17,7 +17,7 @@ export default class RegisteredObservers { /** * @param node Node for which this instance holds RegisteredObserver instances. */ - constructor (node: Node) { + constructor(node: Node) { this._node = node; } @@ -27,7 +27,7 @@ export default class RegisteredObservers { * @param observer Observer to create a registration for * @param options Options for the registration */ - public register (observer: MutationObserver, options: MutationObserverInit) { + public register(observer: MutationObserver, options: MutationObserverInit) { // (continuing from MutationObserver#observe) // 7. For each registered observer registered in target’s list of registered observers whose observer is the // context object: @@ -66,7 +66,7 @@ export default class RegisteredObservers { * * @param registeredObserver The registered observer to remove */ - public remove (registeredObserver: RegisteredObserver): void { + public remove(registeredObserver: RegisteredObserver): void { const index = this._registeredObservers.indexOf(registeredObserver); if (index >= 0) { this._registeredObservers.splice(index, 1); @@ -81,7 +81,7 @@ export default class RegisteredObservers { * * @param observer Observer for which to remove the registration */ - public removeForObserver (observer: MutationObserver): void { + public removeForObserver(observer: MutationObserver): void { // Filter the array in-place let write = 0; for (let read = 0, l = this._registeredObservers.length; read < l; ++read) { @@ -107,18 +107,18 @@ export default class RegisteredObservers { * @param interestedObservers Array of mutation observer objects to append to * @param pairedStrings Paired strings for the mutation observer objects */ - public collectInterestedObservers (type: string, target: Node, data: MutationRecordInit, interestedObservers: MutationObserver[], pairedStrings: (string | null | undefined)[]) { + public collectInterestedObservers( + type: string, + target: Node, + data: MutationRecordInit, + interestedObservers: MutationObserver[], + pairedStrings: (string | null | undefined)[] + ) { // (continuing from queueMutationRecord) // 3. ...and then for each registered observer (with registered observer’s options as options) in node’s list of // registered observers: this._registeredObservers.forEach(registeredObserver => { - registeredObserver.collectInterestedObservers( - type, - target, - data, - interestedObservers, - pairedStrings - ); + registeredObserver.collectInterestedObservers(type, target, data, interestedObservers, pairedStrings); }); } @@ -127,7 +127,7 @@ export default class RegisteredObservers { * * @param node Node to append the transient registered observers to */ - public appendTransientRegisteredObservers (node: Node): void { + public appendTransientRegisteredObservers(node: Node): void { this._registeredObservers.forEach(registeredObserver => { if (registeredObserver.options.subtree) { node._registeredObservers.registerTransient(registeredObserver); @@ -140,10 +140,8 @@ export default class RegisteredObservers { * * @param source The source registered observer */ - public registerTransient (source: RegisteredObserver): void { - this._registeredObservers.push( - new RegisteredObserver(source.observer, this._node, source.options, source) - ); + public registerTransient(source: RegisteredObserver): void { + this._registeredObservers.push(new RegisteredObserver(source.observer, this._node, source.options, source)); // Note that node is not added to the transient observer's observer's list of nodes. } } @@ -153,7 +151,7 @@ export default class RegisteredObservers { * * @param observer The mutation observer object to remove transient registered observers for */ -export function removeTransientRegisteredObserversForObserver (observer: MutationObserver): void { +export function removeTransientRegisteredObserversForObserver(observer: MutationObserver): void { observer._transients.forEach(transientRegisteredObserver => { transientRegisteredObserver.node._registeredObservers.remove(transientRegisteredObserver); }); @@ -165,7 +163,7 @@ export function removeTransientRegisteredObserversForObserver (observer: Mutatio * * @param source The registered observer to remove transient registered observers for */ -export function removeTransientRegisteredObserversForSource (source: RegisteredObserver): void { +export function removeTransientRegisteredObserversForSource(source: RegisteredObserver): void { for (let i = source.observer._transients.length - 1; i >= 0; --i) { const transientRegisteredObserver = source.observer._transients[i]; if (transientRegisteredObserver.source !== source) { diff --git a/src/mutation-observer/queueMutationRecord.ts b/src/mutation-observer/queueMutationRecord.ts index d67adbd..2cc5ebf 100644 --- a/src/mutation-observer/queueMutationRecord.ts +++ b/src/mutation-observer/queueMutationRecord.ts @@ -13,7 +13,7 @@ import Node from '../Node'; * @param target The target node * @param data The data for the mutation record */ -export default function queueMutationRecord (type: string, target: Node, data: MutationRecordInit) { +export default function queueMutationRecord(type: string, target: Node, data: MutationRecordInit) { // 1. Let interested observers be an initially empty set of MutationObserver objects optionally paired with a // string. const interestedObservers: MutationObserver[] = []; diff --git a/src/util/NodeType.ts b/src/util/NodeType.ts index b7a3c1f..0cc5c36 100644 --- a/src/util/NodeType.ts +++ b/src/util/NodeType.ts @@ -23,6 +23,6 @@ export const enum NodeType { * * @return Whether node.nodeType is one of the specified values */ -export function isNodeOfType (node: Node, ...types: NodeType[]): boolean { +export function isNodeOfType(node: Node, ...types: NodeType[]): boolean { return types.some(t => node.nodeType === t); } diff --git a/src/util/attrMutations.ts b/src/util/attrMutations.ts index 89ee502..aacb385 100644 --- a/src/util/attrMutations.ts +++ b/src/util/attrMutations.ts @@ -9,7 +9,7 @@ import queueMutationRecord from '../mutation-observer/queueMutationRecord'; * @param element The element that has the attribute * @param value The new value for the attribute */ -export function changeAttribute (attribute: Attr, element: Element, value: string): void { +export function changeAttribute(attribute: Attr, element: Element, value: string): void { // 1. Queue a mutation record of "attributes" for element with name attribute’s local name, namespace attribute’s // namespace, and oldValue attribute’s value. queueMutationRecord('attributes', element, { @@ -37,7 +37,7 @@ export function changeAttribute (attribute: Attr, element: Element, value: strin * @param attribute The attribute to append * @param element The element to append attribute to */ -export function appendAttribute (attribute: Attr, element: Element): void { +export function appendAttribute(attribute: Attr, element: Element): void { // 1. Queue a mutation record of "attributes" for element with name attribute’s local name, namespace attribute’s // namespace, and oldValue null. queueMutationRecord('attributes', element, { @@ -68,7 +68,7 @@ export function appendAttribute (attribute: Attr, element: Element): void { * @param attribute The attribute to remove * @param element The element to remove attribute from */ -export function removeAttribute (attribute: Attr, element: Element): void { +export function removeAttribute(attribute: Attr, element: Element): void { // 1. Queue a mutation record of "attributes" for element with name attribute’s local name, namespace attribute’s // namespace, and oldValue attribute’s value. queueMutationRecord('attributes', element, { @@ -100,7 +100,7 @@ export function removeAttribute (attribute: Attr, element: Element): void { * @param newAttr The attribute to replace oldAttr with * @param element The element on which to replace the attribute */ -export function replaceAttribute (oldAttr: Attr, newAttr: Attr, element: Element): void { +export function replaceAttribute(oldAttr: Attr, newAttr: Attr, element: Element): void { // 1. Queue a mutation record of "attributes" for element with name oldAttr’s local name, namespace oldAttr’s // namespace, and oldValue oldAttr’s value. queueMutationRecord('attributes', element, { diff --git a/src/util/cloneNode.ts b/src/util/cloneNode.ts index 706e4ac..5e45eb9 100644 --- a/src/util/cloneNode.ts +++ b/src/util/cloneNode.ts @@ -12,7 +12,7 @@ import { getNodeDocument } from './treeHelpers'; * @param cloneChildren Whether to also clone node's descendants * @param document The document used to create the copy */ -export default function cloneNode (node: Node, cloneChildren: boolean = false, document?: Document): Node { +export default function cloneNode(node: Node, cloneChildren: boolean = false, document?: Document): Node { // 1. If document is not given, let document be node’s node document. if (!document) { document = getNodeDocument(node); @@ -46,7 +46,7 @@ export default function cloneNode (node: Node, cloneChildren: boolean = false, d // specified and the clone children flag being set. if (cloneChildren) { for (let child = node.firstChild; child; child = child.nextSibling) { - copy.appendChild(cloneNode(child, true, document)) + copy.appendChild(cloneNode(child, true, document)); } } diff --git a/src/util/createElementNS.ts b/src/util/createElementNS.ts index 0020e18..c39ea96 100644 --- a/src/util/createElementNS.ts +++ b/src/util/createElementNS.ts @@ -13,7 +13,7 @@ import { validateAndExtract } from './namespaceHelpers'; * * @return The new element */ -export default function createElementNS (document: Document, namespace: string | null, qualifiedName: string): Element { +export default function createElementNS(document: Document, namespace: string | null, qualifiedName: string): Element { // 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and // extract. const { namespace: validatedNamespace, prefix, localName } = validateAndExtract(namespace, qualifiedName); diff --git a/src/util/errorHelpers.ts b/src/util/errorHelpers.ts index 1fb1174..290706a 100644 --- a/src/util/errorHelpers.ts +++ b/src/util/errorHelpers.ts @@ -1,55 +1,55 @@ -export function expectArity (args: IArguments, minArity: number): void { +export function expectArity(args: IArguments, minArity: number): void { // According to WebIDL overload resolution semantics, only a lower bound applies to the number of arguments provided if (args.length < minArity) { throw new TypeError(`Function should be called with at least ${minArity} arguments`); } } -export function expectObject (value: T, Constructor: any): void { +export function expectObject(value: T, Constructor: any): void { if (!(value instanceof Constructor)) { throw new TypeError(`Value should be an instance of ${Constructor.name}`); } } -function createDOMException (name: string, code: number, message: string): Error { +function createDOMException(name: string, code: number, message: string): Error { const err = new Error(`${name}: ${message}`); err.name = name; (err as any).code = code; return err; } -export function throwHierarchyRequestError (message: string): never { +export function throwHierarchyRequestError(message: string): never { throw createDOMException('HierarchyRequestError', 3, message); } -export function throwIndexSizeError (message: string): never { +export function throwIndexSizeError(message: string): never { throw createDOMException('IndexSizeError', 1, message); } -export function throwInUseAttributeError (message: string): never { +export function throwInUseAttributeError(message: string): never { throw createDOMException('InUseAttributeError', 10, message); } -export function throwInvalidCharacterError (message: string): never { +export function throwInvalidCharacterError(message: string): never { throw createDOMException('InvalidCharacterError', 5, message); } -export function throwInvalidNodeTypeError (message: string): never { +export function throwInvalidNodeTypeError(message: string): never { throw createDOMException('InvalidNodeTypeError', 24, message); } -export function throwNamespaceError (message: string): never { +export function throwNamespaceError(message: string): never { throw createDOMException('NamespaceError', 14, message); } -export function throwNotFoundError (message: string): never { +export function throwNotFoundError(message: string): never { throw createDOMException('NotFoundError', 8, message); } -export function throwNotSupportedError (message: string): never { +export function throwNotSupportedError(message: string): never { throw createDOMException('NotSupportedError', 9, message); } -export function throwWrongDocumentError (message: string): never { +export function throwWrongDocumentError(message: string): never { throw createDOMException('WrongDocumentError', 4, message); } diff --git a/src/util/mutationAlgorithms.ts b/src/util/mutationAlgorithms.ts index 9da20da..9cfea19 100644 --- a/src/util/mutationAlgorithms.ts +++ b/src/util/mutationAlgorithms.ts @@ -14,7 +14,7 @@ import queueMutationRecord from '../mutation-observer/queueMutationRecord'; /** * To ensure pre-insertion validity of a node into a parent before a child, run these steps: */ -function ensurePreInsertionValidity (node: Node, parent: Node, child: Node | null): void { +function ensurePreInsertionValidity(node: Node, parent: Node, child: Node | null): void { // 1. If parent is not a Document, DocumentFragment, or Element node, throw a HierarchyRequestError. if (!isNodeOfType(parent, NodeType.DOCUMENT_NODE, NodeType.DOCUMENT_FRAGMENT_NODE, NodeType.ELEMENT_NODE)) { throwHierarchyRequestError('parent must be a Document, DocumentFragment or Element node'); @@ -32,15 +32,17 @@ function ensurePreInsertionValidity (node: Node, parent: Node, child: Node | nul // 4. If node is not a DocumentFragment, DocumentType, Element, Text, ProcessingInstruction, or Comment node, throw // a HierarchyRequestError. - if (!isNodeOfType( - node, - NodeType.DOCUMENT_FRAGMENT_NODE, - NodeType.DOCUMENT_TYPE_NODE, - NodeType.ELEMENT_NODE, - NodeType.TEXT_NODE, - NodeType.PROCESSING_INSTRUCTION_NODE, - NodeType.COMMENT_NODE - )) { + if ( + !isNodeOfType( + node, + NodeType.DOCUMENT_FRAGMENT_NODE, + NodeType.DOCUMENT_TYPE_NODE, + NodeType.ELEMENT_NODE, + NodeType.TEXT_NODE, + NodeType.PROCESSING_INSTRUCTION_NODE, + NodeType.COMMENT_NODE + ) + ) { throwHierarchyRequestError( 'node must be a DocumentFragment, DocumentType, Element, Text, ProcessingInstruction or Comment node' ); @@ -74,15 +76,11 @@ function ensurePreInsertionValidity (node: Node, parent: Node, child: Node | nul // or child is not null and a doctype is following child. if ( fragment.firstElementChild && - ( - parentDocument.documentElement || + (parentDocument.documentElement || (child && isNodeOfType(child, NodeType.DOCUMENT_TYPE_NODE)) || - (child && parentDocument.doctype && getNodeIndex(child) < getNodeIndex(parentDocument.doctype)) - ) + (child && parentDocument.doctype && getNodeIndex(child) < getNodeIndex(parentDocument.doctype))) ) { - throwHierarchyRequestError( - 'Document should contain at most one doctype, followed by at most one element' - ); + throwHierarchyRequestError('Document should contain at most one doctype, followed by at most one element'); } break; @@ -95,9 +93,7 @@ function ensurePreInsertionValidity (node: Node, parent: Node, child: Node | nul (child && isNodeOfType(child, NodeType.DOCUMENT_TYPE_NODE)) || (child && parentDocument.doctype && getNodeIndex(child) < getNodeIndex(parentDocument.doctype)) ) { - throwHierarchyRequestError( - 'Document should contain at most one doctype, followed by at most one element' - ); + throwHierarchyRequestError('Document should contain at most one doctype, followed by at most one element'); } break; @@ -107,16 +103,12 @@ function ensurePreInsertionValidity (node: Node, parent: Node, child: Node | nul // parent has an element child. if ( parentDocument.doctype || - ( - child && + (child && parentDocument.documentElement && - getNodeIndex(parentDocument.documentElement) < getNodeIndex(child) - ) || + getNodeIndex(parentDocument.documentElement) < getNodeIndex(child)) || (!child && parentDocument.documentElement) ) { - throwHierarchyRequestError( - 'Document should contain at most one doctype, followed by at most one element' - ); + throwHierarchyRequestError('Document should contain at most one doctype, followed by at most one element'); } break; } @@ -132,7 +124,7 @@ function ensurePreInsertionValidity (node: Node, parent: Node, child: Node | nul * * @return The inserted node */ -export function preInsertNode (node: Node, parent: Node, child: Node | null): Node { +export function preInsertNode(node: Node, parent: Node, child: Node | null): Node { // 1. Ensure pre-insertion validity of node into parent before child. ensurePreInsertionValidity(node, parent, child); @@ -162,7 +154,7 @@ export function preInsertNode (node: Node, parent: Node, child: Node | null): No * @param child Child to insert before, or null to insert at end of parent * @param suppressObservers Whether to skip enqueueing a mutation record for this mutation */ -export function insertNode (node: Node, parent: Node, child: Node | null, suppressObservers: boolean = false): void { +export function insertNode(node: Node, parent: Node, child: Node | null, suppressObservers: boolean = false): void { // 1. Let count be the number of children of node if it is a DocumentFragment node, and one otherwise. const isDocumentFragment = isNodeOfType(node, NodeType.DOCUMENT_FRAGMENT_NODE); const count = isDocumentFragment ? determineLengthOfNode(node) : 1; @@ -208,7 +200,7 @@ export function insertNode (node: Node, parent: Node, child: Node | null, suppre nodes.forEach(node => { // 6.1. If child is null, then append node to parent’s children. // 6.2. Otherwise, insert node into parent’s children before child’s index. - insertIntoChildren(node, parent, child) + insertIntoChildren(node, parent, child); // 6.3. If parent is a shadow host and node is a slotable, then assign a slot for node. // 6.4. If parent is a slot whose assigned nodes is the empty list, then run signal a slot change for parent. @@ -251,7 +243,7 @@ export function insertNode (node: Node, parent: Node, child: Node | null, suppre * * @return The appended node */ -export function appendNode (node: Node, parent: Node): Node { +export function appendNode(node: Node, parent: Node): Node { // pre-insert node into parent before null. return preInsertNode(node, parent, null); } @@ -265,7 +257,7 @@ export function appendNode (node: Node, parent: Node): Node { * * @return The old child node */ -export function replaceChildWithNode (child: Node, node: Node, parent: Node): Node { +export function replaceChildWithNode(child: Node, node: Node, parent: Node): Node { // 1. If parent is not a Document, DocumentFragment, or Element node, throw a HierarchyRequestError. if (!isNodeOfType(parent, NodeType.DOCUMENT_NODE, NodeType.DOCUMENT_FRAGMENT_NODE, NodeType.ELEMENT_NODE)) { throwHierarchyRequestError('Can not replace under a non-parent node'); @@ -283,18 +275,20 @@ export function replaceChildWithNode (child: Node, node: Node, parent: Node): No // 4. If node is not a DocumentFragment, DocumentType, Element, Text, ProcessingInstruction, or Comment node, throw // a HierarchyRequestError. - if (!isNodeOfType( - node, - NodeType.DOCUMENT_FRAGMENT_NODE, - NodeType.DOCUMENT_TYPE_NODE, - NodeType.ELEMENT_NODE, - NodeType.TEXT_NODE, - NodeType.PROCESSING_INSTRUCTION_NODE, - NodeType.COMMENT_NODE - )) { + if ( + !isNodeOfType( + node, + NodeType.DOCUMENT_FRAGMENT_NODE, + NodeType.DOCUMENT_TYPE_NODE, + NodeType.ELEMENT_NODE, + NodeType.TEXT_NODE, + NodeType.PROCESSING_INSTRUCTION_NODE, + NodeType.COMMENT_NODE + ) + ) { throwHierarchyRequestError( - 'Can not insert a node that isn\'t a DocumentFragment, DocumentType, Element, Text, ' + - 'ProcessingInstruction or Comment' + "Can not insert a node that isn't a DocumentFragment, DocumentType, Element, Text, " + + 'ProcessingInstruction or Comment' ); } @@ -326,14 +320,10 @@ export function replaceChildWithNode (child: Node, node: Node, parent: Node): No // a doctype is following child. if ( fragment.firstElementChild && - ( - (parentDocument.documentElement && parentDocument.documentElement !== child) || - (child && parentDocument.doctype && getNodeIndex(child) < getNodeIndex(parentDocument.doctype)) - ) + ((parentDocument.documentElement && parentDocument.documentElement !== child) || + (child && parentDocument.doctype && getNodeIndex(child) < getNodeIndex(parentDocument.doctype))) ) { - throwHierarchyRequestError( - 'Document should contain at most one doctype, followed by at most one element' - ); + throwHierarchyRequestError('Document should contain at most one doctype, followed by at most one element'); } break; @@ -344,9 +334,7 @@ export function replaceChildWithNode (child: Node, node: Node, parent: Node): No (parentDocument.documentElement && parentDocument.documentElement !== child) || (parentDocument.doctype && getNodeIndex(child) < getNodeIndex(parentDocument.doctype)) ) { - throwHierarchyRequestError( - 'Document should contain at most one doctype, followed by at most one element' - ); + throwHierarchyRequestError('Document should contain at most one doctype, followed by at most one element'); } break; @@ -355,14 +343,9 @@ export function replaceChildWithNode (child: Node, node: Node, parent: Node): No // parent has a doctype child that is not child, or an element is preceding child. if ( (parentDocument.doctype && parentDocument.doctype !== child) || - ( - parentDocument.documentElement && - getNodeIndex(parentDocument.documentElement) < getNodeIndex(child) - ) + (parentDocument.documentElement && getNodeIndex(parentDocument.documentElement) < getNodeIndex(child)) ) { - throwHierarchyRequestError( - 'Document should contain at most one doctype, followed by at most one element' - ); + throwHierarchyRequestError('Document should contain at most one doctype, followed by at most one element'); } break; } @@ -423,7 +406,7 @@ export function replaceChildWithNode (child: Node, node: Node, parent: Node): No * * @return The removed child */ -export function preRemoveChild (child: Node, parent: Node): Node { +export function preRemoveChild(child: Node, parent: Node): Node { // 1. If child’s parent is not parent, then throw a NotFoundError. if (child.parentNode !== parent) { throwNotFoundError('child is not a child of parent'); @@ -443,7 +426,7 @@ export function preRemoveChild (child: Node, parent: Node): Node { * @param parent Parent to remove child from * @param suppressObservers Whether to skip enqueueing a mutation record for this mutation */ -export function removeNode (node: Node, parent: Node, suppressObservers: boolean = false): void { +export function removeNode(node: Node, parent: Node, suppressObservers: boolean = false): void { // 1. Let index be node’s index. const index = getNodeIndex(node); @@ -471,7 +454,7 @@ export function removeNode (node: Node, parent: Node, suppressObservers: boolean if (range.endContainer === parent && range.endOffset > index) { range.endOffset -= 1; } - }) + }); // 6. For each NodeIterator object iterator whose root’s node document is node’s node document, run the NodeIterator // pre-removing steps given node and iterator. @@ -546,7 +529,7 @@ export function removeNode (node: Node, parent: Node, suppressObservers: boolean * @param node Node to adopt * @param document Document to adopt node into */ -export function adoptNode (node: Node, document: Document): void { +export function adoptNode(node: Node, document: Document): void { // 1. Let oldDocument be node’s node document. const oldDocument = getNodeDocument(node); @@ -573,7 +556,7 @@ export function adoptNode (node: Node, document: Document): void { attr.ownerDocument = document; } } - }) + }); // 3.2. For each inclusiveDescendant in node’s shadow-including inclusive descendants that is custom, enqueue a // custom element callback reaction with inclusiveDescendant, callback name "adoptedCallback", and an argument list diff --git a/src/util/namespaceHelpers.ts b/src/util/namespaceHelpers.ts index be3aa13..62db877 100644 --- a/src/util/namespaceHelpers.ts +++ b/src/util/namespaceHelpers.ts @@ -74,7 +74,7 @@ const NameChar = NameStartChar.clone() return `^(?:${NameStartChar.toString()})(?:${NameChar.toString()})*$`; */ -const NAME_REGEX_XML_1_0_FIFTH_EDITION = /^(?:[:A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])(?:[\-\.0-:A-Z_a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])*$/ +const NAME_REGEX_XML_1_0_FIFTH_EDITION = /^(?:[:A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])(?:[\-\.0-:A-Z_a-z\xB7\xC0-\xD6\xD8-\xF6\xF8-\u037D\u037F-\u1FFF\u200C\u200D\u203F\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDB7F][\uDC00-\uDFFF])*$/; /** * Returns true if name matches the Name production. @@ -83,7 +83,7 @@ const NAME_REGEX_XML_1_0_FIFTH_EDITION = /^(?:[:A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u * * @return true if name matches Name, otherwise false */ -export function matchesNameProduction (name: string): boolean { +export function matchesNameProduction(name: string): boolean { return NAME_REGEX_XML_1_0_FOURTH_EDITION.test(name); } @@ -95,7 +95,7 @@ export function matchesNameProduction (name: string): boolean { * * @return True if the name is a valid QName, provided it is also a valid Name, otherwise false */ -function isValidQName (name: string): boolean { +function isValidQName(name: string): boolean { const parts = name.split(':'); if (parts.length > 2) { return false; @@ -112,7 +112,7 @@ function isValidQName (name: string): boolean { * * @param qualifiedName Qualified name to validate */ -export function validateQualifiedName (qualifiedName: string): void { +export function validateQualifiedName(qualifiedName: string): void { // throw an InvalidCharacterError if qualifiedName does not match the Name or QName production. // (QName is basically (Name without ':') ':' (Name without ':'), so just check the position of the : if (!isValidQName(qualifiedName) || !matchesNameProduction(qualifiedName)) { @@ -128,7 +128,10 @@ export function validateQualifiedName (qualifiedName: string): void { * * @return Namespace, prefix and localName */ -export function validateAndExtract (namespace: string | null, qualifiedName: string): { namespace: string | null, prefix: string | null, localName: string } { +export function validateAndExtract( + namespace: string | null, + qualifiedName: string +): { namespace: string | null; prefix: string | null; localName: string } { // 1. If namespace is the empty string, set it to null. if (namespace === '') { namespace = null; diff --git a/src/util/treeHelpers.ts b/src/util/treeHelpers.ts index 9a67519..6f7b508 100644 --- a/src/util/treeHelpers.ts +++ b/src/util/treeHelpers.ts @@ -10,7 +10,7 @@ import { NodeType, isNodeOfType } from './NodeType'; * * @return The length of the node */ -export function determineLengthOfNode (node: Node): number { +export function determineLengthOfNode(node: Node): number { switch (node.nodeType) { // DocumentType: Zero. case NodeType.DOCUMENT_TYPE_NODE: @@ -35,7 +35,7 @@ export function determineLengthOfNode (node: Node): number { * * @return Node's inclusive ancestors, in tree order */ -export function getInclusiveAncestors (node: Node): Node[] { +export function getInclusiveAncestors(node: Node): Node[] { let ancestor: Node | null = node; let ancestors: Node[] = []; while (ancestor) { @@ -53,7 +53,7 @@ export function getInclusiveAncestors (node: Node): Node[] { * * @return The node document for node */ -export function getNodeDocument (node: Node): Document { +export function getNodeDocument(node: Node): Document { if (isNodeOfType(node, NodeType.DOCUMENT_NODE)) { return node as Document; } @@ -68,7 +68,7 @@ export function getNodeDocument (node: Node): Document { * * @return The index of node in its parent's children */ -export function getNodeIndex (node: Node): number { +export function getNodeIndex(node: Node): number { return (node.parentNode as Node).childNodes.indexOf(node); } @@ -79,7 +79,7 @@ export function getNodeIndex (node: Node): number { * * @return The root of node */ -export function getRootOfNode (node: Node): Node { +export function getRootOfNode(node: Node): Node { while (node.parentNode) { node = node.parentNode; } @@ -93,7 +93,7 @@ export function getRootOfNode (node: Node): Node { * @param node Root of the subtree to process * @param callback Callback to invoke for each descendant, should not modify node's position in the tree */ -export function forEachInclusiveDescendant (node: Node, callback: (node: Node) => void): void { +export function forEachInclusiveDescendant(node: Node, callback: (node: Node) => void): void { callback(node); for (let child = node.firstChild; child; child = child.nextSibling) { forEachInclusiveDescendant(child, callback); diff --git a/src/util/treeMutations.ts b/src/util/treeMutations.ts index ba4c556..65951be 100644 --- a/src/util/treeMutations.ts +++ b/src/util/treeMutations.ts @@ -15,7 +15,7 @@ import { NodeType, isNodeOfType } from './NodeType'; * @param parent Parent to insert under * @param referenceChild Child to insert before */ -export function insertIntoChildren (node: Node, parent: Node, referenceChild: Node | null): void { +export function insertIntoChildren(node: Node, parent: Node, referenceChild: Node | null): void { // Node node.parentNode = parent; const previousSibling: Node | null = referenceChild === null ? parent.lastChild : referenceChild.previousSibling; @@ -24,15 +24,13 @@ export function insertIntoChildren (node: Node, parent: Node, referenceChild: No node.nextSibling = nextSibling; if (previousSibling) { previousSibling.nextSibling = node; - } - else { + } else { parent.firstChild = node; } if (nextSibling) { nextSibling.previousSibling = node; parent.childNodes.splice(parent.childNodes.indexOf(nextSibling), 0, node); - } - else { + } else { parent.lastChild = node; parent.childNodes.push(node); } @@ -83,8 +81,7 @@ export function insertIntoChildren (node: Node, parent: Node, referenceChild: No const parentDocument = parent as Document; if (isNodeOfType(node, NodeType.ELEMENT_NODE)) { parentDocument.documentElement = node as Element; - } - else if (isNodeOfType(node, NodeType.DOCUMENT_TYPE_NODE)) { + } else if (isNodeOfType(node, NodeType.DOCUMENT_TYPE_NODE)) { parentDocument.doctype = node as DocumentType; } } @@ -98,7 +95,7 @@ export function insertIntoChildren (node: Node, parent: Node, referenceChild: No * @param node Node to remove * @param parent Parent to remove from */ -export function removeFromChildren (node: Node, parent: Node) { +export function removeFromChildren(node: Node, parent: Node) { const previousSibling = node.previousSibling; const nextSibling = node.nextSibling; const isElement = isNodeOfType(node, NodeType.ELEMENT_NODE); @@ -111,14 +108,12 @@ export function removeFromChildren (node: Node, parent: Node) { node.nextSibling = null; if (previousSibling) { previousSibling.nextSibling = nextSibling; - } - else { + } else { parent.firstChild = nextSibling; } if (nextSibling) { nextSibling.previousSibling = previousSibling; - } - else { + } else { parent.lastChild = previousSibling; } parent.childNodes.splice(parent.childNodes.indexOf(node), 1); @@ -142,8 +137,7 @@ export function removeFromChildren (node: Node, parent: Node) { const parentDocument = parent as Document; if (isNodeOfType(node, NodeType.ELEMENT_NODE)) { parentDocument.documentElement = null; - } - else if (isNodeOfType(node, NodeType.DOCUMENT_TYPE_NODE)) { + } else if (isNodeOfType(node, NodeType.DOCUMENT_TYPE_NODE)) { parentDocument.doctype = null; } } diff --git a/src/util/typeHelpers.ts b/src/util/typeHelpers.ts index 5ef0b91..603f26f 100644 --- a/src/util/typeHelpers.ts +++ b/src/util/typeHelpers.ts @@ -1,10 +1,10 @@ import { expectObject } from './errorHelpers'; -export function asUnsignedLong (number: number): number { +export function asUnsignedLong(number: number): number { return number >>> 0; } -export function treatNullAsEmptyString (value: string | null): string { +export function treatNullAsEmptyString(value: string | null): string { // Treat null as empty string if (value === null) { return ''; @@ -14,13 +14,13 @@ export function treatNullAsEmptyString (value: string | null): string { return String(value); } -export function asObject (value: T, Constructor: any): T { +export function asObject(value: T, Constructor: any): T { expectObject(value, Constructor); return value; } -export function asNullableObject (value: T | null | undefined, Constructor: any): T | null { +export function asNullableObject(value: T | null | undefined, Constructor: any): T | null { if (value === undefined || value === null) { return null; } @@ -28,7 +28,7 @@ export function asNullableObject (value: T | null | undefined, Constructor: a return asObject(value, Constructor); } -export function asNullableString (value: string | null | undefined): string | null { +export function asNullableString(value: string | null | undefined): string | null { // Treat undefined as null if (value === undefined) { return null; diff --git a/test/Document.tests.ts b/test/Document.tests.ts index badd20e..28652a6 100644 --- a/test/Document.tests.ts +++ b/test/Document.tests.ts @@ -33,7 +33,7 @@ describe('Document', () => { it('has a documentElement', () => chai.assert.equal(document.documentElement, element)); - it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [ element ])); + it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [element])); it('the child element is adopted into the document', () => chai.assert.equal(element.ownerDocument, document)); @@ -56,7 +56,7 @@ describe('Document', () => { it('has the other element as documentElement', () => chai.assert.equal(document.documentElement, otherElement)); - it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [ otherElement ])); + it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [otherElement])); }); }); @@ -69,7 +69,7 @@ describe('Document', () => { it('has no documentElement', () => chai.assert.equal(document.documentElement, null)); - it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [ processingInstruction ])); + it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [processingInstruction])); describe('after replacing with an element', () => { let otherElement: Element; @@ -80,7 +80,7 @@ describe('Document', () => { it('has the other element as documentElement', () => chai.assert.equal(document.documentElement, otherElement)); - it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [ otherElement ])); + it('has childNodes', () => chai.assert.deepEqual(document.childNodes, [otherElement])); }); }); diff --git a/test/Element.tests.ts b/test/Element.tests.ts index c7cfc59..5d01a7e 100644 --- a/test/Element.tests.ts +++ b/test/Element.tests.ts @@ -1,4 +1,4 @@ -import * as slimdom from '../src/index' +import * as slimdom from '../src/index'; import Attr from '../src/Attr'; import Document from '../src/Document'; @@ -61,27 +61,34 @@ describe('Element', () => { chai.assert.equal(element.getAttribute('noSuchAttribute'), null); }); - function hasAttributes (attributes: Attr[], expected: { name: string, value: string }[]): boolean { - return attributes.length === expected.length && + function hasAttributes(attributes: Attr[], expected: { name: string; value: string }[]): boolean { + return ( + attributes.length === expected.length && attributes.every(attr => expected.some(pair => pair.name === attr.name && pair.value === attr.value)) && - expected.every(pair => attributes.some(attr => attr.name === pair.name && attr.value === pair.value)); + expected.every(pair => attributes.some(attr => attr.name === pair.name && attr.value === pair.value)) + ); } - it('has attributes', () => chai.assert(hasAttributes(element.attributes, [ - {name: 'firstAttribute', value: 'first'}, - {name: 'test', value: '123'}, - {name: 'lastAttribute', value: 'last'} - ]))); + it('has attributes', () => + chai.assert( + hasAttributes(element.attributes, [ + { name: 'firstAttribute', value: 'first' }, + { name: 'test', value: '123' }, + { name: 'lastAttribute', value: 'last' } + ]) + )); it('can overwrite the attribute', () => { element.setAttribute('test', '456'); chai.assert(element.hasAttribute('test'), 'has the attribute'); chai.assert.equal(element.getAttribute('test'), '456'); - chai.assert(hasAttributes(element.attributes, [ - {name: 'firstAttribute', value: 'first'}, - {name: 'test', value: '456'}, - {name: 'lastAttribute', value: 'last'} - ])); + chai.assert( + hasAttributes(element.attributes, [ + { name: 'firstAttribute', value: 'first' }, + { name: 'test', value: '456' }, + { name: 'lastAttribute', value: 'last' } + ]) + ); }); it('can remove the attribute', () => { @@ -89,10 +96,12 @@ describe('Element', () => { chai.assert(element.hasAttribute('firstAttribute'), 'has attribute firstAttribute'); chai.assert(!element.hasAttribute('test'), 'does not have attribute test'); chai.assert(element.hasAttribute('lastAttribute'), 'has attribute lastAttribute'); - chai.assert(hasAttributes(element.attributes, [ - {name: 'firstAttribute', value: 'first'}, - {name: 'lastAttribute', value: 'last'} - ])); + chai.assert( + hasAttributes(element.attributes, [ + { name: 'firstAttribute', value: 'first' }, + { name: 'lastAttribute', value: 'last' } + ]) + ); }); it('ignores removing non-existent attributes', () => { @@ -100,11 +109,13 @@ describe('Element', () => { element.removeAttribute('other'); chai.assert(!element.hasAttribute('other'), 'does not have attribute other'); chai.assert(element.hasAttribute('test'), 'has attribute test'); - chai.assert(hasAttributes(element.attributes, [ - {name: 'firstAttribute', value: 'first'}, - {name: 'test', value: '123'}, - {name: 'lastAttribute', value: 'last'} - ])); + chai.assert( + hasAttributes(element.attributes, [ + { name: 'firstAttribute', value: 'first' }, + { name: 'test', value: '123' }, + { name: 'lastAttribute', value: 'last' } + ]) + ); }); }); @@ -124,7 +135,7 @@ describe('Element', () => { it('has child element references', () => { chai.assert.equal(element.firstElementChild, child); chai.assert.equal(element.lastElementChild, child); - chai.assert.deepEqual(element.children, [ child ]); + chai.assert.deepEqual(element.children, [child]); chai.assert.equal(element.childElementCount, 1); }); @@ -157,13 +168,13 @@ describe('Element', () => { it('has child node references', () => { chai.assert.equal(element.firstChild, otherChild); chai.assert.equal(element.lastChild, otherChild); - chai.assert.deepEqual(element.childNodes, [ otherChild ]); + chai.assert.deepEqual(element.childNodes, [otherChild]); }); it('has child element references', () => { chai.assert.equal(element.firstElementChild, otherChild); chai.assert.equal(element.lastElementChild, otherChild); - chai.assert.deepEqual(element.children, [ otherChild ]); + chai.assert.deepEqual(element.children, [otherChild]); chai.assert.equal(element.childElementCount, 1); }); }); @@ -178,13 +189,13 @@ describe('Element', () => { it('has child node references', () => { chai.assert.equal(element.firstChild, otherChild); chai.assert.equal(element.lastChild, child); - chai.assert.deepEqual(element.childNodes, [ otherChild, child ]); + chai.assert.deepEqual(element.childNodes, [otherChild, child]); }); it('has child element references', () => { chai.assert.equal(element.firstElementChild, otherChild); chai.assert.equal(element.lastElementChild, child); - chai.assert.deepEqual(element.children, [ otherChild, child ]); + chai.assert.deepEqual(element.children, [otherChild, child]); chai.assert.equal(element.childElementCount, 2); }); @@ -217,7 +228,7 @@ describe('Element', () => { it('has child element references', () => { chai.assert.equal(element.firstElementChild, child); chai.assert.equal(element.lastElementChild, otherChild); - chai.assert.deepEqual(element.children, [ child, otherChild ]); + chai.assert.deepEqual(element.children, [child, otherChild]); chai.assert.equal(element.childElementCount, 2); }); @@ -242,13 +253,13 @@ describe('Element', () => { it('has child node references', () => { chai.assert.equal(element.firstChild, child); chai.assert.equal(element.lastChild, child); - chai.assert.deepEqual(element.childNodes, [ child ]); + chai.assert.deepEqual(element.childNodes, [child]); }); it('has child element references', () => { chai.assert.equal(element.firstElementChild, child); chai.assert.equal(element.lastElementChild, child); - chai.assert.deepEqual(element.children, [ child ]); + chai.assert.deepEqual(element.children, [child]); chai.assert.equal(element.childElementCount, 1); }); @@ -271,7 +282,7 @@ describe('Element', () => { it('has child node references', () => { chai.assert.equal(element.firstChild, processingInstruction); chai.assert.equal(element.lastChild, processingInstruction); - chai.assert.deepEqual(element.childNodes, [ processingInstruction ]); + chai.assert.deepEqual(element.childNodes, [processingInstruction]); }); it('has no child elements', () => { @@ -291,13 +302,13 @@ describe('Element', () => { it('has child node references', () => { chai.assert.equal(element.firstChild, otherChild); chai.assert.equal(element.lastChild, otherChild); - chai.assert.deepEqual(element.childNodes, [ otherChild ]); + chai.assert.deepEqual(element.childNodes, [otherChild]); }); it('has child element references', () => { chai.assert.equal(element.firstElementChild, otherChild); chai.assert.equal(element.lastElementChild, otherChild); - chai.assert.deepEqual(element.children, [ otherChild ]); + chai.assert.deepEqual(element.children, [otherChild]); chai.assert.equal(element.childElementCount, 1); }); }); diff --git a/test/MutationObserver.tests.ts b/test/MutationObserver.tests.ts index 4611a0c..8503e2d 100644 --- a/test/MutationObserver.tests.ts +++ b/test/MutationObserver.tests.ts @@ -20,7 +20,7 @@ describe('MutationObserver', () => { let callbackCalled: boolean; let callbackArgs: any[] = []; - function callback (...args: any[]) { + function callback(...args: any[]) { callbackCalled = true; callbackArgs.push(args); } @@ -129,7 +129,7 @@ describe('MutationObserver', () => { const queue = observer.takeRecords(); chai.assert.equal(queue[0].type, 'childList'); - chai.assert.deepEqual(queue[0].addedNodes, [ newElement ]); + chai.assert.deepEqual(queue[0].addedNodes, [newElement]); chai.assert.deepEqual(queue[0].removedNodes, []); chai.assert.equal(queue[0].previousSibling, text); chai.assert.equal(queue[0].nextSibling, null); @@ -141,8 +141,8 @@ describe('MutationObserver', () => { const queue = observer.takeRecords(); chai.assert.equal(queue[0].type, 'childList'); - chai.assert.deepEqual(queue[0].addedNodes, [ newElement ]); - chai.assert.deepEqual(queue[0].removedNodes, [ text ]); + chai.assert.deepEqual(queue[0].addedNodes, [newElement]); + chai.assert.deepEqual(queue[0].removedNodes, [text]); chai.assert.equal(queue[0].previousSibling, null); chai.assert.equal(queue[0].nextSibling, null); }); @@ -157,12 +157,12 @@ describe('MutationObserver', () => { const queue = observer.takeRecords(); chai.assert.equal(queue[0].type, 'childList'); chai.assert.deepEqual(queue[0].addedNodes, []); - chai.assert.deepEqual(queue[0].removedNodes, [ newElement ]); + chai.assert.deepEqual(queue[0].removedNodes, [newElement]); chai.assert.equal(queue[0].previousSibling, text); chai.assert.equal(queue[0].nextSibling, null); chai.assert.equal(queue[1].type, 'childList'); - chai.assert.deepEqual(queue[1].addedNodes, [ newElement ]); + chai.assert.deepEqual(queue[1].addedNodes, [newElement]); chai.assert.deepEqual(queue[1].removedNodes, []); chai.assert.equal(queue[1].previousSibling, null); chai.assert.equal(queue[1].nextSibling, text); @@ -179,14 +179,14 @@ describe('MutationObserver', () => { chai.assert.equal(queue[0].type, 'childList'); chai.assert.equal(queue[0].target, element); chai.assert.deepEqual(queue[0].addedNodes, []); - chai.assert.deepEqual(queue[0].removedNodes, [ newElement ]); + chai.assert.deepEqual(queue[0].removedNodes, [newElement]); chai.assert.equal(queue[0].previousSibling, text); chai.assert.equal(queue[0].nextSibling, null); chai.assert.equal(queue[1].type, 'childList'); chai.assert.equal(queue[1].target, element); - chai.assert.deepEqual(queue[1].addedNodes, [ newElement ]); - chai.assert.deepEqual(queue[1].removedNodes, [ text ]); + chai.assert.deepEqual(queue[1].addedNodes, [newElement]); + chai.assert.deepEqual(queue[1].removedNodes, [text]); chai.assert.equal(queue[1].previousSibling, null); chai.assert.equal(queue[1].nextSibling, null); }); diff --git a/test/Range.tests.ts b/test/Range.tests.ts index 782a784..0dc5bcd 100644 --- a/test/Range.tests.ts +++ b/test/Range.tests.ts @@ -99,7 +99,6 @@ describe('Range', () => { }); describe('under mutations', () => { - describe('in element', () => { beforeEach(() => { range.setStart(element, 0); diff --git a/test/web-platform-tests/SlimdomTreeAdapter.ts b/test/web-platform-tests/SlimdomTreeAdapter.ts index d4ea932..236cb75 100644 --- a/test/web-platform-tests/SlimdomTreeAdapter.ts +++ b/test/web-platform-tests/SlimdomTreeAdapter.ts @@ -5,7 +5,7 @@ import Attr from '../../src/Attr'; import { createElement } from '../../src/Element'; import { appendAttribute } from '../../src/util/attrMutations'; -function undefinedAsNull (value: T | undefined): T | null { +function undefinedAsNull(value: T | undefined): T | null { if (value === undefined) { return null; } @@ -13,7 +13,7 @@ function undefinedAsNull (value: T | undefined): T | null { return value; } -function qualifiedName (namespace: string | undefined, prefix: string | undefined, name: string) { +function qualifiedName(namespace: string | undefined, prefix: string | undefined, name: string) { return prefix ? `${prefix}:${name}` : name; } @@ -21,73 +21,79 @@ export default class SlimdomTreeAdapter implements parse5.AST.TreeAdapter { private _globalDocument = new slimdom.Document(); private _mode: parse5.AST.DocumentMode = 'no-quirks'; - createDocument (): parse5.AST.Document { + createDocument(): parse5.AST.Document { return this._globalDocument.implementation.createDocument(null, ''); } - createDocumentFragment (): parse5.AST.DocumentFragment { - throw new Error("Method not implemented."); + createDocumentFragment(): parse5.AST.DocumentFragment { + throw new Error('Method not implemented.'); } - createElement (tagName: string, namespaceURI: string, attrs: parse5.AST.Default.Attribute[]): parse5.AST.Element { - const [ localName, prefix ] = tagName.indexOf(':') >= 0 ? tagName.split(':') : [ tagName, null ]; + createElement(tagName: string, namespaceURI: string, attrs: parse5.AST.Default.Attribute[]): parse5.AST.Element { + const [localName, prefix] = tagName.indexOf(':') >= 0 ? tagName.split(':') : [tagName, null]; // Create element without validation, as per HTML parser spec const element = createElement(this._globalDocument, localName!, namespaceURI, prefix); attrs.forEach(attr => { // Create Attr node without validation, as per HTML parser spec - const attribute = new Attr(this._globalDocument, undefinedAsNull(attr.namespace), undefinedAsNull(attr.prefix), attr.name, attr.value, element); + const attribute = new Attr( + this._globalDocument, + undefinedAsNull(attr.namespace), + undefinedAsNull(attr.prefix), + attr.name, + attr.value, + element + ); appendAttribute(attribute, element); }); return element; } - createCommentNode (data: string): parse5.AST.CommentNode { + createCommentNode(data: string): parse5.AST.CommentNode { return this._globalDocument.createComment(data); } - appendChild (parentNode: parse5.AST.ParentNode, newNode: parse5.AST.Node): void { + appendChild(parentNode: parse5.AST.ParentNode, newNode: parse5.AST.Node): void { (parentNode as slimdom.Node).appendChild(newNode as slimdom.Node); } - insertBefore (parentNode: parse5.AST.ParentNode, newNode: parse5.AST.Node, referenceNode: parse5.AST.Node): void { + insertBefore(parentNode: parse5.AST.ParentNode, newNode: parse5.AST.Node, referenceNode: parse5.AST.Node): void { (parentNode as slimdom.Node).insertBefore(newNode as slimdom.Node, referenceNode as slimdom.Node); } - setTemplateContent (templateElement: parse5.AST.Element, contentElement: parse5.AST.DocumentFragment): void { - throw new Error("Method not implemented."); + setTemplateContent(templateElement: parse5.AST.Element, contentElement: parse5.AST.DocumentFragment): void { + throw new Error('Method not implemented.'); } - getTemplateContent (templateElement: parse5.AST.Element): parse5.AST.DocumentFragment { - throw new Error("Method not implemented."); + getTemplateContent(templateElement: parse5.AST.Element): parse5.AST.DocumentFragment { + throw new Error('Method not implemented.'); } - setDocumentType (document: parse5.AST.Document, name: string, publicId: string, systemId: string): void { + setDocumentType(document: parse5.AST.Document, name: string, publicId: string, systemId: string): void { const doctype = this._globalDocument.implementation.createDocumentType(name, publicId, systemId); const doc = document as slimdom.Document; if (doc.doctype) { doc.replaceChild(doctype, doc.doctype); - } - else { + } else { doc.insertBefore(doctype, doc.documentElement); } } - setDocumentMode (document: parse5.AST.Document, mode: parse5.AST.DocumentMode): void { + setDocumentMode(document: parse5.AST.Document, mode: parse5.AST.DocumentMode): void { this._mode = mode; } - getDocumentMode (document: parse5.AST.Document): parse5.AST.DocumentMode { + getDocumentMode(document: parse5.AST.Document): parse5.AST.DocumentMode { return this._mode; } - detachNode (node: parse5.AST.Node): void { + detachNode(node: parse5.AST.Node): void { const parent = (node as slimdom.Node).parentNode; if (parent) { parent.removeChild(node as slimdom.Node); } } - insertText (parentNode: parse5.AST.ParentNode, text: string): void { + insertText(parentNode: parse5.AST.ParentNode, text: string): void { const lastChild = (parentNode as slimdom.Node).lastChild; if (lastChild && lastChild.nodeType === slimdom.Node.TEXT_NODE) { (lastChild as slimdom.Text).appendData(text); @@ -97,7 +103,7 @@ export default class SlimdomTreeAdapter implements parse5.AST.TreeAdapter { (parentNode as slimdom.Node).appendChild(this._globalDocument.createTextNode(text)); } - insertTextBefore (parentNode: parse5.AST.ParentNode, text: string, referenceNode: parse5.AST.Node): void { + insertTextBefore(parentNode: parse5.AST.ParentNode, text: string, referenceNode: parse5.AST.Node): void { const sibling = referenceNode && (referenceNode as slimdom.Node).previousSibling; if (sibling && sibling.nodeType === slimdom.Node.TEXT_NODE) { (sibling as slimdom.Text).appendData(text); @@ -107,28 +113,32 @@ export default class SlimdomTreeAdapter implements parse5.AST.TreeAdapter { (parentNode as slimdom.Node).insertBefore(this._globalDocument.createTextNode(text), referenceNode as slimdom.Node); } - adoptAttributes (recipient: parse5.AST.Element, attrs: parse5.AST.Default.Attribute[]): void { + adoptAttributes(recipient: parse5.AST.Element, attrs: parse5.AST.Default.Attribute[]): void { const element = recipient as slimdom.Element; attrs.forEach(attr => { if (!element.hasAttributeNS(undefinedAsNull(attr.namespace), attr.name)) { - element.setAttributeNS(undefinedAsNull(attr.namespace), qualifiedName(attr.namespace, attr.prefix, attr.name), attr.value); + element.setAttributeNS( + undefinedAsNull(attr.namespace), + qualifiedName(attr.namespace, attr.prefix, attr.name), + attr.value + ); } }); } - getFirstChild (node: parse5.AST.ParentNode): parse5.AST.Node { + getFirstChild(node: parse5.AST.ParentNode): parse5.AST.Node { return (node as slimdom.Node).firstChild!; } - getChildNodes (node: parse5.AST.ParentNode): parse5.AST.Node[] { + getChildNodes(node: parse5.AST.ParentNode): parse5.AST.Node[] { return (node as slimdom.Node).childNodes; } - getParentNode (node: parse5.AST.Node): parse5.AST.ParentNode { + getParentNode(node: parse5.AST.Node): parse5.AST.ParentNode { return (node as slimdom.Node).parentNode!; } - getAttrList (element: parse5.AST.Element): parse5.AST.Default.Attribute[] { + getAttrList(element: parse5.AST.Element): parse5.AST.Default.Attribute[] { return (element as slimdom.Element).attributes.map(attr => ({ name: attr.localName, namespace: attr.namespaceURI || undefined, @@ -137,47 +147,47 @@ export default class SlimdomTreeAdapter implements parse5.AST.TreeAdapter { })); } - getTagName (element: parse5.AST.Element): string { + getTagName(element: parse5.AST.Element): string { return (element as slimdom.Element).tagName; } - getNamespaceURI (element: parse5.AST.Element): string { + getNamespaceURI(element: parse5.AST.Element): string { return (element as slimdom.Element).namespaceURI!; } - getTextNodeContent (textNode: parse5.AST.TextNode): string { + getTextNodeContent(textNode: parse5.AST.TextNode): string { return (textNode as slimdom.Text).data; } - getCommentNodeContent (commentNode: parse5.AST.CommentNode): string { + getCommentNodeContent(commentNode: parse5.AST.CommentNode): string { return (commentNode as slimdom.Comment).data; } - getDocumentTypeNodeName (doctypeNode: parse5.AST.DocumentType): string { + getDocumentTypeNodeName(doctypeNode: parse5.AST.DocumentType): string { return (doctypeNode as slimdom.DocumentType).name; } - getDocumentTypeNodePublicId (doctypeNode: parse5.AST.DocumentType): string { + getDocumentTypeNodePublicId(doctypeNode: parse5.AST.DocumentType): string { return (doctypeNode as slimdom.DocumentType).publicId; } - getDocumentTypeNodeSystemId (doctypeNode: parse5.AST.DocumentType): string { + getDocumentTypeNodeSystemId(doctypeNode: parse5.AST.DocumentType): string { return (doctypeNode as slimdom.DocumentType).systemId; } - isTextNode (node: parse5.AST.Node): boolean { + isTextNode(node: parse5.AST.Node): boolean { return node && (node as slimdom.Node).nodeType === slimdom.Node.TEXT_NODE; } - isCommentNode (node: parse5.AST.Node): boolean { + isCommentNode(node: parse5.AST.Node): boolean { return node && (node as slimdom.Node).nodeType === slimdom.Node.COMMENT_NODE; } - isDocumentTypeNode (node: parse5.AST.Node): boolean { + isDocumentTypeNode(node: parse5.AST.Node): boolean { return node && (node as slimdom.Node).nodeType === slimdom.Node.DOCUMENT_TYPE_NODE; } - isElementNode (node: parse5.AST.Node): boolean { + isElementNode(node: parse5.AST.Node): boolean { return node && (node as slimdom.Node).nodeType === slimdom.Node.ELEMENT_NODE; } } diff --git a/test/web-platform-tests/webPlatform.tests.ts b/test/web-platform-tests/webPlatform.tests.ts index 2a1181d..fdaeb94 100644 --- a/test/web-platform-tests/webPlatform.tests.ts +++ b/test/web-platform-tests/webPlatform.tests.ts @@ -16,20 +16,31 @@ const TEST_BLACKLIST: { [key: string]: (string | { [key: string]: string }) } = 'dom/lists': 'DOMTokenList (Element#classList) not implemented', 'dom/nodes/append-on-Document.html': 'ParentNode#append not implemented', 'dom/nodes/attributes.html': { - 'setAttribute should lowercase its name argument (upper case attribute)': 'HTML attribute lowercasing not implemented', - 'setAttribute should lowercase its name argument (mixed case attribute)': 'HTML attribute lowercasing not implemented', + 'setAttribute should lowercase its name argument (upper case attribute)': + 'HTML attribute lowercasing not implemented', + 'setAttribute should lowercase its name argument (mixed case attribute)': + 'HTML attribute lowercasing not implemented', 'Attributes should work in document fragments.': 'Element#attributes not implemented as NamedNodeMap', - 'Only lowercase attributes are returned on HTML elements (upper case attribute)': 'HTML attribute lowercasing not implemented', - 'Only lowercase attributes are returned on HTML elements (mixed case attribute)': 'HTML attribute lowercasing not implemented', - 'setAttributeNode, if it fires mutation events, should fire one with the new node when resetting an existing attribute (outer shell)': 'Mutation events not implemented', + 'Only lowercase attributes are returned on HTML elements (upper case attribute)': + 'HTML attribute lowercasing not implemented', + 'Only lowercase attributes are returned on HTML elements (mixed case attribute)': + 'HTML attribute lowercasing not implemented', + 'setAttributeNode, if it fires mutation events, should fire one with the new node when resetting an existing attribute (outer shell)': + 'Mutation events not implemented', 'getAttributeNames tests': 'Element#getAttributeNames not implemented', 'Own property correctness with basic attributes': 'Element#attributes not implemented as NamedNodeMap', - 'Own property correctness with non-namespaced attribute before same-name namespaced one': 'Element#attributes not implemented as NamedNodeMap', - 'Own property correctness with namespaced attribute before same-name non-namespaced one': 'Element#attributes not implemented as NamedNodeMap', - 'Own property correctness with two namespaced attributes with the same name-with-prefix': 'Element#attributes not implemented as NamedNodeMap', - 'Own property names should only include all-lowercase qualified names for an HTML element in an HTML document': 'Element#attributes not implemented as NamedNodeMap', - 'Own property names should include all qualified names for a non-HTML element in an HTML document': 'Element#attributes not implemented as NamedNodeMap', - 'Own property names should include all qualified names for an HTML element in a non-HTML document': 'Element#attributes not implemented as NamedNodeMap', + 'Own property correctness with non-namespaced attribute before same-name namespaced one': + 'Element#attributes not implemented as NamedNodeMap', + 'Own property correctness with namespaced attribute before same-name non-namespaced one': + 'Element#attributes not implemented as NamedNodeMap', + 'Own property correctness with two namespaced attributes with the same name-with-prefix': + 'Element#attributes not implemented as NamedNodeMap', + 'Own property names should only include all-lowercase qualified names for an HTML element in an HTML document': + 'Element#attributes not implemented as NamedNodeMap', + 'Own property names should include all qualified names for a non-HTML element in an HTML document': + 'Element#attributes not implemented as NamedNodeMap', + 'Own property names should include all qualified names for an HTML element in a non-HTML document': + 'Element#attributes not implemented as NamedNodeMap' }, 'dom/nodes/case.html': 'HTML case behavior not implemented', 'dom/nodes/CharacterData-remove.html': 'ChildNode#remove not implemented', @@ -62,14 +73,16 @@ const TEST_BLACKLIST: { [key: string]: (string | { [key: string]: string }) } = 'createDocument test: metadata for "http://www.w3.org/2000/svg","",null': 'SVG contentType not implemented' }, 'dom/nodes/DOMImplementation-createDocumentType.html': 'DocumentType#ownerDocument not implemented per spec', - 'dom/nodes/DOMImplementation-createHTMLDocument.html': 'HTML*Element interfaces not implemented', + 'dom/nodes/DOMImplementation-createHTMLDocument.html': 'HTML*Element interfaces not implemented', 'dom/nodes/DOMImplementation-hasFeature.html': 'DOMImplementation#hasFeature not implemented', 'dom/nodes/Element-children.html': 'Element#children not implemented as HTMLCollection', 'dom/nodes/Element-classlist.html': 'Element#classList not implemented', 'dom/nodes/Element-closest.html': 'Element#closest not implemented', 'dom/nodes/Element-getElementsByClassName.html': 'Element#getElementsByClassName not implemented', - 'dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html': 'Element#getElementsByTagName not implemented', - 'dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.html': 'Element#getElementsByTagName not implemented', + 'dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html': + 'Element#getElementsByTagName not implemented', + 'dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.html': + 'Element#getElementsByTagName not implemented', 'dom/nodes/Element-getElementsByTagName.html': 'Element#getElementsByTagName not implemented', 'dom/nodes/Element-getElementsByTagNameNS.html': 'Element#getElementsByTagNameNS not implemented', 'dom/nodes/Element-insertAdjacentElement.html': 'Element#insertAdjacentElement not implemented', @@ -101,24 +114,28 @@ const TEST_BLACKLIST: { [key: string]: (string | { [key: string]: string }) } = 'attributes Element.classList.toggle: token removal mutation': 'Element#classList not implemented', 'attributes Element.classList.toggle: token addition mutation': 'Element#classList not implemented', 'attributes Element.classList.toggle: forced token removal mutation': 'Element#classList not implemented', - 'attributes Element.classList.toggle: forced missing token removal no mutation': 'Element#classList not implemented', - 'attributes Element.classList.toggle: forced existing token addition no mutation': 'Element#classList not implemented', + 'attributes Element.classList.toggle: forced missing token removal no mutation': + 'Element#classList not implemented', + 'attributes Element.classList.toggle: forced existing token addition no mutation': + 'Element#classList not implemented', 'attributes Element.classList.toggle: forced token addition mutation': 'Element#classList not implemented', 'attributes Element.removeAttribute: removal no mutation': 'Element#id not implemented', 'childList HTMLInputElement.removeAttribute: type removal mutation': 'Element#id not implemented', 'attributes Element.removeAttributeNS: removal no mutation': 'Element#id not implemented', 'attributes Element.removeAttributeNS: prefixed attribute removal no mutation': 'Element#id not implemented', 'attributes/attributeFilter Element.id/Element.className: update mutation': 'attributeFilter not implemented', - 'attributes/attributeFilter Element.id/Element.className: multiple filter update mutation': 'attributeFilter not implemented', + 'attributes/attributeFilter Element.id/Element.className: multiple filter update mutation': + 'attributeFilter not implemented', 'attributeOldValue alone Element.id: update mutation': 'Element#id not implemented', - 'attributeFilter alone Element.id/Element.className: multiple filter update mutation': 'attributeFilter not implemented', + 'attributeFilter alone Element.id/Element.className: multiple filter update mutation': + 'attributeFilter not implemented', 'childList false: no childList mutation': 'Element#textContent setter not implemented' }, 'dom/nodes/MutationObserver-characterData.html': { 'characterData Range.deleteContents: child and data removal mutation': 'Range#deleteContents not implemented', 'characterData Range.deleteContents: child and data removal mutation (2)': 'Range#deleteContents not implemented', 'characterData Range.extractContents: child and data removal mutation': 'Range#extractContents not implemented', - 'characterData Range.extractContents: child and data removal mutation (2)': 'Range#extractContents not implemented', + 'characterData Range.extractContents: child and data removal mutation (2)': 'Range#extractContents not implemented' }, 'dom/nodes/MutationObserver-childList.html': { 'childList Node.textContent: replace content mutation': 'Element#textContent setter not implemented', @@ -131,7 +148,7 @@ const TEST_BLACKLIST: { [key: string]: (string | { [key: string]: string }) } = 'childList Range.extractContents: child and data removal mutation': 'Range#extractContents not implemented', 'childList Range.insertNode: child insertion mutation': 'Range#insertNode not implemented', 'childList Range.insertNode: children insertion mutation': 'Range#insertNode not implemented', - 'childList Range.surroundContents: children removal and addition mutation': 'Range#surroundContents not implemented', + 'childList Range.surroundContents: children removal and addition mutation': 'Range#surroundContents not implemented' }, 'dom/nodes/MutationObserver-disconnect.html': 'Element#id not implemented', 'dom/nodes/MutationObserver-document.html': 'Running script during parsing not implemented', @@ -331,50 +348,51 @@ const TEST_BLACKLIST: { [key: string]: (string | { [key: string]: string }) } = 'dom/ranges/Range-stringifier.html': 'Range#toString not implemented', 'dom/ranges/Range-surroundContents.html': 'Range#surroundContents not implemented', 'dom/traversal': 'NodeIterator and TreeWalker not implemented' -} +}; -function getNodes (root: slimdom.Node, ...path: string[]): slimdom.Node[] { +function getNodes(root: slimdom.Node, ...path: string[]): slimdom.Node[] { if (!path.length) { return [root]; } const [nodeName, ...remainder] = path; const matchingChildren = Array.from((root as slimdom.Element).childNodes).filter(n => n.nodeName === nodeName); - return matchingChildren.reduce( - (nodes, child) => nodes.concat(getNodes(child, ...remainder)), - [] as slimdom.Node[] - ); + return matchingChildren.reduce((nodes, child) => nodes.concat(getNodes(child, ...remainder)), [] as slimdom.Node[]); } -function getAllText (root: slimdom.Node, ...path: string[]): string { - return getNodes(root, ...path) - .map(n => (n as slimdom.Text).data) - .join(''); +function getAllText(root: slimdom.Node, ...path: string[]): string { + return getNodes(root, ...path).map(n => (n as slimdom.Text).data).join(''); } -function getAllScripts (doc: slimdom.Document, casePath: string) { +function getAllScripts(doc: slimdom.Document, casePath: string) { const scriptElements = (doc as any).getElementsByTagName('script'); - return scriptElements.reduce((scripts: string[], el: slimdom.Element) => { - const src = el.attributes.find(a => a.name === 'src'); - if (src) { - const resolvedPath = src.value.startsWith('/') - ? path.resolve(process.env.WEB_PLATFORM_TESTS_PATH, src.value.substring(1)) - : path.resolve(path.dirname(casePath), src.value); - return scripts.concat([fs.readFileSync(resolvedPath, 'utf-8')]); - } + return scriptElements + .reduce((scripts: string[], el: slimdom.Element) => { + const src = el.attributes.find(a => a.name === 'src'); + if (src) { + const resolvedPath = src.value.startsWith('/') + ? path.resolve(process.env.WEB_PLATFORM_TESTS_PATH, src.value.substring(1)) + : path.resolve(path.dirname(casePath), src.value); + return scripts.concat([fs.readFileSync(resolvedPath, 'utf-8')]); + } - return scripts.concat([getAllText(el, '#text')]); - }, []).join('\n'); + return scripts.concat([getAllText(el, '#text')]); + }, []) + .join('\n'); } -function createTest (casePath: string, blacklistReason: { [key: string]: string } = {}): void { - const document = parse5.parse(fs.readFileSync(casePath, 'utf-8'), { treeAdapter: new SlimdomTreeAdapter }) as slimdom.Document; +function createTest(casePath: string, blacklistReason: { [key: string]: string } = {}): void { + const document = parse5.parse(fs.readFileSync(casePath, 'utf-8'), { + treeAdapter: new SlimdomTreeAdapter() + }) as slimdom.Document; const title = getAllText(document, 'html', 'head', 'title', '#text') || path.basename(casePath); const script = getAllScripts(document, casePath); const scriptAsFunction = new Function('stubEnvironment', `with (stubEnvironment) { ${script} }`); - let stubs: { global: any, onLoadCallbacks: Function[], onErrorCallback?: Function }; + let stubs: { global: any; onLoadCallbacks: Function[]; onErrorCallback?: Function }; - function createStubEnvironment (document: slimdom.Document): { global: any, onLoadCallbacks: Function[], onErrorCallback?: Function } { + function createStubEnvironment( + document: slimdom.Document + ): { global: any; onLoadCallbacks: Function[]; onErrorCallback?: Function } { const onLoadCallbacks: Function[] = []; let onErrorCallback: Function | undefined = undefined; let global: any = { @@ -382,7 +400,7 @@ function createTest (casePath: string, blacklistReason: { [key: string]: string location: { href: casePath }, window: null, - get frames () { + get frames() { return (document as any).getElementsByTagName('iframe').map((iframe: any) => { if (!iframe.contentWindow) { const stubs = createStubEnvironment(document.implementation.createHTMLDocument()); @@ -395,7 +413,7 @@ function createTest (casePath: string, blacklistReason: { [key: string]: string }); }, - addEventListener (event: string, cb: Function) { + addEventListener(event: string, cb: Function) { switch (event) { case 'load': onLoadCallbacks.push(cb); @@ -410,7 +428,7 @@ function createTest (casePath: string, blacklistReason: { [key: string]: string }, ...slimdom - } + }; global.window = global; global.parent = global; global.self = global; @@ -432,7 +450,7 @@ function createTest (casePath: string, blacklistReason: { [key: string]: string return; } - stubs.global.add_completion_callback(function (tests: any[], testStatus: any) { + stubs.global.add_completion_callback(function(tests: any[], testStatus: any) { // TODO: Seems to be triggered by duplicate names in the createDocument tests //chai.assert.equal(testStatus.status, testStatus.OK, testStatus.message); tests.forEach(test => { @@ -452,23 +470,21 @@ function createTest (casePath: string, blacklistReason: { [key: string]: string iframe.onload(); } }); - } - catch (e) { + } catch (e) { if (e instanceof chai.AssertionError) { throw e; } if (stubs.onErrorCallback) { stubs.onErrorCallback(e); - } - else { + } else { throw e; } } }); } -function createTests (dirPath: string): void { +function createTests(dirPath: string): void { fs.readdirSync(dirPath).forEach(entry => { const entryPath = path.join(dirPath, entry); const relativePath = path.relative(process.env.WEB_PLATFORM_TESTS_PATH, entryPath); @@ -489,7 +505,7 @@ function createTests (dirPath: string): void { if (entry.endsWith('.html')) { createTest(entryPath, blacklistReason); } - }) + }); } describe('web platform DOM test suite', () => { @@ -498,8 +514,11 @@ describe('web platform DOM test suite', () => { return; } - (slimdom.Document.prototype as any).getElementsByTagName = function (this: slimdom.Document, tagName: string): slimdom.Node[] { - return (function getElementsByTagName (node: slimdom.Node): slimdom.Node[] { + (slimdom.Document.prototype as any).getElementsByTagName = function( + this: slimdom.Document, + tagName: string + ): slimdom.Node[] { + return (function getElementsByTagName(node: slimdom.Node): slimdom.Node[] { return node.childNodes.reduce((elements, child) => { if (child.nodeName === tagName) { elements.push(child); @@ -514,8 +533,11 @@ describe('web platform DOM test suite', () => { })(this); }; - (slimdom.Document.prototype as any).getElementById = function getElementById (this: slimdom.Node, id: string): slimdom.Node | null { - return (function getElementById (node: slimdom.Node): slimdom.Node | null { + (slimdom.Document.prototype as any).getElementById = function getElementById( + this: slimdom.Node, + id: string + ): slimdom.Node | null { + return (function getElementById(node: slimdom.Node): slimdom.Node | null { for (let child = node.firstChild; child; child = child.nextSibling) { if (child.nodeType === slimdom.Node.ELEMENT_NODE && (child as slimdom.Element).getAttribute('id') === id) { return child; @@ -557,12 +579,12 @@ describe('web platform DOM test suite', () => { value: 'null' }, body: { - get () { + get() { return this.getElementsByTagName('body')[0] || null; } }, title: { - get () { + get() { return getAllText(this, 'html', 'head', 'title', '#text'); } } @@ -576,14 +598,14 @@ describe('web platform DOM test suite', () => { value: true }, textContent: { - get () { + get() { return this.nodeValue; } } }); Object.defineProperties(slimdom.CharacterData.prototype, { textContent: { - get () { + get() { return this.nodeValue; } }