• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import Element from './Element';
17import Node from './Node';
18import { Log } from '../utils';
19
20/**
21 * Document element is the root element in a Document.
22 * @extends Element
23 */
24class DocumentElement extends Element {
25  constructor(type: string = 'div', props: object = {}, isExtended?: boolean) {
26    super(type, props, isExtended);
27  }
28
29  /**
30   * Destroy this document element.
31   */
32  public destroy() {
33    const doc = this._ownerDocument;
34    if (doc) {
35      delete this.docId;
36      delete doc.nodeMap[this.nodeId];
37    }
38    super.destroy();
39  }
40
41  /**
42   * Append a child node.
43   * @param {Node} node - Target node.
44   * @param {number} before - The node next to the target position.
45   * @override
46   */
47  public appendChild(node: Node, before?: Node): void {
48    Log.debug(`DocumentElement#appendChild, node = ${node}, before = ${before}.`);
49
50    if (this.pureChildren.length > 0 || node.parentNode) {
51      return;
52    }
53    const children = this.children;
54    const beforeIndex = children.indexOf(before);
55    if (beforeIndex < 0) {
56      children.push(node);
57    } else {
58      children.splice(beforeIndex, 0, node);
59    }
60
61    if (node.nodeType === Node.NodeType.Element) {
62      const element = node as Element;
63      if (element.role === 'body') {
64        element.docId = this.id;
65        element.ownerDocument = this.ownerDocument;
66        element.parentNode = this;
67        this.linkChild(element);
68      } else {
69        element.children.forEach(child => {
70          child.parentNode = element;
71        });
72        const document = this.ownerDocument;
73        document.setElementToBody(element);
74        element.docId = document.id;
75        element.ownerDocument = document;
76        this.linkChild(this);
77        if (this.ownerDocument) {
78          delete this.ownerDocument.nodeMap[element.nodeId];
79        }
80      }
81      this.pureChildren.push(element);
82      this.ownerDocument.sentBodyToNative(element);
83    } else {
84      node.parentNode = this;
85      this.ownerDocument.nodeMap[node.ref] = node;
86    }
87  }
88}
89
90export default DocumentElement;
91