/*
 * 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)
            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") {
            const description = object.description;
            const maxLength = WI.FormattedValue.MAX_PREVIEW_STRING_LENGTH;
            const longOrMultiLineString = description.length > maxLength || description.slice(0, maxLength).includes("\n");
            return !longOrMultiLineString;
        }

        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({
                url: WI.FileUtilities.inspectorURLForFilename(image.getAttribute("filename")),
                content: parseDataURL(this._message.messageText).data,
                base64Encoded: true,
            }, forceSaveAs);
        });

        contextMenu.appendSeparator();
    }

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