Skip to content

Commit

Permalink
feat: add type check for compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
FeelyChau committed Dec 6, 2023
1 parent 665c0f4 commit be208b4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 14 deletions.
37 changes: 37 additions & 0 deletions src/living/compatible.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { it } from '@jest/globals';
import { NodeImpl } from './nodes/Node';

type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
? 1
: 2
? true
: false;

type Expect<T extends true> = T;

type FindValidFields<T> = {
[K in keyof T]: T[K] extends never ? never : K;
}[keyof T];

type CheckStrictCompatible<
StandardType,
ImplType extends StandardType,
Checked = {
[k in keyof StandardType]: Equal<StandardType[k], ImplType[k]> extends true
? never
: [StandardType[k], ImplType[k]];
}
> = Pick<Checked, FindValidFields<Checked>>;

/**
* Check the consistency between the jsar-dom implementation and the standard dom implementation,
* return the incompatible fields.
*/
type IncompatibleFields = CheckStrictCompatible<Node, NodeImpl>;

type cases = [Expect<Equal<{}, IncompatibleFields>>];

/**
* placeholder for jest, DO NOT REMOVE IT.
*/
it.todo('placeholder test');
17 changes: 9 additions & 8 deletions src/living/nodes/ChildNode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { convertNodesIntoNode } from '../node';
import { NodeImpl } from './Node';
import ParentNodeImpl from './ParentNode';

/**
* Represents an implementation of the ChildNode interface.
Expand All @@ -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;
Expand All @@ -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);
}
}

Expand All @@ -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;
Expand All @@ -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
);
}
}
Expand All @@ -63,7 +64,7 @@ export default class ChildNodeImpl implements ChildNode {
if (!this.parentNode) {
return;
}
this.parentNode._remove(this);
(this.parentNode as ParentNodeImpl)._remove(this);
}

/**
Expand All @@ -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;
Expand All @@ -86,10 +87,10 @@ export default class ChildNodeImpl implements ChildNode {
}

const node = convertNodesIntoNode<NodeImpl>(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);
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/living/nodes/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -509,8 +509,9 @@ export class NodeImpl extends EventTarget implements Node {
removeChild<T extends Node>(child: T): T {
return this._preRemove(child as unknown as NodeImpl) as unknown as T;
}
replaceChild<T1 extends Node, T2 extends Node>(node: T1, child: T1): T2 {
return this._replace(node as unknown as NodeImpl, child as unknown as NodeImpl) as unknown as T2;

replaceChild<T extends Node>(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
Expand Down

0 comments on commit be208b4

Please sign in to comment.