/*
 * Copyright (C) 2011 Google Inc.  All rights reserved.
 * Copyright (C) 2007, 2008, 2013-2015 Apple Inc.  All rights reserved.
 * Copyright (C) 2009 Joseph Pecoraro
 *
 * 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.
 * 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE 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 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.ConsoleMessageView = class ConsoleMessageView extends WI.Object
{
    constructor(message)
    {
        super();

        console.assert(message instanceof WI.ConsoleMessage);

        this._message = message;
        this._expandable = false;
        this._repeatCount = message._repeatCount || 0;

        // These are the parameters unused by the messages's optional format string.
        // Any extra parameters will be displayed as children of this message.
        this._extraParameters = message.parameters;
    }

    // Public

    render()
    {
        console.assert(!this._element);
        this._element = document.createElement("div");
        this._element.classList.add("console-message");
        this._element.dir = "ltr";

        // FIXME: <https://webkit.org/b/143545> Web Inspector: LogContentView should use higher level objects
        this._element.__message = this._message;
        this._element.__messageView = this;

        if (this._message.type === WI.ConsoleMessage.MessageType.Result) {
            this._element.classList.add("console-user-command-result");
            this._element.setAttribute("data-labelprefix", WI.UIString("Output: "));
        } else if (this._message.type === WI.ConsoleMessage.MessageType.StartGroup || this._message.type === WI.ConsoleMessage.MessageType.StartGroupCollapsed)
            this._element.classList.add("console-group-title");

        switch (this._message.level) {
        case WI.ConsoleMessage.MessageLevel.Log:
            this._element.classList.add("console-log-level");
            this._element.setAttribute("data-labelprefix", WI.UIString("Log: "));
            break;
        case WI.ConsoleMessage.MessageLevel.Info:
            this._element.classList.add("console-info-level");
            this._element.setAttribute("data-labelprefix", WI.UIString("Info: "));
            break;
        case WI.ConsoleMessage.MessageLevel.Debug:
            this._element.classList.add("console-debug-level");
            this._element.setAttribute("data-labelprefix", WI.UIString("Debug: "));
            break;
        case WI.ConsoleMessage.MessageLevel.Warning:
            this._element.classList.add("console-warning-level");
            this._element.setAttribute("data-labelprefix", WI.UIString("Warning: "));
            break;
        case WI.ConsoleMessage.MessageLevel.Error:
            this._element.classList.add("console-error-level");
            this._element.setAttribute("data-labelprefix", WI.UIString("Error: "));
            break;
        }

        // FIXME: The location link should include stack trace information.
        this._appendLocationLink();

        this._messageBodyElement = this._element.appendChild(document.createElement("span"));
        this._messageBodyElement.classList.add("console-top-level-message", "console-message-body");
        this._appendMessageTextAndArguments(this._messageBodyElement);
        this._appendSavedResultIndex();

        this._appendExtraParameters();
        this._appendStackTrace();

        this._renderRepeatCount();

        if (this._message.type === WI.ConsoleMessage.MessageType.Dir)
            this.expand();
        else if (this._message.type === WI.ConsoleMessage.MessageType.Image) {
            this._element.classList.add("console-image");
            this._element.addEventListener("contextmenu", this._handleContextMenu.bind(this));
        }

        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BlackboxChanged, this._handleDebuggerBlackboxChanged, this);
    }

    get element()
    {
        return this._element;
    }

    get message()
    {
        return this._message;
    }

    get repeatCount()
    {
        return this._repeatCount;
    }

    set repeatCount(count)
    {
        console.assert(typeof count === "number");

        if (this._repeatCount === count)
            return;

        this._repeatCount = count;

        if (this._element)
            this._renderRepeatCount();
    }

    _renderRepeatCount()
    {
        let count = this._repeatCount;

        if (count <= 1) {
            if (this._repeatCountElement) {
                this._repeatCountElement.remove();
                this._repeatCountElement = null;
            }
            return;
        }

        if (!this._repeatCountElement) {
            this._repeatCountElement = document.createElement("span");
            this._repeatCountElement.classList.add("repeat-count");
            this._element.insertBefore(this._repeatCountElement, this._element.firstChild);
        }

        this._repeatCountElement.textContent = Number.abbreviate(count);
    }

    get expandable()
    {
        // There are extra arguments or a call stack that can be shown.
        if (this._expandable)
            return true;

        // There is an object tree that could be expanded.
        if (this._objectTree)
            return true;

        return false;
    }

    expand()
    {
        if (this._expandable)
            this._element.classList.add("expanded");

        // Auto-expand an inner object tree if there is a single object.
        // For Trace messages we are auto-expanding for the call stack, don't also auto-expand an object as well.
        if (this._objectTree && this._message.type !== WI.ConsoleMessage.MessageType.Trace) {
            if (!this._extraParameters || this._extraParameters.length <= 1)
                this._objectTree.expand();
        }
    }

    collapse()
    {
        if (this._expandable)
            this._element.classList.remove("expanded");

        // Collapse the object tree just in cases where it was autoexpanded.
        if (this._objectTree) {
            if (!this._extraParameters || this._extraParameters.length <= 1)
                this._objectTree.collapse();
        }
    }

    toggle()
    {
        if (this._element.classList.contains("expanded"))
            this.collapse();
        else
            this.expand();
    }

    toClipboardString(isPrefixOptional)
    {
        let clipboardString = this._messageBodyElement.innerText.removeWordBreakCharacters();
        if (this._message.savedResultIndex) {
            let escapedSavedResultPrefix = WI.RuntimeManager.preferredSavedResultPrefix().escapeForRegExp();
            clipboardString = clipboardString.replace(new RegExp(`\\s*=\\s*${escapedSavedResultPrefix}\\d+\\s*$`), "");
        }

        let hasStackTrace = this._shouldShowStackTrace();
        if (!hasStackTrace) {
            let repeatString = this.repeatCount > 1 ? "x" + this.repeatCount : "";
            let urlLine = "";
            if (this._message.url) {
                let components = [WI.displayNameForURL(this._message.url), "line " + this._message.line];
                if (repeatString)
                    components.push(repeatString);
                urlLine = " (" + components.join(", ") + ")";
            } else if (repeatString)
                urlLine = " (" + repeatString + ")";

            if (urlLine) {
                let lines = clipboardString.split("\n");
                lines[0] += urlLine;
                clipboardString = lines.join("\n");
            }
        }

        if (this._extraElementsList)
            clipboardString += "\n" + this._extraElementsList.innerText.removeWordBreakCharacters().trim();

        if (hasStackTrace) {
            this._message.stackTrace.callFrames.forEach(function(frame) {
                clipboardString += "\n\t" + (frame.functionName || WI.UIString("(anonymous function)"));
                if (frame.sourceCodeLocation)
                    clipboardString += " (" + frame.sourceCodeLocation.originalLocationString() + ")";
            });
        }

        if (!isPrefixOptional || this._enforcesClipboardPrefixString())
            return this._clipboardPrefixString() + clipboardString;
        return clipboardString;
    }

    clearSessionState()
    {
        for (let node of this._messageBodyElement.querySelectorAll(".console-saved-variable"))
            node.remove();

        if (this._objectTree instanceof WI.ObjectTreeView)
            this._objectTree.resetPropertyPath();

        // FIXME: <https://webkit.org/b/196956> Web Inspector: use weak collections for holding event listeners
        WI.settings.consoleSavedResultAlias.removeEventListener(null, null, this);

        WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.BlackboxChanged, this._handleDebuggerBlackboxChanged, this);
    }

    // Private

    _appendMessageTextAndArguments(element)
    {
        if (this._message.source === WI.ConsoleMessage.MessageSource.ConsoleAPI) {
            switch (this._message.type) {
            case WI.ConsoleMessage.MessageType.Trace:
                var args = [WI.UIString("Trace")];
                if (this._message.parameters) {
                    if (this._message.parameters[0].type === "string") {
                        var prefixedFormatString = WI.UIString("Trace: %s").format(this._message.parameters[0].description);
                        args = [prefixedFormatString].concat(this._message.parameters.slice(1));
                    } else
                        args.pushAll(this._message.parameters);
                }
                this._appendFormattedArguments(element, args);
                return;

            case WI.ConsoleMessage.MessageType.Assert:
                var args = [WI.UIString("Assertion Failed")];
                if (this._message.parameters) {
                    if (this._message.parameters[0].type === "string") {
                        var prefixedFormatString = WI.UIString("Assertion Failed: %s").format(this._message.parameters[0].description);
                        args = [prefixedFormatString].concat(this._message.parameters.slice(1));
                    } else
                        args.pushAll(this._message.parameters);
                }
                this._appendFormattedArguments(element, args);
                return;

            case WI.ConsoleMessage.MessageType.Dir:
                var obj = this._message.parameters ? this._message.parameters[0] : undefined;
                this._appendFormattedArguments(element, ["%O", obj]);
                return;

            case WI.ConsoleMessage.MessageType.Table:
                var args = this._message.parameters;
                element.appendChild(this._formatParameterAsTable(args));
                this._extraParameters = null;
                return;

            case WI.ConsoleMessage.MessageType.StartGroup:
            case WI.ConsoleMessage.MessageType.StartGroupCollapsed:
                var args = this._message.parameters || [this._message.messageText || WI.UIString("Group")];
                this._formatWithSubstitutionString(args, element);
                this._extraParameters = null;
                return;

            case WI.ConsoleMessage.MessageType.Timing: {
                let args = [this._message.messageText];
                if (this._extraParameters)
                    args.pushAll(this._extraParameters);
                this._appendFormattedArguments(element, args);
                return;
            }

            case WI.ConsoleMessage.MessageType.Image: {
                if (this._message.level === WI.ConsoleMessage.MessageLevel.Log) {
                    let divider = null;

                    if (this._message.parameters.length > 1) {
                        this._appendFormattedArguments(element, this._message.parameters.slice(1));

                        divider = element.appendChild(document.createElement("hr"));
                    }

                    let target = this._message.parameters[0];
                    if (target === "Viewport")
                        target = WI.UIString("Viewport");
                    this._appendFormattedArguments(element, [target]);

                    if (this._message.messageText) {
                        let img = document.createElement("img");
                        img.classList.add("show-grid");
                        img.src = this._message.messageText;
                        img.setAttribute("filename", WI.FileUtilities.screenshotString() + ".png");
                        img.addEventListener("load", (event) => {
                            if (img.width >= img.height)
                                img.width = img.width / window.devicePixelRatio;
                            else
                                img.height = img.height / window.devicePixelRatio;
                            element.appendChild(img);
                        });
                        img.addEventListener("error", (event) => {
                            this._element.setAttribute("data-labelprefix", WI.UIString("Error: "));
                            this._element.classList.add("console-error-level");
                            this._element.classList.remove("console-log-level");

                            if (divider) {
                                while (divider.nextSibling)
                                    divider.nextSibling.remove();
                            } else
                                element.removeChildren();

                            let args = [WI.UIString("Could not capture screenshot"), this._message.messageText];
                            if (this._extraParameters)
                                args.pushAll(this._extraParameters);
                            this._appendFormattedArguments(element, args);
                        });
                    }
                    return;
                }

                if (this._message.level === WI.ConsoleMessage.MessageLevel.Error) {
                    let args = [];
                    if (this._message.messageText === "Could not capture screenshot")
                        args.push(WI.UIString("Could not capture screenshot"));
                    else
                        args.push(this._message.messageText);
                    if (this._extraParameters)
                        args.pushAll(this._extraParameters);
                    this._appendFormattedArguments(element, args);
                    return;
                }

                console.assert();
                break;
            }
            }
        }

        // FIXME: Better handle WI.ConsoleMessage.MessageSource.Network once it has request info.

        var args = this._message.parameters || [this._message.messageText];
        this._appendFormattedArguments(element, args);
    }

    _appendSavedResultIndex(element)
    {
        let savedResultIndex = this._message.savedResultIndex;
        if (!savedResultIndex)
            return;

        console.assert(this._message instanceof WI.ConsoleCommandResultMessage);
        console.assert(this._message.type === WI.ConsoleMessage.MessageType.Result);

        var savedVariableElement = document.createElement("span");
        savedVariableElement.classList.add("console-saved-variable");

        // FIXME: <https://webkit.org/b/196956> Web Inspector: use weak collections for holding event listeners
        function updateSavedVariableText() {
            savedVariableElement.textContent = " = " + WI.RuntimeManager.preferredSavedResultPrefix() + savedResultIndex;
        }
        WI.settings.consoleSavedResultAlias.addEventListener(WI.Setting.Event.Changed, updateSavedVariableText, this);
        updateSavedVariableText();

        if (this._objectTree)
            this._objectTree.appendTitleSuffix(savedVariableElement);
        else
            this._messageBodyElement.appendChild(savedVariableElement);
    }

    _appendLocationLink()
    {
        if (this._message.source === WI.ConsoleMessage.MessageSource.Network) {
            if (this._message.url) {
                var anchor = WI.linkifyURLAsNode(this._message.url, this._message.url, "console-message-url");
                anchor.classList.add("console-message-location");
                this._element.appendChild(anchor);
            }
            return;
        }

        var callFrame;
        let firstNonNativeNonAnonymousNotBlackboxedCallFrame = this._message.stackTrace.firstNonNativeNonAnonymousNotBlackboxedCallFrame;
        if (firstNonNativeNonAnonymousNotBlackboxedCallFrame) {
            // JavaScript errors and console.* methods.
            callFrame = firstNonNativeNonAnonymousNotBlackboxedCallFrame;
        } else if (this._message.url && !this._shouldHideURL(this._message.url)) {
            // CSS warnings have no stack traces.
            callFrame = WI.CallFrame.fromPayload(this._message.target, {
                functionName: "",
                url: this._message.url,
                lineNumber: this._message.line,
                columnNumber: this._message.column
            });
        }

        if (callFrame && (!callFrame.isConsoleEvaluation || WI.settings.debugShowConsoleEvaluations.value)) {
            let existingCallFrameView = this._callFrameView;

            this._callFrameView = new WI.CallFrameView(callFrame, {showFunctionName: !!callFrame.functionName});
            this._callFrameView.classList.add("console-message-location");

            if (existingCallFrameView)
                this._element.replaceChild(this._callFrameView, existingCallFrameView);
            else
                this._element.appendChild(this._callFrameView);
            return;
        }

        if (this._message.parameters && this._message.parameters.length === 1) {
            var parameter = this._createRemoteObjectIfNeeded(this._message.parameters[0]);

            parameter.findFunctionSourceCodeLocation().then((result) => {
                if (result === WI.RemoteObject.SourceCodeLocationPromise.NoSourceFound || result === WI.RemoteObject.SourceCodeLocationPromise.MissingObjectId)
                    return;

                let link = WI.linkifySourceCode(result.sourceCode, new WI.SourceCodePosition(result.lineNumber, result.columnNumber), {
                    className: "console-message-url",
                    ignoreNetworkTab: true,
                    ignoreSearchTab: true,
                });
                link.classList.add("console-message-location");

                if (this._element.hasChildNodes())
                    this._element.insertBefore(link, this._element.firstChild);
                else
                    this._element.appendChild(link);
            });
        }
    }

    _appendExtraParameters()
    {
        if (!this._extraParameters || !this._extraParameters.length)
            return;

        this._makeExpandable();

        // Auto-expand if there are multiple objects or if there were simple parameters.
        if (this._extraParameters.length > 1)
            this.expand();

        this._extraElementsList = this._element.appendChild(document.createElement("ol"));
        this._extraElementsList.classList.add("console-message-extra-parameters-container");

        for (var parameter of this._extraParameters) {
            var listItemElement = this._extraElementsList.appendChild(document.createElement("li"));
            const forceObjectFormat = parameter.type === "object" && (parameter.subtype !== "null" && parameter.subtype !== "regexp" && parameter.subtype !== "node" && parameter.subtype !== "error");
            listItemElement.classList.add("console-message-extra-parameter");
            listItemElement.appendChild(this._formatParameter(parameter, forceObjectFormat));
        }
    }

    _appendStackTrace()
    {
        if (!this._shouldShowStackTrace())
            return;

        this._makeExpandable();

        if (this._message.type === WI.ConsoleMessage.MessageType.Trace && WI.settings.consoleAutoExpandTrace.value)
            this.expand();

        this._stackTraceElement = this._element.appendChild(document.createElement("div"));
        this._stackTraceElement.classList.add("console-message-body", "console-message-stack-trace-container");

        var callFramesElement = new WI.StackTraceView(this._message.stackTrace).element;
        this._stackTraceElement.appendChild(callFramesElement);
    }

    _createRemoteObjectIfNeeded(parameter)
    {
        // FIXME: Only pass RemoteObjects here so we can avoid this work.
        if (parameter instanceof WI.RemoteObject)
            return parameter;

        if (typeof parameter === "object")
            return WI.RemoteObject.fromPayload(parameter, this._message.target);

        return WI.RemoteObject.fromPrimitiveValue(parameter);
    }

    _appendFormattedArguments(element, parameters)
    {
        if (!parameters.length)
            return;

        for (let i = 0; i < parameters.length; ++i)
            parameters[i] = this._createRemoteObjectIfNeeded(parameters[i]);

        let builderElement = element.appendChild(document.createElement("span"));
        let shouldFormatWithStringSubstitution = parameters[0].type === "string" && this._message.type !== WI.ConsoleMessage.MessageType.Result;

        // Single object (e.g. console result or logging a non-string object).
        if (parameters.length === 1 && !shouldFormatWithStringSubstitution) {
            this._extraParameters = null;
            builderElement.appendChild(this._formatParameter(parameters[0], false));
            return;
        }

        console.assert(this._message.type !== WI.ConsoleMessage.MessageType.Result);

        if (shouldFormatWithStringSubstitution && this._isStackTrace(parameters[0]))
            shouldFormatWithStringSubstitution = false;

        let needsDivider = false;
        function appendDividerIfNeeded() {
            if (!needsDivider)
                return null;
            let element = builderElement.appendChild(document.createElement("span"));
            element.classList.add("console-message-preview-divider");
            element.textContent = ` ${enDash} `;
            return element;
        }

        // Format string.
        if (shouldFormatWithStringSubstitution) {
            let result = this._formatWithSubstitutionString(parameters, builderElement);
            parameters = result.unusedSubstitutions;
            this._extraParameters = parameters;
            needsDivider = true;
        }

        // Trailing inline parameters.
        if (parameters.length) {
            let simpleParametersCount = 0;
            for (let parameter of parameters) {
                if (!this._hasSimpleDisplay(parameter))
                    break;
                simpleParametersCount++;
            }

            // Show one or more simple parameters inline on the message line.
            if (simpleParametersCount) {
                let simpleParameters = parameters.splice(0, simpleParametersCount);
                this._extraParameters = parameters;

                for (let parameter of simpleParameters) {
                    let dividerElement = appendDividerIfNeeded();
                    if (dividerElement)
                        dividerElement.classList.add("inline-lossless");

                    let previewContainer = builderElement.appendChild(document.createElement("span"));
                    previewContainer.classList.add("inline-lossless");

                    let preview = WI.FormattedValue.createObjectPreviewOrFormattedValueForRemoteObject(parameter, WI.ObjectPreviewView.Mode.Brief);
                    let isPreviewView = preview instanceof WI.ObjectPreviewView;

                    if (isPreviewView)
                        preview.setOriginatingObjectInfo(parameter, null);

                    let previewElement = isPreviewView ? preview.element : preview;
                    previewContainer.appendChild(previewElement);

                    needsDivider = true;

                    // Simple displayable parameters should pretty much always be lossless.
                    // An exception might be a truncated string.
                    console.assert((isPreviewView && preview.lossless) || (!isPreviewView && this._shouldConsiderObjectLossless(parameter)));
                }
            }

            // If there is a single non-simple parameter after simple paramters, show it inline.
            if (parameters.length === 1 && !this._isStackTrace(parameters[0])) {
                let parameter = parameters[0];

                let dividerElement = appendDividerIfNeeded();

                let previewContainer = builderElement.appendChild(document.createElement("span"));
                previewContainer.classList.add("console-message-preview");

                let preview = WI.FormattedValue.createObjectPreviewOrFormattedValueForRemoteObject(parameter, WI.ObjectPreviewView.Mode.Brief);
                let isPreviewView = preview instanceof WI.ObjectPreviewView;

                if (isPreviewView)
                    preview.setOriginatingObjectInfo(parameter, null);

                let previewElement = isPreviewView ? preview.element : preview;
                previewContainer.appendChild(previewElement);

                needsDivider = true;

                // If this preview is effectively lossless, we can avoid making this console message expandable.
                if ((isPreviewView && preview.lossless) || (!isPreviewView && this._shouldConsiderObjectLossless(parameter))) {
                    this._extraParameters = null;
                    if (dividerElement)
                        dividerElement.classList.add("inline-lossless");
                    previewContainer.classList.add("inline-lossless");
                }
            } else if (parameters.length) {
                // Multiple remaining objects. Show an indicator and they will be appended as extra parameters.
                let enclosedElement = document.createElement("span");
                builderElement.append(" ", enclosedElement);
                enclosedElement.classList.add("console-message-enclosed");
                enclosedElement.textContent = "(" + parameters.length + ")";
            }
        }
    }

    _hasSimpleDisplay(parameter)
    {
        console.assert(parameter instanceof WI.RemoteObject);

        return WI.FormattedValue.hasSimpleDisplay(parameter) && !this._isStackTrace(parameter);
    }

    _isStackTrace(parameter)
    {
        console.assert(parameter instanceof WI.RemoteObject);

        return parameter.type === "string" && WI.StackTrace.isLikelyStackTrace(parameter.description);
    }

    _shouldConsiderObjectLossless(object)
    {
        if (object.type === "string")
            return WI.FormattedValue.isSimpleString(object.description);

        return object.type !== "object" || object.subtype === "null" || object.subtype === "regexp";
    }

    _formatParameter(parameter, forceObjectFormat)
    {
        var type;
        if (forceObjectFormat)
            type = "object";
        else if (parameter instanceof WI.RemoteObject)
            type = parameter.subtype || parameter.type;
        else {
            console.assert(false, "no longer reachable");
            type = typeof parameter;
        }

        var formatters = {
            "object": this._formatParameterAsObject,
            "error": this._formatParameterAsError,
            "map": this._formatParameterAsObject,
            "set": this._formatParameterAsObject,
            "weakmap": this._formatParameterAsObject,
            "weakset": this._formatParameterAsObject,
            "iterator": this._formatParameterAsObject,
            "class": this._formatParameterAsObject,
            "proxy": this._formatParameterAsObject,
            "array": this._formatParameterAsArray,
            "node": this._formatParameterAsNode,
            "string": this._formatParameterAsString,
        };

        var formatter = formatters[type] || this._formatParameterAsValue;

        const fragment = document.createDocumentFragment();
        formatter.call(this, parameter, fragment, forceObjectFormat);
        return fragment;
    }

    _formatParameterAsValue(value, fragment)
    {
        fragment.appendChild(WI.FormattedValue.createElementForRemoteObject(value));
    }

    _formatParameterAsString(object, fragment)
    {
        if (this._isStackTrace(object)) {
            let stackTrace = WI.StackTrace.fromString(this._message.target, object.description);
            if (stackTrace.callFrames.length) {
                let stackView = new WI.StackTraceView(stackTrace);
                fragment.appendChild(stackView.element);
                return;
            }
        }

        fragment.appendChild(WI.FormattedValue.createLinkifiedElementString(object.description));
    }

    _formatParameterAsNode(object, fragment)
    {
        fragment.appendChild(WI.FormattedValue.createElementForNode(object));
    }

    _formatParameterAsObject(object, fragment, forceExpansion)
    {
        // FIXME: Should have a better ObjectTreeView mode for classes (static methods and methods).
        this._objectTree = new WI.ObjectTreeView(object, null, this._rootPropertyPathForObject(object), forceExpansion);
        fragment.appendChild(this._objectTree.element);
    }

    _formatParameterAsError(object, fragment)
    {
        this._objectTree = new WI.ErrorObjectView(object);
        fragment.appendChild(this._objectTree.element);
    }

    _formatParameterAsArray(array, fragment)
    {
        this._objectTree = new WI.ObjectTreeView(array, WI.ObjectTreeView.Mode.Properties, this._rootPropertyPathForObject(array));
        fragment.appendChild(this._objectTree.element);
    }

    _rootPropertyPathForObject(object)
    {
        let savedResultIndex = this._message.savedResultIndex;
        if (!savedResultIndex)
            return null;

        function prefixSavedResultIndex() {
            return WI.RuntimeManager.preferredSavedResultPrefix() + savedResultIndex;
        }

        let propertyPath = new WI.PropertyPath(object, prefixSavedResultIndex());

        // FIXME: <https://webkit.org/b/196956> Web Inspector: use weak collections for holding event listeners
        WI.settings.consoleSavedResultAlias.addEventListener(WI.Setting.Event.Changed, (event) => {
            propertyPath.pathComponent = prefixSavedResultIndex();
        }, this);

        return propertyPath;
    }

    _formatWithSubstitutionString(parameters, formattedResult)
    {
        function parameterFormatter(force, obj)
        {
            return this._formatParameter(obj, force);
        }

        function stringFormatter(obj)
        {
            return obj.description;
        }

        function floatFormatter(obj, token)
        {
            let value = typeof obj.value === "number" ? obj.value : obj.description;
            return String.standardFormatters.f(value, token);
        }

        function integerFormatter(obj)
        {
            let value = typeof obj.value === "number" ? obj.value : obj.description;
            return String.standardFormatters.d(value);
        }

        var currentStyle = null;
        function styleFormatter(obj)
        {
            currentStyle = {};
            var buffer = document.createElement("span");
            buffer.setAttribute("style", obj.description);
            for (var i = 0; i < buffer.style.length; i++) {
                var property = buffer.style[i];
                if (isWhitelistedProperty(property))
                    currentStyle[property] = buffer.style[property];
            }
        }

        function isWhitelistedProperty(property)
        {
            for (var prefix of ["background", "border", "color", "font", "line", "margin", "padding", "text"]) {
                if (property.startsWith(prefix) || property.startsWith("-webkit-" + prefix))
                    return true;
            }
            return false;
        }

        // Firebug uses %o for formatting objects.
        var formatters = {};
        formatters.o = parameterFormatter.bind(this, false);
        formatters.s = stringFormatter;
        formatters.f = floatFormatter;

        // Firebug allows both %i and %d for formatting integers.
        formatters.i = integerFormatter;
        formatters.d = integerFormatter;

        // Firebug uses %c for styling the message.
        formatters.c = styleFormatter;

        // Support %O to force object formatting, instead of the type-based %o formatting.
        formatters.O = parameterFormatter.bind(this, true);

        function append(a, b)
        {
            if (b instanceof Node)
                a.appendChild(b);
            else if (b !== undefined) {
                var toAppend = WI.linkifyStringAsFragment(b.toString());
                if (currentStyle) {
                    var wrapper = document.createElement("span");
                    for (var key in currentStyle)
                        wrapper.style[key] = currentStyle[key];
                    wrapper.appendChild(toAppend);
                    toAppend = wrapper;
                }

                a.appendChild(toAppend);
            }
            return a;
        }

        // String.format does treat formattedResult like a Builder, result is an object.
        return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
    }

    _shouldShowStackTrace()
    {
        if (!this._message.stackTrace.callFrames.length)
            return false;

        return this._message.source === WI.ConsoleMessage.MessageSource.Network
            || this._message.level === WI.ConsoleMessage.MessageLevel.Error
            || this._message.type === WI.ConsoleMessage.MessageType.Trace;
    }

    _shouldHideURL(url)
    {
        return url === "undefined" || url === "[native code]";
    }

    _userProvidedColumnNames(columnNamesArgument)
    {
        if (!columnNamesArgument)
            return null;

        console.assert(columnNamesArgument instanceof WI.RemoteObject);

        // Single primitive argument.
        if (columnNamesArgument.type === "string" || columnNamesArgument.type === "number")
            return [String(columnNamesArgument.value)];

        // Ignore everything that is not an array with property previews.
        if (columnNamesArgument.type !== "object" || columnNamesArgument.subtype !== "array" || !columnNamesArgument.preview || !columnNamesArgument.preview.propertyPreviews)
            return null;

        // Array. Look into the preview and get string values.
        var extractedColumnNames = [];
        for (var propertyPreview of columnNamesArgument.preview.propertyPreviews) {
            if (propertyPreview.type === "string" || propertyPreview.type === "number")
                extractedColumnNames.push(String(propertyPreview.value));
        }

        return extractedColumnNames.length ? extractedColumnNames : null;
    }

    _formatParameterAsTable(parameters)
    {
        var element = document.createElement("span");
        var table = parameters[0];
        if (!table || !table.preview)
            return element;

        var rows = [];
        var columnNames = [];
        var flatValues = [];
        var preview = table.preview;
        var userProvidedColumnNames = false;

        // User provided columnNames.
        var extractedColumnNames = this._userProvidedColumnNames(parameters[1]);
        if (extractedColumnNames) {
            userProvidedColumnNames = true;
            columnNames = extractedColumnNames;
        }

        // Check first for valuePreviews in the properties meaning this was an array of objects.
        if (preview.propertyPreviews) {
            for (var i = 0; i < preview.propertyPreviews.length; ++i) {
                var rowProperty = preview.propertyPreviews[i];
                var rowPreview = rowProperty.valuePreview;
                if (!rowPreview || !rowPreview.propertyPreviews)
                    continue;

                var rowValue = {};
                var maxColumnsToRender = 15;
                for (var j = 0; j < rowPreview.propertyPreviews.length; ++j) {
                    var cellProperty = rowPreview.propertyPreviews[j];
                    var columnRendered = columnNames.includes(cellProperty.name);
                    if (!columnRendered) {
                        if (userProvidedColumnNames || columnNames.length === maxColumnsToRender)
                            continue;
                        columnRendered = true;
                        columnNames.push(cellProperty.name);
                    }

                    rowValue[cellProperty.name] = WI.FormattedValue.createElementForPropertyPreview(cellProperty);
                }
                rows.push([rowProperty.name, rowValue]);
            }
        }

        // If there were valuePreviews, convert to a flat list.
        if (rows.length) {
            columnNames.unshift(WI.UIString("(Index)"));
            for (var i = 0; i < rows.length; ++i) {
                var rowName = rows[i][0];
                var rowValue = rows[i][1];
                flatValues.push(rowName);
                for (var j = 1; j < columnNames.length; ++j) {
                    var columnName = columnNames[j];
                    if (!(columnName in rowValue))
                        flatValues.push(emDash);
                    else
                        flatValues.push(rowValue[columnName]);
                }
            }
        }

        // If there were no value Previews, then check for an array of values.
        if (!flatValues.length && preview.propertyPreviews) {
            for (var i = 0; i < preview.propertyPreviews.length; ++i) {
                var rowProperty = preview.propertyPreviews[i];
                if (!("value" in rowProperty))
                    continue;

                if (!columnNames.length) {
                    columnNames.push(WI.UIString("Index"));
                    columnNames.push(WI.UIString("Value"));
                }

                flatValues.push(rowProperty.name);
                flatValues.push(WI.FormattedValue.createElementForPropertyPreview(rowProperty));
            }
        }

        // If no table data show nothing.
        if (!flatValues.length)
            return element;

        // FIXME: Should we output something extra if the preview is lossless?

        var dataGrid = WI.DataGrid.createSortableDataGrid(columnNames, flatValues);
        dataGrid.inline = true;
        dataGrid.variableHeightRows = true;

        element.appendChild(dataGrid.element);

        dataGrid.updateLayoutIfNeeded();

        return element;
    }

    _levelString()
    {
        switch (this._message.level) {
        case WI.ConsoleMessage.MessageLevel.Log:
            return "Log";
        case WI.ConsoleMessage.MessageLevel.Info:
            return "Info";
        case WI.ConsoleMessage.MessageLevel.Warning:
            return "Warning";
        case WI.ConsoleMessage.MessageLevel.Debug:
            return "Debug";
        case WI.ConsoleMessage.MessageLevel.Error:
            return "Error";
        }
    }

    _enforcesClipboardPrefixString()
    {
        return this._message.type !== WI.ConsoleMessage.MessageType.Result;
    }

    _clipboardPrefixString()
    {
        if (this._message.type === WI.ConsoleMessage.MessageType.Result)
            return "< ";

        return "[" + this._levelString() + "] ";
    }

    _makeExpandable()
    {
        if (this._expandable)
            return;

        this._expandable = true;

        this._element.classList.add("expandable");

        this._boundClickHandler = this.toggle.bind(this);
        this._messageBodyElement.addEventListener("click", this._boundClickHandler);
    }

    _handleContextMenu(event)
    {
        let image = event.target.closest(".console-image > .console-message-body > img");
        if (!image)
            return;

        let contextMenu = WI.ContextMenu.createFromEvent(event);

        contextMenu.appendItem(WI.UIString("Save Image"), () => {
            const forceSaveAs = true;
            WI.FileUtilities.save({
                content: parseDataURL(this._message.messageText).data,
                base64Encoded: true,
                suggestedName: image.getAttribute("filename"),
            }, forceSaveAs);
        });

        contextMenu.appendSeparator();
    }

    _handleDebuggerBlackboxChanged(event)
    {
        if (this._callFrameView)
            this._appendLocationLink();
    }
};
