From be208b45e8049681289d52aac8877f096a29e9ac Mon Sep 17 00:00:00 2001 From: feely Date: Mon, 4 Dec 2023 18:02:28 +0800 Subject: [PATCH] feat: add type check for compatible --- src/living/compatible.test.ts | 37 +++++++++++++++++++++++++++++++++++ src/living/nodes/ChildNode.ts | 17 ++++++++-------- src/living/nodes/Node.ts | 13 ++++++------ 3 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 src/living/compatible.test.ts diff --git a/src/living/compatible.test.ts b/src/living/compatible.test.ts new file mode 100644 index 0000000..7abec68 --- /dev/null +++ b/src/living/compatible.test.ts @@ -0,0 +1,37 @@ +import { it } from '@jest/globals'; +import { NodeImpl } from './nodes/Node'; + +type Equal = (() => T extends X ? 1 : 2) extends () => T extends Y + ? 1 + : 2 + ? true + : false; + +type Expect = T; + +type FindValidFields = { + [K in keyof T]: T[K] extends never ? never : K; +}[keyof T]; + +type CheckStrictCompatible< + StandardType, + ImplType extends StandardType, + Checked = { + [k in keyof StandardType]: Equal extends true + ? never + : [StandardType[k], ImplType[k]]; + } +> = Pick>; + +/** + * Check the consistency between the jsar-dom implementation and the standard dom implementation, + * return the incompatible fields. + */ +type IncompatibleFields = CheckStrictCompatible; + +type cases = [Expect>]; + +/** + * placeholder for jest, DO NOT REMOVE IT. + */ +it.todo('placeholder test'); diff --git a/src/living/nodes/ChildNode.ts b/src/living/nodes/ChildNode.ts index d9de7d8..c82db8d 100644 --- a/src/living/nodes/ChildNode.ts +++ b/src/living/nodes/ChildNode.ts @@ -1,5 +1,6 @@ import { convertNodesIntoNode } from '../node'; import { NodeImpl } from './Node'; +import ParentNodeImpl from './ParentNode'; /** * Represents an implementation of the ChildNode interface. @@ -12,7 +13,7 @@ export default class ChildNodeImpl implements ChildNode { * @param nodes - The nodes or strings to insert. */ after(...nodes: (string | Node)[]): void { - const parent = this.parentNode; + const parent = this.parentNode as ParentNodeImpl; if (parent) { let viableNextSibling = this.nextSibling; let idx = viableNextSibling ? nodes.indexOf(viableNextSibling) : -1; @@ -25,7 +26,7 @@ export default class ChildNodeImpl implements ChildNode { idx = nodes.indexOf(viableNextSibling); } - parent._preInsert(convertNodesIntoNode(this._ownerDocument, nodes), viableNextSibling); + parent._preInsert(convertNodesIntoNode(this._ownerDocument, nodes), viableNextSibling as ChildNodeImpl); } } @@ -36,7 +37,7 @@ export default class ChildNodeImpl implements ChildNode { * @returns void */ before(...nodes: (string | Node)[]): void { - const parent = this.parentNode; + const parent = this.parentNode as ParentNodeImpl; if (parent) { let viablePreviousSibling = this.previousSibling; let idx = viablePreviousSibling ? nodes.indexOf(viablePreviousSibling) : -1; @@ -51,7 +52,7 @@ export default class ChildNodeImpl implements ChildNode { parent._preInsert( convertNodesIntoNode(this._ownerDocument, nodes), - viablePreviousSibling ? viablePreviousSibling.nextSibling : parent.firstChild + (viablePreviousSibling ? viablePreviousSibling.nextSibling : parent.firstChild) as ChildNodeImpl ); } } @@ -63,7 +64,7 @@ export default class ChildNodeImpl implements ChildNode { if (!this.parentNode) { return; } - this.parentNode._remove(this); + (this.parentNode as ParentNodeImpl)._remove(this); } /** @@ -72,7 +73,7 @@ export default class ChildNodeImpl implements ChildNode { * @param nodes - The nodes to replace the child nodes with. */ replaceWith(...nodes: (string | Node)[]): void { - const parent = this.parentNode; + const parent = this.parentNode as ParentNodeImpl; if (parent) { let viableNextSibling = this.nextSibling; let idx = viableNextSibling ? nodes.indexOf(viableNextSibling) : -1; @@ -86,10 +87,10 @@ export default class ChildNodeImpl implements ChildNode { } const node = convertNodesIntoNode(this._ownerDocument, nodes); - if (this.parentNode === parent) { + if (this.parentNode as ParentNodeImpl === parent) { parent._replace(node, this); } else { - parent._preInsert(node, viableNextSibling); + parent._preInsert(node, viableNextSibling as ChildNodeImpl); } } } diff --git a/src/living/nodes/Node.ts b/src/living/nodes/Node.ts index c00b29a..7810c2a 100644 --- a/src/living/nodes/Node.ts +++ b/src/living/nodes/Node.ts @@ -214,7 +214,7 @@ export class NodeImpl extends EventTarget implements Node { return documentBaseURLSerialized(this._ownerDocument); } - get parentNode(): ParentNodeImpl { + get parentNode(): ParentNode { return domSymbolTree.parent(this); } @@ -275,15 +275,15 @@ export class NodeImpl extends EventTarget implements Node { return this.nodeType === this.DOCUMENT_NODE ? null : this._ownerDocument as Document; } - get nextSibling() { + get nextSibling(): ChildNode | null { return domSymbolTree.nextSibling(this); } - get previousSibling() { + get previousSibling(): ChildNode | null { return domSymbolTree.previousSibling(this); } - get parentElement() { + get parentElement(): HTMLElement | null { const parentNode = domSymbolTree.parent(this); return parentNode !== null && parentNode.nodeType === NodeImpl.ELEMENT_NODE ? parentNode : null; } @@ -509,8 +509,9 @@ export class NodeImpl extends EventTarget implements Node { removeChild(child: T): T { return this._preRemove(child as unknown as NodeImpl) as unknown as T; } - replaceChild(node: T1, child: T1): T2 { - return this._replace(node as unknown as NodeImpl, child as unknown as NodeImpl) as unknown as T2; + + replaceChild(node: Node, child: T): T { + return this._replace(node as unknown as NodeImpl, child as unknown as NodeImpl) as unknown as T; } // https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity