/*
 * 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) {
            let target = WI.assumingMainTarget();
            if (target.hasCommand("DOM.getDataBindingsForNode")) {
                this._dataBindingsSection = new WI.DetailsSection("dom-node-data-bindings", WI.UIString("Data Bindings"), []);
                this.contentView.element.appendChild(this._dataBindingsSection.element);
            }
            if (target.hasCommand("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 InspectorBackend.hasCommand("DOM.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 target = WI.assumingMainTarget();

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

        let domNode = this.domNode;
        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.getPropertyDescriptors(fillSection.bind(this), {ownProperties: true});
        }

        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));

            let optionsElement = null;
            if ((WI.DOMManager.supportsDisablingEventListeners() || WI.DOMManager.supportsEventListenerBreakpoints()) && groups.some((group) => group.supportsStateModification)) {
                optionsElement = WI.ImageUtilities.useSVGSymbol("Images/Gear.svg", "event-listener-options", WI.UIString("Options"));
                WI.addMouseDownContextMenuHandlers(optionsElement, (contextMenu) => {
                    if (WI.DOMManager.supportsDisablingEventListeners()) {
                        let shouldDisable = groups.some((eventListener) => !eventListener.isEventListenerDisabled);
                        contextMenu.appendItem(shouldDisable ? WI.UIString("Disable Event Listeners") : WI.UIString("Enable Event Listeners"), () => {
                            for (let group of groups)
                                group.isEventListenerDisabled = shouldDisable;
                        });
                    }

                    if (WI.DOMManager.supportsEventListenerBreakpoints()) {
                        let shouldBreakpoint = groups.some((eventListener) => !eventListener.hasEventListenerBreakpoint);
                        contextMenu.appendItem(shouldBreakpoint ? WI.UIString("Add Breakpoints") : WI.UIString("Delete Breakpoints"), () => {
                            for (let group of groups)
                                group.hasEventListenerBreakpoint = shouldBreakpoint;
                        });
                    }
                });
            }

            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;

        let target = WI.assumingMainTarget();
        target.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;

        let target = WI.assumingMainTarget();

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

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

        target.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 === InspectorBackend.Enum.DOM.AccessibilityPropertiesChecked.True)
                        checked = WI.UIString("Yes");
                    else if (accessibilityProperties.checked === InspectorBackend.Enum.DOM.AccessibilityPropertiesChecked.Mixed)
                        checked = WI.UIString("Mixed");
                    else // InspectorBackend.Enum.DOM.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 InspectorBackend.Enum.DOM.AccessibilityPropertiesCurrent.True:
                    current = WI.UIString("True");
                    break;
                case InspectorBackend.Enum.DOM.AccessibilityPropertiesCurrent.Page:
                    current = WI.UIString("Page");
                    break;
                case InspectorBackend.Enum.DOM.AccessibilityPropertiesCurrent.Location:
                    current = WI.UIString("Location");
                    break;
                case InspectorBackend.Enum.DOM.AccessibilityPropertiesCurrent.Step:
                    current = WI.UIString("Step");
                    break;
                case InspectorBackend.Enum.DOM.AccessibilityPropertiesCurrent.Date:
                    current = WI.UIString("Date");
                    break;
                case InspectorBackend.Enum.DOM.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 === InspectorBackend.Enum.DOM.AccessibilityPropertiesInvalid.True)
                    invalid = WI.UIString("Yes");
                else if (accessibilityProperties.invalid === InspectorBackend.Enum.DOM.AccessibilityPropertiesInvalid.Grammar)
                    invalid = WI.UIString("Grammar");
                else if (accessibilityProperties.invalid === InspectorBackend.Enum.DOM.AccessibilityPropertiesInvalid.Spelling)
                    invalid = WI.UIString("Spelling");

                var label = accessibilityProperties.label;

                var liveRegionStatus = "";
                var liveRegionStatusNode = null;
                var liveRegionStatusToken = accessibilityProperties.liveRegionStatus;
                switch (liveRegionStatusToken) {
                case InspectorBackend.Enum.DOM.AccessibilityPropertiesLiveRegionStatus.Assertive:
                    liveRegionStatus = WI.UIString("Assertive");
                    break;
                case InspectorBackend.Enum.DOM.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] === InspectorBackend.Enum.DOM.LiveRegionRelevant.Additions
                            && liveRegionRelevant[1] === InspectorBackend.Enum.DOM.LiveRegionRelevant.Removals
                            && liveRegionRelevant[2] === InspectorBackend.Enum.DOM.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 InspectorBackend.Enum.DOM.LiveRegionRelevant.Additions:
                                    return WI.UIString("Additions");
                                case InspectorBackend.Enum.DOM.LiveRegionRelevant.Removals:
                                    return WI.UIString("Removals");
                                case InspectorBackend.Enum.DOM.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",
};
