1 | /**
|
2 | * Copyright 2018 The Incremental DOM Authors. All Rights Reserved.
|
3 | *
|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | * you may not use this file except in compliance with the License.
|
6 | * You may obtain a copy of the License at
|
7 | *
|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
9 | *
|
10 | * Unless required by applicable law or agreed to in writing, software
|
11 | * distributed under the License is distributed on an "AS-IS" BASIS,
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | * See the License for the specific language governing permissions and
|
14 | * limitations under the License.
|
15 | */
|
16 |
|
17 | import { getData, initData } from "./node_data";
|
18 | import { Key, NameOrCtorDef } from "./types";
|
19 |
|
20 | /**
|
21 | * Gets the namespace to create an element (of a given tag) in.
|
22 | * @param tag The tag to get the namespace for.
|
23 | * @param parent The current parent Node, if any.
|
24 | * @returns The namespace to use,
|
25 | */
|
26 | function getNamespaceForTag(tag: string, parent: Node | null) {
|
27 | if (tag === "svg") {
|
28 | return "http://www.w3.org/2000/svg";
|
29 | }
|
30 |
|
31 | if (tag === "math") {
|
32 | return "http://www.w3.org/1998/Math/MathML";
|
33 | }
|
34 |
|
35 | if (parent == null) {
|
36 | return null;
|
37 | }
|
38 |
|
39 | if (getData(parent).nameOrCtor === "foreignObject") {
|
40 | return null;
|
41 | }
|
42 |
|
43 | return parent.namespaceURI;
|
44 | }
|
45 |
|
46 | /**
|
47 | * Creates an Element and initializes the NodeData.
|
48 | * @param doc The document with which to create the Element.
|
49 | * @param parent The parent of new Element.
|
50 | * @param nameOrCtor The tag or constructor for the Element.
|
51 | * @param key A key to identify the Element.
|
52 | * @returns The newly created Element.
|
53 | */
|
54 | function createElement(
|
55 | doc: Document,
|
56 | parent: Node | null,
|
57 | nameOrCtor: NameOrCtorDef,
|
58 | key: Key
|
59 | ): Element {
|
60 | let el;
|
61 |
|
62 | if (typeof nameOrCtor === "function") {
|
63 | el = new nameOrCtor();
|
64 | } else {
|
65 | const namespace = getNamespaceForTag(nameOrCtor, parent);
|
66 |
|
67 | if (namespace) {
|
68 | el = doc.createElementNS(namespace, nameOrCtor);
|
69 | } else {
|
70 | el = doc.createElement(nameOrCtor);
|
71 | }
|
72 | }
|
73 |
|
74 | initData(el, nameOrCtor, key);
|
75 |
|
76 | return el;
|
77 | }
|
78 |
|
79 | /**
|
80 | * Creates a Text Node.
|
81 | * @param doc The document with which to create the Element.
|
82 | * @returns The newly created Text.
|
83 | */
|
84 | function createText(doc: Document): Text {
|
85 | const node = doc.createTextNode("");
|
86 | initData(node, "#text", null);
|
87 | return node;
|
88 | }
|
89 |
|
90 | export { createElement, createText };
|