/*
 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.DOMNode = class DOMNode extends WI.Object
{
    constructor(domManager, doc, isInShadowTree, payload)
    {
        super();

        this._destroyed = false;

        this._domManager = domManager;
        this._isInShadowTree = isInShadowTree;

        this.id = payload.nodeId;
        this._domManager._idToDOMNode[this.id] = this;

        this._nodeType = payload.nodeType;
        this._nodeName = payload.nodeName;
        this._localName = payload.localName;
        this._nodeValue = payload.nodeValue;
        this._pseudoType = payload.pseudoType;
        this._shadowRootType = payload.shadowRootType;
        this._computedRole = null;
        this._contentSecurityPolicyHash = payload.contentSecurityPolicyHash;
        this._layoutContextType = null;
        this._layoutOverlayShowing = false;
        this._layoutOverlayColorSetting = null;

        if (this._nodeType === Node.DOCUMENT_NODE)
            this.ownerDocument = this;
        else
            this.ownerDocument = doc;

        this._frame = null;

        // COMPATIBILITY (iOS 12.2): DOM.Node.frameId was changed to represent the owner frame, not the content frame.
        // Since support can't be tested directly, check for Audit (iOS 13.0+).
        // FIXME: Use explicit version checking once https://webkit.org/b/148680 is fixed.
        if (InspectorBackend.hasDomain("Audit")) {
            if (payload.frameId)
                this._frame = WI.networkManager.frameForIdentifier(payload.frameId);
        }

        if (!this._frame && this.ownerDocument)
            this._frame = WI.networkManager.frameForIdentifier(this.ownerDocument.frameIdentifier);

        this._attributes = [];
        this._attributesMap = new Map;
        if (payload.attributes)
            this._setAttributesPayload(payload.attributes);

        this._childNodeCount = payload.childNodeCount;
        this._children = null;

        this._nextSibling = null;
        this._previousSibling = null;
        this.parentNode = null;

        this._enabledPseudoClasses = [];

        // FIXME: The logic around this._shadowRoots and this._children is very confusing.
        // We eventually include shadow roots at the start of _children. However we might
        // not have our actual children yet. So we try to defer initializing _children until
        // we have both shadowRoots and child nodes.
        this._shadowRoots = [];
        if (payload.shadowRoots) {
            for (var i = 0; i < payload.shadowRoots.length; ++i) {
                var root = payload.shadowRoots[i];
                var node = new WI.DOMNode(this._domManager, this.ownerDocument, true, root);
                node.parentNode = this;
                this._shadowRoots.push(node);
            }
        }

        if (payload.children)
            this._setChildrenPayload(payload.children);
        else if (this._shadowRoots.length && !this._childNodeCount)
            this._children = this._shadowRoots.slice();

        if (this._nodeType === Node.ELEMENT_NODE)
            this._customElementState = payload.customElementState || WI.DOMNode.CustomElementState.Builtin;
        else
            this._customElementState = null;

        if (payload.templateContent) {
            this._templateContent = new WI.DOMNode(this._domManager, this.ownerDocument, false, payload.templateContent);
            this._templateContent.parentNode = this;
        }

        this._pseudoElements = new Map;
        if (payload.pseudoElements) {
            for (var i = 0; i < payload.pseudoElements.length; ++i) {
                var node = new WI.DOMNode(this._domManager, this.ownerDocument, this._isInShadowTree, payload.pseudoElements[i]);
                node.parentNode = this;
                this._pseudoElements.set(node.pseudoType(), node);
            }
        }

        if (payload.contentDocument) {
            this._contentDocument = new WI.DOMNode(this._domManager, null, false, payload.contentDocument);
            this._children = [this._contentDocument];
            this._renumber();
        }

        if (this._nodeType === Node.ELEMENT_NODE) {
            // HTML and BODY from internal iframes should not overwrite top-level ones.
            if (this.ownerDocument && !this.ownerDocument.documentElement && this._nodeName === "HTML")
                this.ownerDocument.documentElement = this;
            if (this.ownerDocument && !this.ownerDocument.body && this._nodeName === "BODY")
                this.ownerDocument.body = this;
            if (payload.documentURL)
                this.documentURL = payload.documentURL;
        } else if (this._nodeType === Node.DOCUMENT_TYPE_NODE) {
            this.publicId = payload.publicId;
            this.systemId = payload.systemId;
        } else if (this._nodeType === Node.DOCUMENT_NODE) {
            this.documentURL = payload.documentURL;
            this.xmlVersion = payload.xmlVersion;
        } else if (this._nodeType === Node.ATTRIBUTE_NODE) {
            this.name = payload.name;
            this.value = payload.value;
        }

        this._domEvents = [];
        this._powerEfficientPlaybackRanges = [];

        if (this.isMediaElement())
            WI.DOMNode.addEventListener(WI.DOMNode.Event.DidFireEvent, this._handleDOMNodeDidFireEvent, this);

        // Setting layoutContextType to anything other than null will dispatch an event.
        this.layoutContextType = payload.layoutContextType;
    }

    // Static

    static resetDefaultLayoutOverlayConfiguration()
    {
        let configuration = WI.DOMNode._defaultLayoutOverlayConfiguration;
        configuration.nextFlexColorIndex = 0;
        configuration.nextGridColorIndex = 0;
    }

    static getFullscreenDOMEvents(domEvents)
    {
        return domEvents.reduce((accumulator, current) => {
            if (current.eventName === "webkitfullscreenchange" && current.data && (!accumulator.length || accumulator.lastValue.data.enabled !== current.data.enabled))
                accumulator.push(current);
            return accumulator;
        }, []);
    }

    static isPlayEvent(eventName)
    {
        return eventName === "play"
            || eventName === "playing";
    }

    static isPauseEvent(eventName)
    {
        return eventName === "pause"
            || eventName === "stall";
    }

    static isStopEvent(eventName)
    {
        return eventName === "emptied"
            || eventName === "ended"
            || eventName === "suspend";
    }


    // Public

    get destroyed() { return this._destroyed; }
    get frame() { return this._frame; }
    get nextSibling() { return this._nextSibling; }
    get previousSibling() { return this._previousSibling; }
    get children() { return this._children; }
    get domEvents() { return this._domEvents; }
    get powerEfficientPlaybackRanges() { return this._powerEfficientPlaybackRanges; }
    get layoutOverlayShowing() { return this._layoutOverlayShowing; }

    get attached()
    {
        if (this._destroyed)
            return false;

        for (let node = this; node; node = node.parentNode) {
            if (node.ownerDocument === node)
                return true;
        }
        return false;
    }

    get firstChild()
    {
        var children = this.children;

        if (children && children.length > 0)
            return children[0];

        return null;
    }

    get lastChild()
    {
        var children = this.children;

        if (children && children.length > 0)
            return children.lastValue;

        return null;
    }

    get childNodeCount()
    {
        var children = this.children;
        if (children)
            return children.length;

        return this._childNodeCount + this._shadowRoots.length;
    }

    set childNodeCount(count)
    {
        this._childNodeCount = count;
    }

    get layoutContextType()
    {
        return this._layoutContextType;
    }

    set layoutContextType(layoutContextType)
    {
        layoutContextType ||= null;
        if (layoutContextType === this._layoutContextType)
            return;

        let oldLayoutContextType = this._layoutContextType;
        this._layoutContextType = layoutContextType;

        this.dispatchEventToListeners(WI.DOMNode.Event.LayoutContextTypeChanged);

        if (!this._layoutOverlayShowing)
            return;

        // The overlay is automatically hidden on the backend when the context type changes.
        this.dispatchEventToListeners(WI.DOMNode.Event.LayoutOverlayHidden);

        switch (oldLayoutContextType) {
        case WI.DOMNode.LayoutContextType.Flex:
            WI.settings.flexOverlayShowOrderNumbers.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            break;

        case WI.DOMNode.LayoutContextType.Grid:
            WI.settings.gridOverlayShowExtendedGridLines.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowLineNames.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowLineNumbers.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowTrackSizes.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowAreaNames.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            break;
        }
    }

    markDestroyed()
    {
        console.assert(!this._destroyed, this);
        this._destroyed = true;

        this.layoutContextType = null;
    }

    computedRole()
    {
        return this._computedRole;
    }

    contentSecurityPolicyHash()
    {
        return this._contentSecurityPolicyHash;
    }

    hasAttributes()
    {
        return this._attributes.length > 0;
    }

    hasChildNodes()
    {
        return this.childNodeCount > 0;
    }

    hasShadowRoots()
    {
        return !!this._shadowRoots.length;
    }

    isInShadowTree()
    {
        return this._isInShadowTree;
    }

    isInUserAgentShadowTree()
    {
        return this._isInShadowTree && this.ancestorShadowRoot().isUserAgentShadowRoot();
    }

    isCustomElement()
    {
        return this._customElementState === WI.DOMNode.CustomElementState.Custom;
    }

    customElementState()
    {
        return this._customElementState;
    }

    isShadowRoot()
    {
        return !!this._shadowRootType;
    }

    isUserAgentShadowRoot()
    {
        return this._shadowRootType === WI.DOMNode.ShadowRootType.UserAgent;
    }

    ancestorShadowRoot()
    {
        if (!this._isInShadowTree)
            return null;

        let node = this;
        while (node && !node.isShadowRoot())
            node = node.parentNode;
        return node;
    }

    ancestorShadowHost()
    {
        let shadowRoot = this.ancestorShadowRoot();
        return shadowRoot ? shadowRoot.parentNode : null;
    }

    isPseudoElement()
    {
        return this._pseudoType !== undefined;
    }

    nodeType()
    {
        return this._nodeType;
    }

    nodeName()
    {
        return this._nodeName;
    }

    nodeNameInCorrectCase()
    {
        return this.isXMLNode() ? this.nodeName() : this.nodeName().toLowerCase();
    }

    setNodeName(name, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.setNodeName(this.id, name, this._makeUndoableCallback(callback));
    }

    localName()
    {
        return this._localName;
    }

    templateContent()
    {
        return this._templateContent || null;
    }

    pseudoType()
    {
        return this._pseudoType;
    }

    hasPseudoElements()
    {
        return this._pseudoElements.size > 0;
    }

    pseudoElements()
    {
        return this._pseudoElements;
    }

    beforePseudoElement()
    {
        return this._pseudoElements.get(WI.DOMNode.PseudoElementType.Before) || null;
    }

    afterPseudoElement()
    {
        return this._pseudoElements.get(WI.DOMNode.PseudoElementType.After) || null;
    }

    shadowRoots()
    {
        return this._shadowRoots;
    }

    shadowRootType()
    {
        return this._shadowRootType;
    }

    nodeValue()
    {
        return this._nodeValue;
    }

    setNodeValue(value, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.setNodeValue(this.id, value, this._makeUndoableCallback(callback));
    }

    getAttribute(name)
    {
        let attr = this._attributesMap.get(name);
        return attr ? attr.value : undefined;
    }

    setAttribute(name, text, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.setAttributesAsText(this.id, text, name, this._makeUndoableCallback(callback));
    }

    setAttributeValue(name, value, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.setAttributeValue(this.id, name, value, this._makeUndoableCallback(callback));
    }

    attributes()
    {
        return this._attributes;
    }

    removeAttribute(name, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        function mycallback(error, success)
        {
            if (!error) {
                this._attributesMap.delete(name);
                for (var i = 0; i < this._attributes.length; ++i) {
                    if (this._attributes[i].name === name) {
                        this._attributes.splice(i, 1);
                        break;
                    }
                }
            }

            this._makeUndoableCallback(callback)(error);
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.removeAttribute(this.id, name, mycallback.bind(this));
    }

    toggleClass(className, flag)
    {
        if (!className || !className.length)
            return;

        if (this.isPseudoElement()) {
            this.parentNode.toggleClass(className, flag);
            return;
        }

        if (this.nodeType() !== Node.ELEMENT_NODE)
            return;

        WI.RemoteObject.resolveNode(this).then((object) => {
            function inspectedPage_node_toggleClass(className, flag) {
                this.classList.toggle(className, flag);
            }

            object.callFunction(inspectedPage_node_toggleClass, [className, flag]);
            object.release();
        });
    }

    querySelector(selector, callback)
    {
        console.assert(!this._destroyed, this);

        let target = WI.assumingMainTarget();

        if (typeof callback !== "function") {
            if (this._destroyed)
                return Promise.reject("ERROR: node is destroyed");
            return target.DOMAgent.querySelector(this.id, selector).then(({nodeId}) => nodeId);
        }

        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        target.DOMAgent.querySelector(this.id, selector, WI.DOMManager.wrapClientCallback(callback));
    }

    querySelectorAll(selector, callback)
    {
        console.assert(!this._destroyed, this);

        let target = WI.assumingMainTarget();

        if (typeof callback !== "function") {
            if (this._destroyed)
                return Promise.reject("ERROR: node is destroyed");
            return target.DOMAgent.querySelectorAll(this.id, selector).then(({nodeIds}) => nodeIds);
        }

        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        target.DOMAgent.querySelectorAll(this.id, selector, WI.DOMManager.wrapClientCallback(callback));
    }

    highlight(mode)
    {
        if (this._destroyed)
            return;

        if (this._hideDOMNodeHighlightTimeout) {
            clearTimeout(this._hideDOMNodeHighlightTimeout);
            this._hideDOMNodeHighlightTimeout = undefined;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.highlightNode(WI.DOMManager.buildHighlightConfig(mode), this.id);
    }

    showLayoutOverlay({color, initiator} = {})
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed)
            return Promise.reject("ERROR: node is destroyed");

        console.assert(Object.values(WI.DOMNode.LayoutContextType).includes(this._layoutContextType), this);

        console.assert(!color || color instanceof WI.Color, color);
        color ||= this.layoutOverlayColor;

        let target = WI.assumingMainTarget();
        let agentCommandFunction = null;
        let agentCommandArguments = {nodeId: this.id};

        switch (this._layoutContextType) {
        case WI.DOMNode.LayoutContextType.Grid:
            agentCommandArguments.gridColor = color.toProtocol();
            agentCommandArguments.showLineNames = WI.settings.gridOverlayShowLineNames.value;
            agentCommandArguments.showLineNumbers = WI.settings.gridOverlayShowLineNumbers.value;
            agentCommandArguments.showExtendedGridLines = WI.settings.gridOverlayShowExtendedGridLines.value;
            agentCommandArguments.showTrackSizes = WI.settings.gridOverlayShowTrackSizes.value;
            agentCommandArguments.showAreaNames = WI.settings.gridOverlayShowAreaNames.value;
            agentCommandFunction = target.DOMAgent.showGridOverlay;

            if (!this._layoutOverlayShowing) {
                WI.settings.gridOverlayShowExtendedGridLines.addEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
                WI.settings.gridOverlayShowLineNames.addEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
                WI.settings.gridOverlayShowLineNumbers.addEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
                WI.settings.gridOverlayShowTrackSizes.addEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
                WI.settings.gridOverlayShowAreaNames.addEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            }
            break;

        case WI.DOMNode.LayoutContextType.Flex:
            agentCommandArguments.flexColor = color.toProtocol();
            agentCommandArguments.showOrderNumbers = WI.settings.flexOverlayShowOrderNumbers.value;
            agentCommandFunction = target.DOMAgent.showFlexOverlay;

            if (!this._layoutOverlayShowing)
                WI.settings.flexOverlayShowOrderNumbers.addEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            break;
        }

        this._layoutOverlayShowing = true;

        this.dispatchEventToListeners(WI.DOMNode.Event.LayoutOverlayShown, {initiator});

        console.assert(agentCommandFunction);
        return agentCommandFunction.invoke(agentCommandArguments);
    }

    hideLayoutOverlay()
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed)
            return Promise.reject("ERROR: node is destroyed");

        console.assert(Object.values(WI.DOMNode.LayoutContextType).includes(this._layoutContextType), this);

        let target = WI.assumingMainTarget();
        let agentCommandFunction;
        let agentCommandArguments = {nodeId: this.id};

        switch (this._layoutContextType) {
        case WI.DOMNode.LayoutContextType.Grid:
            WI.settings.gridOverlayShowExtendedGridLines.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowLineNames.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowLineNumbers.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowTrackSizes.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);
            WI.settings.gridOverlayShowAreaNames.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);

            agentCommandFunction = target.DOMAgent.hideGridOverlay;
            break;

        case WI.DOMNode.LayoutContextType.Flex:
            WI.settings.flexOverlayShowOrderNumbers.removeEventListener(WI.Setting.Event.Changed, this._handleLayoutOverlaySettingChanged, this);

            agentCommandFunction = target.DOMAgent.hideFlexOverlay;
            break;
        }

        console.assert(this._layoutOverlayShowing, this);
        this._layoutOverlayShowing = false;

        this.dispatchEventToListeners(WI.DOMNode.Event.LayoutOverlayHidden);

        console.assert(agentCommandFunction);
        return agentCommandFunction.invoke(agentCommandArguments);
    }

    get layoutOverlayColor()
    {
        this._createLayoutOverlayColorSettingIfNeeded();
        return new WI.Color(WI.Color.Format.HSL, this._layoutOverlayColorSetting.value);
    }

    set layoutOverlayColor(color)
    {
        console.assert(color instanceof WI.Color, color);

        this._createLayoutOverlayColorSettingIfNeeded();
        this._layoutOverlayColorSetting.value = color.hsl;

        if (this._layoutOverlayShowing)
            this.showLayoutOverlay({color});
    }

    scrollIntoView()
    {
        WI.RemoteObject.resolveNode(this).then((object) => {
            function inspectedPage_node_scrollIntoView() {
                this.scrollIntoViewIfNeeded(true);
            }

            object.callFunction(inspectedPage_node_scrollIntoView);
            object.release();
        });
    }

    getChildNodes(callback)
    {
        if (this.children) {
            if (callback)
                callback(this.children);
            return;
        }

        if (this._destroyed) {
            callback(this.children);
            return;
        }

        function mycallback(error) {
            if (!error && callback)
                callback(this.children);
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.requestChildNodes(this.id, mycallback.bind(this));
    }

    getSubtree(depth, callback)
    {
        if (this._destroyed) {
            callback(this.children);
            return;
        }

        function mycallback(error)
        {
            if (callback)
                callback(error ? null : this.children);
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.requestChildNodes(this.id, depth, mycallback.bind(this));
    }

    getOuterHTML(callback)
    {
        console.assert(!this._destroyed, this);

        let target = WI.assumingMainTarget();

        if (typeof callback !== "function") {
            if (this._destroyed)
                return Promise.reject("ERROR: node is destroyed");
            return target.DOMAgent.getOuterHTML(this.id).then(({outerHTML}) => outerHTML);
        }

        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        target.DOMAgent.getOuterHTML(this.id, callback);
    }

    setOuterHTML(html, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.setOuterHTML(this.id, html, this._makeUndoableCallback(callback));
    }

    insertAdjacentHTML(position, html)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed)
            return;

        if (this.nodeType() !== Node.ELEMENT_NODE)
            return;

        let target = WI.assumingMainTarget();

        // COMPATIBILITY (iOS 11.0): DOM.insertAdjacentHTML did not exist.
        if (!target.hasCommand("DOM.insertAdjacentHTML")) {
            WI.RemoteObject.resolveNode(this).then((object) => {
                function inspectedPage_node_insertAdjacentHTML(position, html) {
                    this.insertAdjacentHTML(position, html);
                }

                object.callFunction(inspectedPage_node_insertAdjacentHTML, [position, html]);
                object.release();
            });
            return;
        }

        target.DOMAgent.insertAdjacentHTML(this.id, position, html, this._makeUndoableCallback());
    }

    removeNode(callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.removeNode(this.id, this._makeUndoableCallback(callback));
    }

    getEventListeners(callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        console.assert(WI.domManager.inspectedNode === this);

        let target = WI.assumingMainTarget();
        target.DOMAgent.getEventListenersForNode(this.id, callback);
    }

    accessibilityProperties(callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback({});
            return;
        }

        function accessibilityPropertiesCallback(error, accessibilityProperties)
        {
            if (!error && callback && accessibilityProperties) {
                this._computedRole = accessibilityProperties.role;

                callback({
                    activeDescendantNodeId: accessibilityProperties.activeDescendantNodeId,
                    busy: accessibilityProperties.busy,
                    checked: accessibilityProperties.checked,
                    childNodeIds: accessibilityProperties.childNodeIds,
                    controlledNodeIds: accessibilityProperties.controlledNodeIds,
                    current: accessibilityProperties.current,
                    disabled: accessibilityProperties.disabled,
                    exists: accessibilityProperties.exists,
                    expanded: accessibilityProperties.expanded,
                    flowedNodeIds: accessibilityProperties.flowedNodeIds,
                    focused: accessibilityProperties.focused,
                    ignored: accessibilityProperties.ignored,
                    ignoredByDefault: accessibilityProperties.ignoredByDefault,
                    invalid: accessibilityProperties.invalid,
                    isPopupButton: accessibilityProperties.isPopUpButton,
                    headingLevel: accessibilityProperties.headingLevel,
                    hierarchyLevel: accessibilityProperties.hierarchyLevel,
                    hidden: accessibilityProperties.hidden,
                    label: accessibilityProperties.label,
                    liveRegionAtomic: accessibilityProperties.liveRegionAtomic,
                    liveRegionRelevant: accessibilityProperties.liveRegionRelevant,
                    liveRegionStatus: accessibilityProperties.liveRegionStatus,
                    mouseEventNodeId: accessibilityProperties.mouseEventNodeId,
                    nodeId: accessibilityProperties.nodeId,
                    ownedNodeIds: accessibilityProperties.ownedNodeIds,
                    parentNodeId: accessibilityProperties.parentNodeId,
                    pressed: accessibilityProperties.pressed,
                    readonly: accessibilityProperties.readonly,
                    required: accessibilityProperties.required,
                    role: accessibilityProperties.role,
                    selected: accessibilityProperties.selected,
                    selectedChildNodeIds: accessibilityProperties.selectedChildNodeIds
                });
            }
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.getAccessibilityPropertiesForNode(this.id, accessibilityPropertiesCallback.bind(this));
    }

    path()
    {
        var path = [];
        var node = this;
        while (node && "index" in node && node._nodeName.length) {
            path.push([node.index, node._nodeName]);
            node = node.parentNode;
        }
        path.reverse();
        return path.join(",");
    }

    get escapedIdSelector()
    {
        return this._idSelector(true);
    }

    get escapedClassSelector()
    {
        return this._classSelector(true);
    }

    get displayName()
    {
        if (this.isPseudoElement())
            return "::" + this._pseudoType;
        return this.nodeNameInCorrectCase() + this.escapedIdSelector + this.escapedClassSelector;
    }

    get unescapedSelector()
    {
        if (this.isPseudoElement())
            return "::" + this._pseudoType;

        const shouldEscape = false;
        return this.nodeNameInCorrectCase() + this._idSelector(shouldEscape) + this._classSelector(shouldEscape);
    }

    appropriateSelectorFor(justSelector)
    {
        if (this.isPseudoElement())
            return this.parentNode.appropriateSelectorFor() + "::" + this._pseudoType;

        let lowerCaseName = this.localName() || this.nodeName().toLowerCase();

        let id = this.escapedIdSelector;
        if (id.length)
            return justSelector ? id : lowerCaseName + id;

        let classes = this.escapedClassSelector;
        if (classes.length)
            return justSelector ? classes : lowerCaseName + classes;

        if (lowerCaseName === "input" && this.getAttribute("type"))
            return lowerCaseName + "[type=\"" + this.getAttribute("type") + "\"]";

        return lowerCaseName;
    }

    isAncestor(node)
    {
        if (!node)
            return false;

        var currentNode = node.parentNode;
        while (currentNode) {
            if (this === currentNode)
                return true;
            currentNode = currentNode.parentNode;
        }
        return false;
    }

    isDescendant(descendant)
    {
        return descendant !== null && descendant.isAncestor(this);
    }

    get ownerSVGElement()
    {
        if (this._nodeName === "svg")
            return this;

        if (!this.parentNode)
            return null;

        return this.parentNode.ownerSVGElement;
    }

    isSVGElement()
    {
        return !!this.ownerSVGElement;
    }

    isMediaElement()
    {
        let lowerCaseName = this.localName() || this.nodeName().toLowerCase();
        return lowerCaseName === "video" || lowerCaseName === "audio";
    }

    didFireEvent(eventName, timestamp, data)
    {
        // Called from WI.DOMManager.

        this._addDOMEvent({
            eventName,
            timestamp: WI.timelineManager.computeElapsedTime(timestamp),
            data,
        });
    }

    powerEfficientPlaybackStateChanged(timestamp, isPowerEfficient)
    {
        // Called from WI.DOMManager.

        console.assert(this.canEnterPowerEfficientPlaybackState());

        let lastValue = this._powerEfficientPlaybackRanges.lastValue;

        if (isPowerEfficient) {
            console.assert(!lastValue || lastValue.endTimestamp);
            if (!lastValue || lastValue.endTimestamp)
                this._powerEfficientPlaybackRanges.push({startTimestamp: timestamp});
        } else {
            console.assert(!lastValue || lastValue.startTimestamp);
            if (!lastValue)
                this._powerEfficientPlaybackRanges.push({endTimestamp: timestamp});
            else if (lastValue.startTimestamp)
                lastValue.endTimestamp = timestamp;
        }

        this.dispatchEventToListeners(DOMNode.Event.PowerEfficientPlaybackStateChanged, {isPowerEfficient, timestamp});
    }

    canEnterPowerEfficientPlaybackState()
    {
        return this.localName() === "video" || this.nodeName().toLowerCase() === "video";
    }

    _handleDOMNodeDidFireEvent(event)
    {
        if (event.target === this || !event.target.isAncestor(this))
            return;

        let domEvent = Object.shallowCopy(event.data.domEvent);
        domEvent.originator = event.target;

        this._addDOMEvent(domEvent);
    }

    _addDOMEvent(domEvent)
    {
        this._domEvents.push(domEvent);

        this.dispatchEventToListeners(WI.DOMNode.Event.DidFireEvent, {domEvent});
    }

    _setAttributesPayload(attrs)
    {
        this._attributes = [];
        this._attributesMap = new Map;
        for (var i = 0; i < attrs.length; i += 2)
            this._addAttribute(attrs[i], attrs[i + 1]);
    }

    _insertChild(prev, payload)
    {
        var node = new WI.DOMNode(this._domManager, this.ownerDocument, this._isInShadowTree, payload);
        if (!prev) {
            if (!this._children) {
                // First node
                this._children = this._shadowRoots.concat([node]);
            } else
                this._children.unshift(node);
        } else
            this._children.splice(this._children.indexOf(prev) + 1, 0, node);
        this._renumber();
        return node;
    }

    _removeChild(node)
    {
        // FIXME: Handle removal if this is a shadow root.
        if (node.isPseudoElement()) {
            this._pseudoElements.delete(node.pseudoType());
            node.parentNode = null;
        } else {
            this._children.splice(this._children.indexOf(node), 1);
            node.parentNode = null;
            this._renumber();
        }
    }

    _setChildrenPayload(payloads)
    {
        // We set children in the constructor.
        if (this._contentDocument)
            return;

        this._children = this._shadowRoots.slice();
        for (var i = 0; i < payloads.length; ++i) {
            var node = new WI.DOMNode(this._domManager, this.ownerDocument, this._isInShadowTree, payloads[i]);
            this._children.push(node);
        }
        this._renumber();
    }

    _renumber()
    {
        var childNodeCount = this._children.length;
        if (childNodeCount === 0)
            return;

        for (var i = 0; i < childNodeCount; ++i) {
            var child = this._children[i];
            child.index = i;
            child._nextSibling = i + 1 < childNodeCount ? this._children[i + 1] : null;
            child._previousSibling = i - 1 >= 0 ? this._children[i - 1] : null;
            child.parentNode = this;
        }
    }

    _addAttribute(name, value)
    {
        let attr = {name, value, _node: this};
        this._attributesMap.set(name, attr);
        this._attributes.push(attr);
    }

    _setAttribute(name, value)
    {
        let attr = this._attributesMap.get(name);
        if (attr)
            attr.value = value;
        else
            this._addAttribute(name, value);
    }

    _removeAttribute(name)
    {
        let attr = this._attributesMap.get(name);
        if (attr) {
            this._attributes.remove(attr);
            this._attributesMap.delete(name);
        }
    }

    moveTo(targetNode, anchorNode, callback)
    {
        console.assert(!this._destroyed, this);
        if (this._destroyed) {
            callback("ERROR: node is destroyed");
            return;
        }

        let target = WI.assumingMainTarget();
        target.DOMAgent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, this._makeUndoableCallback(callback));
    }

    isXMLNode()
    {
        return !!this.ownerDocument && !!this.ownerDocument.xmlVersion;
    }

    get enabledPseudoClasses()
    {
        return this._enabledPseudoClasses;
    }

    setPseudoClassEnabled(pseudoClass, enabled)
    {
        var pseudoClasses = this._enabledPseudoClasses;
        if (enabled) {
            if (pseudoClasses.includes(pseudoClass))
                return;
            pseudoClasses.push(pseudoClass);
        } else {
            if (!pseudoClasses.includes(pseudoClass))
                return;
            pseudoClasses.remove(pseudoClass);
        }

        function changed(error)
        {
            if (!error)
                this.dispatchEventToListeners(WI.DOMNode.Event.EnabledPseudoClassesChanged);
        }

        let target = WI.assumingMainTarget();
        target.CSSAgent.forcePseudoState(this.id, pseudoClasses, changed.bind(this));
    }

    _makeUndoableCallback(callback)
    {
        return (...args) => {
            if (!args[0]) { // error
                let target = WI.assumingMainTarget();
                if (target.hasCommand("DOM.markUndoableState"))
                    target.DOMAgent.markUndoableState();
            }

            if (callback)
                callback.apply(null, args);
        };
    }

    _idSelector(shouldEscape)
    {
        let id = this.getAttribute("id");
        if (!id)
            return "";

        id = id.trim();
        if (!id.length)
            return "";

        if (shouldEscape)
            id = CSS.escape(id);
        if (/[\s'"]/.test(id))
            return `[id="${id}"]`;

        return `#${id}`;
    }

    _classSelector(shouldEscape) {
        let classes = this.getAttribute("class");
        if (!classes)
            return "";

        classes = classes.trim();
        if (!classes.length)
            return "";

        let foundClasses = new Set;
        return classes.split(/\s+/).reduce((selector, className) => {
            if (!className.length || foundClasses.has(className))
                return selector;

            foundClasses.add(className);
            return `${selector}.${(shouldEscape ? CSS.escape(className) : className)}`;
        }, "");
    }

    _createLayoutOverlayColorSettingIfNeeded()
    {
        if (this._layoutOverlayColorSetting)
            return;

        let defaultConfiguration = WI.DOMNode._defaultLayoutOverlayConfiguration;

        let url = this.ownerDocument.documentURL || WI.networkManager.mainFrame.url;

        let nextColorIndex;
        switch (this._layoutContextType) {
        case WI.DOMNode.LayoutContextType.Grid:
            nextColorIndex = defaultConfiguration.nextGridColorIndex;
            defaultConfiguration.nextGridColorIndex = (nextColorIndex + 1) % defaultConfiguration.colors.length;
            break;

        case WI.DOMNode.LayoutContextType.Flex:
            nextColorIndex = defaultConfiguration.nextFlexColorIndex;
            defaultConfiguration.nextFlexColorIndex = (nextColorIndex + 1) % defaultConfiguration.colors.length;
            break;
        }

        this._layoutOverlayColorSetting = new WI.Setting(`overlay-color-${url.hash}-${this.path().hash}`, defaultConfiguration.colors[nextColorIndex]);
    }

    _handleLayoutOverlaySettingChanged(event)
    {
        if (this._layoutOverlayShowing)
            this.showLayoutOverlay();
    }
};

WI.DOMNode._defaultLayoutOverlayConfiguration = {
    colors: [
        [329, 91, 70],
        [207, 96, 69],
        [92, 90, 64],
        [291, 73, 68],
        [40, 97, 57],
    ],
    nextFlexColorIndex: 0,
    nextGridColorIndex: 0,
};

WI.DOMNode.Event = {
    EnabledPseudoClassesChanged: "dom-node-enabled-pseudo-classes-did-change",
    AttributeModified: "dom-node-attribute-modified",
    AttributeRemoved: "dom-node-attribute-removed",
    EventListenersChanged: "dom-node-event-listeners-changed",
    DidFireEvent: "dom-node-did-fire-event",
    PowerEfficientPlaybackStateChanged: "dom-node-power-efficient-playback-state-changed",
    LayoutContextTypeChanged: "dom-node-layout-context-type-changed",
    LayoutOverlayShown: "dom-node-layout-overlay-shown",
    LayoutOverlayHidden: "dom-node-layout-overlay-hidden",
};

WI.DOMNode.PseudoElementType = {
    Before: "before",
    After: "after",
};

WI.DOMNode.ShadowRootType = {
    UserAgent: "user-agent",
    Closed: "closed",
    Open: "open",
};

WI.DOMNode.CustomElementState = {
    Builtin: "builtin",
    Custom: "custom",
    Waiting: "waiting",
    Failed: "failed",
};

// Corresponds to `CSS.LayoutContextType`.
WI.DOMNode.LayoutContextType = {
    Flex: "flex",
    Grid: "grid",
};
