Skip to content

Commit

Permalink
refactor(node): Use tagged union for node types (#804)
Browse files Browse the repository at this point in the history
This makes it straight-forward for users to consume the types.

Also adds a CDATA class.

BREAKING: Several classes have become abstract, and their constructors have changed.
  • Loading branch information
fb55 authored Apr 8, 2022
1 parent 9250dd5 commit acc934b
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 77 deletions.
17 changes: 9 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ElementType } from "domelementtype";
import {
Node,
ChildNode,
Element,
DataNode,
Text,
Comment,
NodeWithChildren,
CDATA,
Document,
ProcessingInstruction,
ParentNode,
} from "./node";

export * from "./node";
Expand Down Expand Up @@ -51,12 +52,12 @@ interface ParserInterface {
endIndex: number | null;
}

type Callback = (error: Error | null, dom: Node[]) => void;
type Callback = (error: Error | null, dom: ChildNode[]) => void;
type ElementCallback = (element: Element) => void;

export class DomHandler {
/** The elements of the DOM */
public dom: Node[] = [];
public dom: ChildNode[] = [];

/** The root element for the DOM */
public root = new Document(this.dom);
Expand All @@ -74,7 +75,7 @@ export class DomHandler {
private done = false;

/** Stack of open tags. */
protected tagStack: NodeWithChildren[] = [this.root];
protected tagStack: ParentNode[] = [this.root];

/** A data node that is still being written to. */
protected lastNode: DataNode | null = null;
Expand Down Expand Up @@ -184,7 +185,7 @@ export class DomHandler {

public oncdatastart(): void {
const text = new Text("");
const node = new NodeWithChildren(ElementType.CDATA, [text]);
const node = new CDATA([text]);

this.addNode(node);

Expand All @@ -209,10 +210,10 @@ export class DomHandler {
}
}

protected addNode(node: Node): void {
protected addNode(node: ChildNode): void {
const parent = this.tagStack[this.tagStack.length - 1];
const previousSibling = parent.children[parent.children.length - 1] as
| Node
| ChildNode
| undefined;

if (this.options.withStartIndices) {
Expand Down
21 changes: 20 additions & 1 deletion src/node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ describe("Nodes", () => {
});

it("should throw an error when cloning unsupported types", () => {
const el = new node.Node(ElementType.Doctype);
class Doctype extends node.Node {
type = ElementType.Doctype;
nodeType = NaN;
}
const el = new Doctype();
expect(() => el.cloneNode()).toThrow("Not implemented yet: doctype");
});

Expand All @@ -81,6 +85,21 @@ describe("Nodes", () => {
expect(node.isDirective(result)).toBe(false);
expect(node.isDocument(result)).toBe(false);
});

it("should support using tagged types", () => {
// We want to make sure TS is happy about the tagged types.
const parent: node.ParentNode = new node.Document([]);

function setQuirks(el: node.ParentNode): void {
if (el.type === ElementType.Root) {
el["x-mode"] = "no-quirks";
}
}

setQuirks(parent);

expect(parent).toHaveProperty("x-mode", "no-quirks");
});
});

type Options = DomHandlerOptions & ParserOptions;
Expand Down
Loading

0 comments on commit acc934b

Please sign in to comment.