tree.js 2.2 KB

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