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