/*
 * 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.DOMNodeDetailsSidebarPanel = class DOMNodeDetailsSidebarPanel extends WI.DOMDetailsSidebarPanel
{
    constructor()
    {
        super("dom-node-details", WI.UIString("Node"));

        this._eventListenerGroupingMethodSetting = new WI.Setting("dom-node-event-listener-grouping-method", WI.DOMNodeDetailsSidebarPanel.EventListenerGroupingMethod.Event);

        this.element.classList.add("dom-node");

        this._nodeRemoteObject = null;
    }

    // Public

    closed()
    {
        WI.domManager.removeEventListener(null, null, this);

        super.closed();
    }

    // Protected

    initialLayout()
    {
        super.initialLayout();

        WI.domManager.addEventListener(WI.DOMManager.Event.AttributeModified, this._attributesChanged, this);
        WI.domManager.addEventListener(WI.DOMManager.Event.AttributeRemoved, this._attributesChanged, this);
        WI.domManager.addEventListener(WI.DOMManager.Event.CharacterDataModified, this._characterDataModified, this);
        WI.domManager.addEventListener(WI.DOMManager.Event.CustomElementStateChanged, this._customElementStateChanged, this);

        this._identityNodeTypeRow = new WI.DetailsSectionSimpleRow(WI.UIString("Type"));
        this._identityNodeNameRow = new WI.DetailsSectionSimpleRow(WI.UIString("Name"));
        this._identityNodeValueRow = new WI.DetailsSectionSimpleRow(WI.UIString("Value"));
        this._identityNodeContentSecurityPolicyHashRow = new WI.DetailsSectionSimpleRow(WI.UIString("CSP Hash"));

        var identityGroup = new WI.DetailsSectionGroup([this._identityNodeTypeRow, this._identityNodeNameRow, this._identityNodeValueRow, this._identityNodeContentSecurityPolicyHashRow]);
        var identitySection = new WI.DetailsSection("dom-node-identity", WI.UIString("Identity"), [identityGroup]);

        this._attributesDataGridRow = new WI.DetailsSectionDataGridRow(null, WI.UIString("No Attributes"));

        var attributesGroup = new WI.DetailsSectionGroup([this._attributesDataGridRow]);
        var attributesSection = new WI.DetailsSection("dom-node-attributes", WI.UIString("Attributes"), [attributesGroup]);

        this._propertiesRow = new WI.DetailsSectionRow;

        var propertiesGroup = new WI.DetailsSectionGroup([this._propertiesRow]);
        var propertiesSection = new WI.DetailsSection("dom-node-properties", WI.UIString("Properties"), [propertiesGroup]);

        let eventListenersFilterElement = WI.ImageUtilities.useSVGSymbol("Images/FilterFieldGlyph.svg", "filter", WI.UIString("Grouping Method"));

        let eventListenersGroupMethodSelectElement = eventListenersFilterElement.appendChild(document.createElement("select"));
        eventListenersGroupMethodSelectElement.addEventListener("change", (event) => {
            this._eventListenerGroupingMethodSetting.value = eventListenersGroupMethodSelectElement.value;

            this._refreshEventListeners();
        });

        function createOption(text, value) {
            let optionElement = eventListenersGroupMethodSelectElement.appendChild(document.createElement("option"));
            optionElement.value = value;
            optionElement.textContent = text;
        }

        createOption(WI.UIString("Group by Event"), WI.DOMNodeDetailsSidebarPanel.EventListenerGroupingMethod.Event);
        createOption(WI.UIString("Group by Target"), WI.DOMNodeDetailsSidebarPanel.EventListenerGroupingMethod.Target);

        eventListenersGroupMethodSelectElement.value = this._eventListenerGroupingMethodSetting.value;

        this._eventListenersSectionGroup = new WI.DetailsSectionGroup;
        let eventListenersSection = new WI.DetailsSection("dom-node-event-listeners", WI.UIString("Event Listeners"), [this._eventListenersSectionGroup], eventListenersFilterElement);

        this.contentView.element.appendChild(identitySection.element);
        this.contentView.element.appendChild(attributesSection.element);
        this.contentView.element.appendChild(propertiesSection.element);
        this.contentView.element.appendChild(eventListenersSection.element);

        if (WI.sharedApp.hasExtraDomains) {
            if (InspectorBackend.domains.DOM.getDataBindingsForNode) {
                this._dataBindingsSection = new WI.DetailsSection("dom-node-data-bindings", WI.UIString("Data Bindings"), []);
                this.contentView.element.appendChild(this._dataBindingsSection.element);
            }

            if (InspectorBackend.domains.DOM.getAssociatedDataForNode) {
                this._associatedDataGrid = new WI.DetailsSectionRow(WI.UIString("No Associated Data"));

                let associatedDataGroup = new WI.DetailsSectionGroup([this._associatedDataGrid]);

                let associatedSection = new WI.DetailsSection("dom-node-associated-data", WI.UIString("Associated Data"), [associatedDataGroup]);
                this.contentView.element.appendChild(associatedSection.element);
            }
        }

        if (this._accessibilitySupported()) {
            this._accessibilityEmptyRow = new WI.DetailsSectionRow(WI.UIString("No Accessibility Information"));
            this._accessibilityNodeActiveDescendantRow = new WI.DetailsSectionSimpleRow(WI.UIString("Shared Focus"));
            this._accessibilityNodeBusyRow = new WI.DetailsSectionSimpleRow(WI.UIString("Busy"));
            this._accessibilityNodeCheckedRow = new WI.DetailsSectionSimpleRow(WI.UIString("Checked"));
            this._accessibilityNodeChildrenRow = new WI.DetailsSectionSimpleRow(WI.UIString("Children"));
            this._accessibilityNodeControlsRow = new WI.DetailsSectionSimpleRow(WI.UIString("Controls"));
            this._accessibilityNodeCurrentRow = new WI.DetailsSectionSimpleRow(WI.UIString("Current"));
            this._accessibilityNodeDisabledRow = new WI.DetailsSectionSimpleRow(WI.UIString("Disabled"));
            this._accessibilityNodeExpandedRow = new WI.DetailsSectionSimpleRow(WI.UIString("Expanded"));
            this._accessibilityNodeFlowsRow = new WI.DetailsSectionSimpleRow(WI.UIString("Flows"));
            this._accessibilityNodeFocusedRow = new WI.DetailsSectionSimpleRow(WI.UIString("Focused"));
            this._accessibilityNodeHeadingLevelRow = new WI.DetailsSectionSimpleRow(WI.UIString("Heading Level"));
            this._accessibilityNodehierarchyLevelRow = new WI.DetailsSectionSimpleRow(WI.UIString("Hierarchy Level"));
            this._accessibilityNodeIgnoredRow = new WI.DetailsSectionSimpleRow(WI.UIString("Ignored"));
            this._accessibilityNodeInvalidRow = new WI.DetailsSectionSimpleRow(WI.UIString("Invalid"));
            this._accessibilityNodeLiveRegionStatusRow = new WI.DetailsSectionSimpleRow(WI.UIString("Live"));
            this._accessibilityNodeMouseEventRow = new WI.DetailsSectionSimpleRow("");
            this._accessibilityNodeLabelRow = new WI.DetailsSectionSimpleRow(WI.UIString("Label"));
            this._accessibilityNodeOwnsRow = new WI.DetailsSectionSimpleRow(WI.UIString("Owns"));
            this._accessibilityNodeParentRow = new WI.DetailsSectionSimpleRow(WI.UIString("Parent"));
            this._accessibilityNodePressedRow = new WI.DetailsSectionSimpleRow(WI.UIString("Pressed"));
            this._accessibilityNodeReadonlyRow = new WI.DetailsSectionSimpleRow(WI.UIString("Readonly"));
            this._accessibilityNodeRequiredRow = new WI.DetailsSectionSimpleRow(WI.UIString("Required"));
            this._accessibilityNodeRoleRow = new WI.DetailsSectionSimpleRow(WI.UIString("Role"));
            this._accessibilityNodeSelectedRow = new WI.DetailsSectionSimpleRow(WI.UIString("Selected"));
            this._accessibilityNodeSelectedChildrenRow = new WI.DetailsSectionSimpleRow(WI.UIString("Selected Items"));

            this._accessibilityGroup = new WI.DetailsSectionGroup([this._accessibilityEmptyRow]);
            var accessibilitySection = new WI.DetailsSection("dom-node-accessibility", WI.UIString("Accessibility"), [this._accessibilityGroup]);

            this.contentView.element.appendChild(accessibilitySection.element);
        }
    }

    layout()
    {
        super.layout();

        if (!this.domNode)
            return;

        this._refreshIdentity();
        this._refreshAttributes();
        this._refreshProperties();
        this._refreshEventListeners();
        this._refreshDataBindings();
        this._refreshAssociatedData();
        this._refreshAccessibility();
    }

    sizeDidChange()
    {
        super.sizeDidChange();

        // FIXME: <https://webkit.org/b/152269> Web Inspector: Convert DetailsSection classes to use View
        this._attributesDataGridRow.sizeDidChange();
    }

    attached()
    {
        super.attached();

        WI.DOMNode.addEventListener(WI.DOMNode.Event.EventListenersChanged, this._eventListenersChanged, this);
    }

    detached()
    {
        WI.DOMNode.removeEventListener(WI.DOMNode.Event.EventListenersChanged, this._eventListenersChanged, this);

        super.detached();
    }

    // Private

    _accessibilitySupported()
    {
        return window.DOMAgent && DOMAgent.getAccessibilityPropertiesForNode;
    }

    _refreshIdentity()
    {
        const domNode = this.domNode;
        this._identityNodeTypeRow.value = this._nodeTypeDisplayName();
        this._identityNodeNameRow.value = domNode.nodeNameInCorrectCase();
        this._identityNodeValueRow.value = domNode.nodeValue();
        this._identityNodeContentSecurityPolicyHashRow.value = domNode.contentSecurityPolicyHash();
    }

    _refreshAttributes()
    {
        let domNode = this.domNode;
        if (!domNode || !domNode.hasAttributes()) {
            // Remove the DataGrid to show the placeholder text.
            this._attributesDataGridRow.dataGrid = null;
            return;
        }

        let dataGrid = this._attributesDataGridRow.dataGrid;
        if (!dataGrid) {
            const columns = {
                name: {title: WI.UIString("Name"), width: "30%"},
                value: {title: WI.UIString("Value")},
            };
            dataGrid = this._attributesDataGridRow.dataGrid = new WI.DataGrid(columns);
        }

        dataGrid.removeChildren();

        let attributes = domNode.attributes();
        attributes.sort((a, b) => a.name.extendedLocaleCompare(b.name));
        for (let attribute of attributes) {
            let dataGridNode = new WI.EditableDataGridNode(attribute);
            dataGridNode.addEventListener(WI.EditableDataGridNode.Event.ValueChanged, this._attributeNodeValueChanged, this);
            dataGrid.appendChild(dataGridNode);
        }

        dataGrid.updateLayoutIfNeeded();
    }

    _refreshProperties()
    {
        if (this._nodeRemoteObject) {
            this._nodeRemoteObject.release();
            this._nodeRemoteObject = null;
        }

        let domNode = this.domNode;

        const objectGroup = "dom-node-details-sidebar-properties-object-group";
        RuntimeAgent.releaseObjectGroup(objectGroup);

        WI.RemoteObject.resolveNode(domNode, objectGroup).then((object) => {
            // Bail if the DOM node changed while we were waiting for the async response.
            if (this.domNode !== domNode)
                return;

            this._nodeRemoteObject = object;

            function inspectedPage_node_collectPrototypes()
            {
                // This builds an object with numeric properties. This is easier than dealing with arrays
                // with the way RemoteObject works. Start at 1 since we use parseInt later and parseInt
                // returns 0 for non-numeric strings make it ambiguous.
                var prototype = this;
                var result = [];
                var counter = 1;

                while (prototype) {
                    result[counter++] = prototype;
                    prototype = prototype.__proto__;
                }

                return result;
            }

            const args = undefined;
            const generatePreview = false;
            object.callFunction(inspectedPage_node_collectPrototypes, args, generatePreview, nodePrototypesReady.bind(this));
        });

        function nodePrototypesReady(error, object, wasThrown)
        {
            if (error || wasThrown || !object)
                return;

            // Bail if the DOM node changed while we were waiting for the async response.
            if (this.domNode !== domNode)
                return;

            object.deprecatedGetOwnProperties(fillSection.bind(this));
        }

        function fillSection(prototypes)
        {
            if (!prototypes)
                return;

            // Bail if the DOM node changed while we were waiting for the async response.
            if (this.domNode !== domNode)
                return;

            let element = this._propertiesRow.element;
            element.removeChildren();

            let propertyPath = new WI.PropertyPath(this._nodeRemoteObject, "node");

            let initialSection = true;
            for (let i = 0; i < prototypes.length; ++i) {
                // The only values we care about are numeric, as assigned in collectPrototypes.
                if (!parseInt(prototypes[i].name, 10))
                    continue;

                let prototype = prototypes[i].value;
                let prototypeName = prototype.description;
                let title = prototypeName;
                if (/Prototype$/.test(title)) {
                    prototypeName = prototypeName.replace(/Prototype$/, "");
                    title = prototypeName + WI.UIString(" (Prototype)");
                } else if (title === "Object")
                    title = title + WI.UIString(" (Prototype)");

                let mode = initialSection ? WI.ObjectTreeView.Mode.Properties : WI.ObjectTreeView.Mode.PureAPI;
                let objectTree = new WI.ObjectTreeView(prototype, mode, propertyPath);
                objectTree.showOnlyProperties();
                objectTree.setPrototypeNameOverride(prototypeName);

                let detailsSection = new WI.DetailsSection(prototype.description.hash + "-prototype-properties", title, null, null, true);
                detailsSection.groups[0].rows = [new WI.ObjectPropertiesDetailSectionRow(objectTree, detailsSection)];

                element.appendChild(detailsSection.element);

                initialSection = false;
            }
        }
    }

    _refreshEventListeners()
    {
        var domNode = this.domNode;
        if (!domNode)
            return;

        const windowTargetIdentifier = Symbol("window");

        function createEventListenerSection(title, eventListeners, options = {}) {
            let groups = eventListeners.map((eventListener) => new WI.EventListenerSectionGroup(eventListener, options));

            const optionsElement = null;
            const defaultCollapsedSettingValue = true;
            let section = new WI.DetailsSection(`${title}-event-listener-section`, title, groups, optionsElement, defaultCollapsedSettingValue);
            section.element.classList.add("event-listener-section");
            return section;
        }

        function generateGroupsByEvent(eventListeners) {
            let eventListenerTypes = new Map;
            for (let eventListener of eventListeners) {
                console.assert(eventListener.nodeId || eventListener.onWindow);
                if (eventListener.nodeId)
                    eventListener.node = WI.domManager.nodeForId(eventListener.nodeId);

                let eventListenersForType = eventListenerTypes.get(eventListener.type);
                if (!eventListenersForType)
                    eventListenerTypes.set(eventListener.type, eventListenersForType = []);
                eventListenersForType.push(eventListener);
            }

            let rows = [];

            let types = Array.from(eventListenerTypes.keys());
            types.sort();
            for (let type of types)
                rows.push(createEventListenerSection(type, eventListenerTypes.get(type), {hideType: true}));

            return rows;
        }

        function generateGroupsByTarget(eventListeners) {
            let eventListenerTargets = new Map;
            for (let eventListener of eventListeners) {
                console.assert(eventListener.nodeId || eventListener.onWindow);
                if (eventListener.nodeId)
                    eventListener.node = WI.domManager.nodeForId(eventListener.nodeId);

                let target = eventListener.onWindow ? windowTargetIdentifier : eventListener.node;
                let eventListenersForTarget = eventListenerTargets.get(target);
                if (!eventListenersForTarget)
                    eventListenerTargets.set(target, eventListenersForTarget = []);
                eventListenersForTarget.push(eventListener);
            }

            let rows = [];

            function generateSectionForTarget(target) {
                let eventListenersForTarget = eventListenerTargets.get(target);
                if (!eventListenersForTarget)
                    return;

                eventListenersForTarget.sort((a, b) => a.type.toLowerCase().extendedLocaleCompare(b.type.toLowerCase()));

                let title = target === windowTargetIdentifier ? WI.unlocalizedString("window") : target.displayName;

                let section = createEventListenerSection(title, eventListenersForTarget, {hideTarget: true});
                if (target instanceof WI.DOMNode)
                    WI.bindInteractionsForNodeToElement(target, section.titleElement, {ignoreClick: true});
                rows.push(section);
            }

            let currentNode = domNode;
            do {
                generateSectionForTarget(currentNode);
            } while (currentNode = currentNode.parentNode);

            generateSectionForTarget(windowTargetIdentifier);

            return rows;
        }

        function eventListenersCallback(error, eventListeners)
        {
            if (error)
                return;

            // Bail if the DOM node changed while we were waiting for the async response.
            if (this.domNode !== domNode)
                return;

            if (!eventListeners.length) {
                var emptyRow = new WI.DetailsSectionRow(WI.UIString("No Event Listeners"));
                emptyRow.showEmptyMessage();
                this._eventListenersSectionGroup.rows = [emptyRow];
                return;
            }

            switch (this._eventListenerGroupingMethodSetting.value) {
            case WI.DOMNodeDetailsSidebarPanel.EventListenerGroupingMethod.Event:
                this._eventListenersSectionGroup.rows = generateGroupsByEvent.call(this, eventListeners);
                break;

            case WI.DOMNodeDetailsSidebarPanel.EventListenerGroupingMethod.Target:
                this._eventListenersSectionGroup.rows = generateGroupsByTarget.call(this, eventListeners);
                break;
            }
        }

        domNode.getEventListeners(eventListenersCallback.bind(this));
    }

    _refreshDataBindings()
    {
        if (!this._dataBindingsSection)
            return;

        let domNode = this.domNode;
        if (!domNode)
            return;

        DOMAgent.getDataBindingsForNode(this.domNode.id).then(({dataBindings}) => {
            if (this.domNode !== domNode)
                return;

            if (!dataBindings.length) {
                let emptyRow = new WI.DetailsSectionRow(WI.UIString("No Data Bindings"));
                emptyRow.showEmptyMessage();
                this._dataBindingsSection.groups = [new WI.DetailsSectionGroup([emptyRow])];
                return;
            }

            let groups = [];
            for (let {binding, type, value} of dataBindings) {
                groups.push(new WI.DetailsSectionGroup([
                    new WI.DetailsSectionSimpleRow(WI.UIString("Binding"), binding),
                    new WI.DetailsSectionSimpleRow(WI.UIString("Type"), type),
                    new WI.DetailsSectionSimpleRow(WI.UIString("Value"), value),
                ]));
            }
            this._dataBindingsSection.groups = groups;
        });
    }

    _refreshAssociatedData()
    {
        if (!this._associatedDataGrid)
            return;

        const objectGroup = "dom-node-details-sidebar-associated-data-object-group";
        RuntimeAgent.releaseObjectGroup(objectGroup);

        let domNode = this.domNode;
        if (!domNode)
            return;

        DOMAgent.getAssociatedDataForNode(domNode.id).then(({associatedData}) => {
            if (this.domNode !== domNode)
                return;

            if (!associatedData) {
                this._associatedDataGrid.showEmptyMessage();
                return;
            }

            let expression = associatedData;
            const options = {
                objectGroup,
                doNotPauseOnExceptionsAndMuteConsole: true,
            };
            WI.runtimeManager.evaluateInInspectedWindow(expression, options, (result, wasThrown) => {
                console.assert(!wasThrown);

                if (!result) {
                    this._associatedDataGrid.showEmptyMessage();
                    return;
                }

                this._associatedDataGrid.hideEmptyMessage();

                const propertyPath = null;
                const forceExpanding = true;
                let element = WI.FormattedValue.createObjectTreeOrFormattedValueForRemoteObject(result, propertyPath, forceExpanding);

                let objectTree = element.__objectTree;
                if (objectTree) {
                    objectTree.showOnlyJSON();
                    objectTree.expand();
                }

                this._associatedDataGrid.element.appendChild(element);
            });
        });
    }

    _refreshAccessibility()
    {
        if (!this._accessibilitySupported())
            return;

        var domNode = this.domNode;
        if (!domNode)
            return;

        var properties = {};

        function booleanValueToLocalizedStringIfTrue(property) {
            if (properties[property])
                return WI.UIString("Yes");
            return "";
        }

        function booleanValueToLocalizedStringIfPropertyDefined(property) {
            if (properties[property] !== undefined) {
                if (properties[property])
                    return WI.UIString("Yes");
                else
                    return WI.UIString("No");
            }
            return "";
        }

        function linkForNodeId(nodeId) {
            var link = null;
            if (nodeId !== undefined && typeof nodeId === "number") {
                var node = WI.domManager.nodeForId(nodeId);
                if (node)
                    link = WI.linkifyAccessibilityNodeReference(node);
            }
            return link;
        }

        function linkListForNodeIds(nodeIds) {
            if (!nodeIds)
                return null;

            const itemsToShow = 5;
            let hasLinks = false;
            let listItemCount = 0;
            let container = document.createElement("div");
            container.classList.add("list-container");
            let linkList = container.createChild("ul", "node-link-list");
            let initiallyHiddenItems = [];
            for (let nodeId of nodeIds) {
                let node = WI.domManager.nodeForId(nodeId);
                if (!node)
                    continue;
                let link = WI.linkifyAccessibilityNodeReference(node);
                hasLinks = true;
                let li = linkList.createChild("li");
                li.appendChild(link);
                if (listItemCount >= itemsToShow) {
                    li.hidden = true;
                    initiallyHiddenItems.push(li);
                }
                listItemCount++;
            }
            container.appendChild(linkList);
            if (listItemCount > itemsToShow) {
                let moreNodesButton = container.createChild("button", "expand-list-button");
                moreNodesButton.textContent = WI.UIString("%d More\u2026").format(listItemCount - itemsToShow);
                moreNodesButton.addEventListener("click", () => {
                    initiallyHiddenItems.forEach((element) => { element.hidden = false; });
                    moreNodesButton.remove();
                });
            }
            if (hasLinks)
                return container;

            return null;
        }

        function accessibilityPropertiesCallback(accessibilityProperties) {
            if (this.domNode !== domNode)
                return;

            // Make sure the current set of properties is available in the closure scope for the helper functions.
            properties = accessibilityProperties;

            if (accessibilityProperties && accessibilityProperties.exists) {

                var activeDescendantLink = linkForNodeId(accessibilityProperties.activeDescendantNodeId);
                var busy = booleanValueToLocalizedStringIfPropertyDefined("busy");

                var checked = "";
                if (accessibilityProperties.checked !== undefined) {
                    if (accessibilityProperties.checked === DOMAgent.AccessibilityPropertiesChecked.True)
                        checked = WI.UIString("Yes");
                    else if (accessibilityProperties.checked === DOMAgent.AccessibilityPropertiesChecked.Mixed)
                        checked = WI.UIString("Mixed");
                    else // DOMAgent.AccessibilityPropertiesChecked.False
                        checked = WI.UIString("No");
                }

                // Accessibility tree children are not a 1:1 mapping with DOM tree children.
                var childNodeLinkList = linkListForNodeIds(accessibilityProperties.childNodeIds);
                var controlledNodeLinkList = linkListForNodeIds(accessibilityProperties.controlledNodeIds);

                var current = "";
                switch (accessibilityProperties.current) {
                case DOMAgent.AccessibilityPropertiesCurrent.True:
                    current = WI.UIString("True");
                    break;
                case DOMAgent.AccessibilityPropertiesCurrent.Page:
                    current = WI.UIString("Page");
                    break;
                case DOMAgent.AccessibilityPropertiesCurrent.Location:
                    current = WI.UIString("Location");
                    break;
                case DOMAgent.AccessibilityPropertiesCurrent.Step:
                    current = WI.UIString("Step");
                    break;
                case DOMAgent.AccessibilityPropertiesCurrent.Date:
                    current = WI.UIString("Date");
                    break;
                case DOMAgent.AccessibilityPropertiesCurrent.Time:
                    current = WI.UIString("Time");
                    break;
                default:
                    current = "";
                }

                var disabled = booleanValueToLocalizedStringIfTrue("disabled");
                var expanded = booleanValueToLocalizedStringIfPropertyDefined("expanded");
                var flowedNodeLinkList = linkListForNodeIds(accessibilityProperties.flowedNodeIds);
                var focused = booleanValueToLocalizedStringIfPropertyDefined("focused");

                var ignored = "";
                if (accessibilityProperties.ignored) {
                    ignored = WI.UIString("Yes");
                    if (accessibilityProperties.hidden)
                        ignored = WI.UIString("%s (hidden)").format(ignored);
                    else if (accessibilityProperties.ignoredByDefault)
                        ignored = WI.UIString("%s (default)").format(ignored);
                }

                var invalid = "";
                if (accessibilityProperties.invalid === DOMAgent.AccessibilityPropertiesInvalid.True)
                    invalid = WI.UIString("Yes");
                else if (accessibilityProperties.invalid === DOMAgent.AccessibilityPropertiesInvalid.Grammar)
                    invalid = WI.UIString("Grammar");
                else if (accessibilityProperties.invalid === DOMAgent.AccessibilityPropertiesInvalid.Spelling)
                    invalid = WI.UIString("Spelling");

                var label = accessibilityProperties.label;

                var liveRegionStatus = "";
                var liveRegionStatusNode = null;
                var liveRegionStatusToken = accessibilityProperties.liveRegionStatus;
                switch (liveRegionStatusToken) {
                case DOMAgent.AccessibilityPropertiesLiveRegionStatus.Assertive:
                    liveRegionStatus = WI.UIString("Assertive");
                    break;
                case DOMAgent.AccessibilityPropertiesLiveRegionStatus.Polite:
                    liveRegionStatus = WI.UIString("Polite");
                    break;
                default:
                    liveRegionStatus = "";
                }
                if (liveRegionStatus) {
                    var liveRegionRelevant = accessibilityProperties.liveRegionRelevant;
                    // Append @aria-relevant values. E.g. "Live: Assertive (Additions, Text)".
                    if (liveRegionRelevant && liveRegionRelevant.length) {
                        // @aria-relevant="all" is exposed as ["additions","removals","text"], in order.
                        // This order is controlled in WebCore and expected in WebInspectorUI.
                        if (liveRegionRelevant.length === 3
                            && liveRegionRelevant[0] === DOMAgent.LiveRegionRelevant.Additions
                            && liveRegionRelevant[1] === DOMAgent.LiveRegionRelevant.Removals
                            && liveRegionRelevant[2] === DOMAgent.LiveRegionRelevant.Text)
                            liveRegionRelevant = [WI.UIString("All Changes")];
                        else {
                            // Reassign localized strings in place: ["additions","text"] becomes ["Additions","Text"].
                            liveRegionRelevant = liveRegionRelevant.map(function(value) {
                                switch (value) {
                                case DOMAgent.LiveRegionRelevant.Additions:
                                    return WI.UIString("Additions");
                                case DOMAgent.LiveRegionRelevant.Removals:
                                    return WI.UIString("Removals");
                                case DOMAgent.LiveRegionRelevant.Text:
                                    return WI.UIString("Text");
                                default: // If WebCore sends a new unhandled value, display as a String.
                                    return "\"" + value + "\"";
                                }
                            });
                        }
                        liveRegionStatus += " (" + liveRegionRelevant.join(", ") + ")";
                    }
                    // Clarify @aria-atomic if necessary.
                    if (accessibilityProperties.liveRegionAtomic) {
                        liveRegionStatusNode = document.createElement("div");
                        liveRegionStatusNode.className = "value-with-clarification";
                        liveRegionStatusNode.setAttribute("role", "text");
                        liveRegionStatusNode.append(liveRegionStatus);
                        var clarificationNode = document.createElement("div");
                        clarificationNode.className = "clarification";
                        clarificationNode.append(WI.UIString("Region announced in its entirety."));
                        liveRegionStatusNode.appendChild(clarificationNode);
                    }
                }

                var mouseEventNodeId = accessibilityProperties.mouseEventNodeId;
                var mouseEventTextValue = "";
                var mouseEventNodeLink = null;
                if (mouseEventNodeId) {
                    if (mouseEventNodeId === accessibilityProperties.nodeId)
                        mouseEventTextValue = WI.UIString("Yes");
                    else
                        mouseEventNodeLink = linkForNodeId(mouseEventNodeId);
                }

                var ownedNodeLinkList = linkListForNodeIds(accessibilityProperties.ownedNodeIds);

                // Accessibility tree parent is not a 1:1 mapping with the DOM tree parent.
                var parentNodeLink = linkForNodeId(accessibilityProperties.parentNodeId);

                var pressed = booleanValueToLocalizedStringIfPropertyDefined("pressed");
                var readonly = booleanValueToLocalizedStringIfTrue("readonly");
                var required = booleanValueToLocalizedStringIfPropertyDefined("required");

                var role = accessibilityProperties.role;
                let hasPopup = accessibilityProperties.isPopupButton;
                let roleType = null;
                let buttonType = null;
                let buttonTypePopupString = WI.UIString("popup");
                let buttonTypeToggleString = WI.UIString("toggle");
                let buttonTypePopupToggleString = WI.UIString("popup, toggle");

                if (role === "" || role === "unknown")
                    role = WI.UIString("No matching ARIA role");
                else if (role) {
                    if (role === "button") {
                        if (pressed)
                            buttonType = buttonTypeToggleString;

                        // In cases where an element is a toggle button, but it also has
                        // aria-haspopup, we concatenate the button types. If it is just
                        // a popup button, we only include "popup".
                        if (hasPopup)
                            buttonType = buttonType ? buttonTypePopupToggleString : buttonTypePopupString;
                    }

                    if (!domNode.getAttribute("role"))
                        roleType = WI.UIString("default");
                    else if (buttonType || domNode.getAttribute("role") !== role)
                        roleType = WI.UIString("computed");

                    if (buttonType && roleType)
                        role = WI.UIString("%s (%s, %s)").format(role, buttonType, roleType);
                    else if (roleType || buttonType) {
                        let extraInfo = roleType || buttonType;
                        role = WI.UIString("%s (%s)").format(role, extraInfo);
                    }
                }

                var selected = booleanValueToLocalizedStringIfTrue("selected");
                var selectedChildNodeLinkList = linkListForNodeIds(accessibilityProperties.selectedChildNodeIds);

                var headingLevel = accessibilityProperties.headingLevel;
                var hierarchyLevel = accessibilityProperties.hierarchyLevel;
                // Assign all the properties to their respective views.
                this._accessibilityNodeActiveDescendantRow.value = activeDescendantLink || "";
                this._accessibilityNodeBusyRow.value = busy;
                this._accessibilityNodeCheckedRow.value = checked;
                this._accessibilityNodeChildrenRow.value = childNodeLinkList || "";
                this._accessibilityNodeControlsRow.value = controlledNodeLinkList || "";
                this._accessibilityNodeCurrentRow.value = current;
                this._accessibilityNodeDisabledRow.value = disabled;
                this._accessibilityNodeExpandedRow.value = expanded;
                this._accessibilityNodeFlowsRow.value = flowedNodeLinkList || "";
                this._accessibilityNodeFocusedRow.value = focused;
                this._accessibilityNodeHeadingLevelRow.value = headingLevel || "";
                this._accessibilityNodehierarchyLevelRow.value = hierarchyLevel || "";
                this._accessibilityNodeIgnoredRow.value = ignored;
                this._accessibilityNodeInvalidRow.value = invalid;
                this._accessibilityNodeLabelRow.value = label;
                this._accessibilityNodeLiveRegionStatusRow.value = liveRegionStatusNode || liveRegionStatus;

                // Row label changes based on whether the value is a delegate node link.
                this._accessibilityNodeMouseEventRow.label = mouseEventNodeLink ? WI.UIString("Click Listener") : WI.UIString("Clickable");
                this._accessibilityNodeMouseEventRow.value = mouseEventNodeLink || mouseEventTextValue;

                this._accessibilityNodeOwnsRow.value = ownedNodeLinkList || "";
                this._accessibilityNodeParentRow.value = parentNodeLink || "";
                this._accessibilityNodePressedRow.value = pressed;
                this._accessibilityNodeReadonlyRow.value = readonly;
                this._accessibilityNodeRequiredRow.value = required;
                this._accessibilityNodeRoleRow.value = role;
                this._accessibilityNodeSelectedRow.value = selected;

                this._accessibilityNodeSelectedChildrenRow.label = WI.UIString("Selected Items");
                this._accessibilityNodeSelectedChildrenRow.value = selectedChildNodeLinkList || "";
                if (selectedChildNodeLinkList && accessibilityProperties.selectedChildNodeIds.length === 1)
                    this._accessibilityNodeSelectedChildrenRow.label = WI.UIString("Selected Item");

                // Display order, not alphabetical as above.
                this._accessibilityGroup.rows = [
                    // Global properties for all elements.
                    this._accessibilityNodeIgnoredRow,
                    this._accessibilityNodeRoleRow,
                    this._accessibilityNodeLabelRow,
                    this._accessibilityNodeParentRow,
                    this._accessibilityNodeActiveDescendantRow,
                    this._accessibilityNodeSelectedChildrenRow,
                    this._accessibilityNodeChildrenRow,
                    this._accessibilityNodeOwnsRow,
                    this._accessibilityNodeControlsRow,
                    this._accessibilityNodeFlowsRow,
                    this._accessibilityNodeMouseEventRow,
                    this._accessibilityNodeFocusedRow,
                    this._accessibilityNodeHeadingLevelRow,
                    this._accessibilityNodehierarchyLevelRow,
                    this._accessibilityNodeBusyRow,
                    this._accessibilityNodeLiveRegionStatusRow,
                    this._accessibilityNodeCurrentRow,

                    // Properties exposed for all input-type elements.
                    this._accessibilityNodeDisabledRow,
                    this._accessibilityNodeInvalidRow,
                    this._accessibilityNodeRequiredRow,

                    // Role-specific properties.
                    this._accessibilityNodeCheckedRow,
                    this._accessibilityNodeExpandedRow,
                    this._accessibilityNodePressedRow,
                    this._accessibilityNodeReadonlyRow,
                    this._accessibilityNodeSelectedRow
                ];

                this._accessibilityEmptyRow.hideEmptyMessage();

            } else {
                this._accessibilityGroup.rows = [this._accessibilityEmptyRow];
                this._accessibilityEmptyRow.showEmptyMessage();
            }
        }

        domNode.accessibilityProperties(accessibilityPropertiesCallback.bind(this));
    }

    _eventListenersChanged(event)
    {
        if (event.target === this.domNode || event.target.isAncestor(this.domNode))
            this._refreshEventListeners();
    }

    _attributesChanged(event)
    {
        if (event.data.node !== this.domNode)
            return;
        this._refreshAttributes();
        this._refreshAccessibility();
        this._refreshDataBindings();
    }

    _attributeNodeValueChanged(event)
    {
        let change = event.data;
        let data = event.target.data;

        if (change.columnIdentifier === "name") {
            this.domNode.removeAttribute(data[change.columnIdentifier], (error) => {
                this.domNode.setAttribute(change.value, `${change.value}="${data.value}"`);
            });
        } else if (change.columnIdentifier === "value")
            this.domNode.setAttributeValue(data.name, change.value);
    }

    _characterDataModified(event)
    {
        if (event.data.node !== this.domNode)
            return;
        this._identityNodeValueRow.value = this.domNode.nodeValue();
    }

    _customElementStateChanged(event)
    {
        if (event.data.node !== this.domNode)
            return;
        this._refreshIdentity();
    }

    _nodeTypeDisplayName()
    {
        switch (this.domNode.nodeType()) {
        case Node.ELEMENT_NODE: {
            const nodeName = WI.UIString("Element");
            const state = this._customElementState();
            return state === null ? nodeName : `${nodeName} (${state})`;
        }
        case Node.TEXT_NODE:
            return WI.UIString("Text Node");
        case Node.COMMENT_NODE:
            return WI.UIString("Comment");
        case Node.DOCUMENT_NODE:
            return WI.UIString("Document");
        case Node.DOCUMENT_TYPE_NODE:
            return WI.UIString("Document Type");
        case Node.DOCUMENT_FRAGMENT_NODE:
            return WI.UIString("Document Fragment");
        case Node.CDATA_SECTION_NODE:
            return WI.UIString("Character Data");
        case Node.PROCESSING_INSTRUCTION_NODE:
            return WI.UIString("Processing Instruction");
        default:
            console.error("Unknown DOM node type: ", this.domNode.nodeType());
            return this.domNode.nodeType();
        }
    }

    _customElementState()
    {
        const state = this.domNode.customElementState();
        switch (state) {
        case WI.DOMNode.CustomElementState.Builtin:
            return null;
        case WI.DOMNode.CustomElementState.Custom:
            return WI.UIString("Custom");
        case WI.DOMNode.CustomElementState.Waiting:
            return WI.UIString("Undefined custom element");
        case WI.DOMNode.CustomElementState.Failed:
            return WI.UIString("Failed to upgrade");
        }
        console.error("Unknown DOM custom element state: ", state);
        return null;
    }
};

WI.DOMNodeDetailsSidebarPanel.EventListenerGroupingMethod = {
    Event: "event",
    Target: "target",
};
