UNPKG

2.22 kBJavaScriptView Raw
1// @flow
2
3import utils from "./utils";
4
5import type {CssStyle, HtmlDomNode} from "./domTree";
6import type {MathDomNode} from "./mathMLTree";
7
8
9// To ensure that all nodes have compatible signatures for these methods.
10export interface VirtualNode {
11 toNode(): Node;
12 toMarkup(): string;
13}
14
15
16/**
17 * This node represents a document fragment, which contains elements, but when
18 * placed into the DOM doesn't have any representation itself. It only contains
19 * children and doesn't have any DOM node properties.
20 */
21export class DocumentFragment<ChildType: VirtualNode>
22 implements HtmlDomNode, MathDomNode {
23 children: ChildType[];
24 // HtmlDomNode
25 classes: string[];
26 height: number;
27 depth: number;
28 maxFontSize: number;
29 style: CssStyle; // Never used; needed for satisfying interface.
30
31 constructor(children: ChildType[]) {
32 this.children = children;
33 this.classes = [];
34 this.height = 0;
35 this.depth = 0;
36 this.maxFontSize = 0;
37 this.style = {};
38 }
39
40 hasClass(className: string): boolean {
41 return utils.contains(this.classes, className);
42 }
43
44 /** Convert the fragment into a node. */
45 toNode(): Node {
46 const frag = document.createDocumentFragment();
47
48 for (let i = 0; i < this.children.length; i++) {
49 frag.appendChild(this.children[i].toNode());
50 }
51
52 return frag;
53 }
54
55 /** Convert the fragment into HTML markup. */
56 toMarkup(): string {
57 let markup = "";
58
59 // Simply concatenate the markup for the children together.
60 for (let i = 0; i < this.children.length; i++) {
61 markup += this.children[i].toMarkup();
62 }
63
64 return markup;
65 }
66
67 /**
68 * Converts the math node into a string, similar to innerText. Applies to
69 * MathDomNode's only.
70 */
71 toText(): string {
72 // To avoid this, we would subclass documentFragment separately for
73 // MathML, but polyfills for subclassing is expensive per PR 1469.
74 // $FlowFixMe: Only works for ChildType = MathDomNode.
75 const toText = (child: ChildType): string => child.toText();
76 return this.children.map(toText).join("");
77 }
78}