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

WebInspector.SourceFrame = function(contentProvider, url, isScript)
{
    WebInspector.View.call(this);

    this.element.addStyleClass("script-view");

    this._contentProvider = contentProvider;
    this._url = url;
    this._isScript = isScript;

    this._textModel = new WebInspector.TextEditorModel();
    this._textModel.replaceTabsWithSpaces = true;

    this._currentSearchResultIndex = -1;
    this._searchResults = [];

    this._messages = [];
    this._rowMessages = {};
    this._messageBubbles = {};

    this._popoverObjectGroup = "popover";
}

WebInspector.SourceFrame.prototype = {

    show: function(parentElement)
    {
        WebInspector.View.prototype.show.call(this, parentElement);

        if (!this._contentRequested) {
            this._contentRequested = true;
            this._contentProvider.requestContent(this._createTextViewer.bind(this));
        }

        if (this._textViewer) {
            if (this._scrollTop)
                this._textViewer.scrollTop = this._scrollTop;
            if (this._scrollLeft)
                this._textViewer.scrollLeft = this._scrollLeft;
            this._textViewer.resize();
        }
    },

    hide: function()
    {
        if (this._textViewer) {
            this._scrollTop = this._textViewer.scrollTop;
            this._scrollLeft = this._textViewer.scrollLeft;
            this._textViewer.freeCachedElements();
        }

        WebInspector.View.prototype.hide.call(this);

        this._hidePopup();
        this._clearLineHighlight();
    },

    hasContent: function()
    {
        return true;
    },

    markDiff: function(diffData)
    {
        if (this._diffLines && this._textViewer)
            this._removeDiffDecorations();

        this._diffLines = diffData;
        if (this._textViewer)
            this._updateDiffDecorations();
    },

    revealLine: function(lineNumber)
    {
        if (this._textViewer)
            this._textViewer.revealLine(lineNumber - 1, 0);
        else
            this._lineNumberToReveal = lineNumber;
    },

    addMessage: function(msg)
    {
        // Don't add the message if there is no message or valid line or if the msg isn't an error or warning.
        if (!msg.message || msg.line <= 0 || !msg.isErrorOrWarning())
            return;
        this._messages.push(msg);
        if (this._textViewer)
            this._addMessageToSource(msg);
    },

    clearMessages: function()
    {
        for (var line in this._messageBubbles) {
            var bubble = this._messageBubbles[line];
            bubble.parentNode.removeChild(bubble);
        }

        this._messages = [];
        this._rowMessages = {};
        this._messageBubbles = {};
        if (this._textViewer)
            this._textViewer.resize();
    },

    sizeToFitContentHeight: function()
    {
        if (this._textViewer)
            this._textViewer.revalidateDecorationsAndPaint();
    },

    get textModel()
    {
        return this._textModel;
    },

    get scrollTop()
    {
        return this._textViewer ? this._textViewer.scrollTop : this._scrollTop;
    },

    set scrollTop(scrollTop)
    {
        this._scrollTop = scrollTop;
        if (this._textViewer)
            this._textViewer.scrollTop = scrollTop;
    },

    highlightLine: function(line)
    {
        if (this._textViewer)
            this._textViewer.highlightLine(line - 1);
        else
            this._lineToHighlight = line;
    },

    _clearLineHighlight: function()
    {
        if (this._textViewer)
            this._textViewer.clearLineHighlight();
        else
            delete this._lineToHighlight;
    },

    _createTextViewer: function(mimeType, content)
    {
        this._content = content;
        this._textModel.setText(null, content.text);

        this._textViewer = new WebInspector.TextViewer(this._textModel, WebInspector.platform, this._url);
        var element = this._textViewer.element;
        element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
        element.addEventListener("mousedown", this._mouseDown.bind(this), true);
        element.addEventListener("mousemove", this._mouseMove.bind(this), true);
        element.addEventListener("scroll", this._scroll.bind(this), true);
        element.addEventListener("dblclick", this._doubleClick.bind(this), true);
        this.element.appendChild(element);

        this._textViewer.beginUpdates();

        this._textViewer.mimeType = mimeType;
        this._setTextViewerDecorations();

        if (this._lineNumberToReveal) {
            this.revealLine(this._lineNumberToReveal);
            delete this._lineNumberToReveal;
        }

        if (this._lineToHighlight) {
            this.highlightLine(this._lineToHighlight);
            delete this._lineToHighlight;
        }

        if (this._delayedFindSearchMatches) {
            this._delayedFindSearchMatches();
            delete this._delayedFindSearchMatches;
        }

        this._textViewer.endUpdates();

        WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointAdded, this._breakpointAdded, this);
        WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointRemoved, this._breakpointRemoved, this);
        WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
    },

    _setTextViewerDecorations: function()
    {
        this._rowMessages = {};
        this._messageBubbles = {};

        this._textViewer.beginUpdates();

        this._addExistingMessagesToSource();
        this._updateDiffDecorations();

        if (this._executionLocation)
            this._setExecutionLocation();

        this._breakpointIdToTextViewerLineNumber = {};
        this._textViewerLineNumberToBreakpointId = {};
        var breakpoints = WebInspector.debuggerModel.breakpoints;
        for (var id in breakpoints)
            this._breakpointAdded({ data: breakpoints[id] });

        this._textViewer.resize();

        this._textViewer.endUpdates();
    },

    _shouldDisplayBreakpoint: function(breakpoint)
    {
        if (this._url)
            return this._url === breakpoint.url;
        var scripts = this._content.scriptRanges;
        for (var i = 0; i < scripts.length; ++i) {
            if (breakpoint.sourceID === scripts[i].sourceID)
                return true;
        }
        return false;
    },

    performSearch: function(query, callback)
    {
        // Call searchCanceled since it will reset everything we need before doing a new search.
        this.searchCanceled();

        function doFindSearchMatches(query)
        {
            this._currentSearchResultIndex = -1;
            this._searchResults = [];

            // First do case-insensitive search.
            var regexObject = createSearchRegex(query);
            this._collectRegexMatches(regexObject, this._searchResults);

            // Then try regex search if user knows the / / hint.
            try {
                if (/^\/.*\/$/.test(query))
                    this._collectRegexMatches(new RegExp(query.substring(1, query.length - 1)), this._searchResults);
            } catch (e) {
                // Silent catch.
            }

            callback(this, this._searchResults.length);
        }

        if (this._textViewer)
            doFindSearchMatches.call(this, query);
        else
            this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query);

    },

    searchCanceled: function()
    {
        delete this._delayedFindSearchMatches;
        if (!this._textViewer)
            return;

        this._currentSearchResultIndex = -1;
        this._searchResults = [];
        this._textViewer.markAndRevealRange(null);
    },

    jumpToFirstSearchResult: function()
    {
        this._jumpToSearchResult(0);
    },

    jumpToLastSearchResult: function()
    {
        this._jumpToSearchResult(this._searchResults.length - 1);
    },

    jumpToNextSearchResult: function()
    {
        this._jumpToSearchResult(this._currentSearchResultIndex + 1);
    },

    jumpToPreviousSearchResult: function()
    {
        this._jumpToSearchResult(this._currentSearchResultIndex - 1);
    },

    showingFirstSearchResult: function()
    {
        return this._searchResults.length &&  this._currentSearchResultIndex === 0;
    },

    showingLastSearchResult: function()
    {
        return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1);
    },

    _jumpToSearchResult: function(index)
    {
        if (!this._textViewer || !this._searchResults.length)
            return;
        this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
        this._textViewer.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]);
    },

    _collectRegexMatches: function(regexObject, ranges)
    {
        for (var i = 0; i < this._textModel.linesCount; ++i) {
            var line = this._textModel.line(i);
            var offset = 0;
            do {
                var match = regexObject.exec(line);
                if (match) {
                    ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length));
                    offset += match.index + 1;
                    line = line.substring(match.index + 1);
                }
            } while (match)
        }
        return ranges;
    },

    _incrementMessageRepeatCount: function(msg, repeatDelta)
    {
        if (!msg._resourceMessageLineElement)
            return;

        if (!msg._resourceMessageRepeatCountElement) {
            var repeatedElement = document.createElement("span");
            msg._resourceMessageLineElement.appendChild(repeatedElement);
            msg._resourceMessageRepeatCountElement = repeatedElement;
        }

        msg.repeatCount += repeatDelta;
        msg._resourceMessageRepeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", msg.repeatCount);
    },

    setExecutionLocation: function(lineNumber, columnNumber)
    {
        this._executionLocation = { lineNumber: lineNumber, columnNumber: columnNumber };
        if (this._textViewer)
            this._setExecutionLocation();
    },

    clearExecutionLocation: function()
    {
        if (this._textViewer) {
            var textViewerLineNumber = this._content.actualLocationToSourceFrameLineNumber(this._executionLocation.lineNumber, this._executionLocation.columnNumber);
            this._textViewer.removeDecoration(textViewerLineNumber, "webkit-execution-line");
        }
        delete this._executionLocation;
    },

    _setExecutionLocation: function()
    {
        var textViewerLineNumber = this._content.actualLocationToSourceFrameLineNumber(this._executionLocation.lineNumber, this._executionLocation.columnNumber);
        this._textViewer.addDecoration(textViewerLineNumber, "webkit-execution-line");
    },

    _updateDiffDecorations: function()
    {
        if (!this._diffLines)
            return;

        function addDecorations(textViewer, lines, className)
        {
            for (var i = 0; i < lines.length; ++i)
                textViewer.addDecoration(lines[i], className);
        }
        addDecorations(this._textViewer, this._diffLines.added, "webkit-added-line");
        addDecorations(this._textViewer, this._diffLines.removed, "webkit-removed-line");
        addDecorations(this._textViewer, this._diffLines.changed, "webkit-changed-line");
    },

    _removeDiffDecorations: function()
    {
        function removeDecorations(textViewer, lines, className)
        {
            for (var i = 0; i < lines.length; ++i)
                textViewer.removeDecoration(lines[i], className);
        }
        removeDecorations(this._textViewer, this._diffLines.added, "webkit-added-line");
        removeDecorations(this._textViewer, this._diffLines.removed, "webkit-removed-line");
        removeDecorations(this._textViewer, this._diffLines.changed, "webkit-changed-line");
    },

    _addExistingMessagesToSource: function()
    {
        var length = this._messages.length;
        for (var i = 0; i < length; ++i)
            this._addMessageToSource(this._messages[i]);
    },

    _addMessageToSource: function(msg)
    {
        if (msg.line > this._textModel.linesCount)
            return;

        var messageBubbleElement = this._messageBubbles[msg.line];
        if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
            messageBubbleElement = document.createElement("div");
            messageBubbleElement.className = "webkit-html-message-bubble";
            this._messageBubbles[msg.line] = messageBubbleElement;
            this._textViewer.addDecoration(msg.line - 1, messageBubbleElement);
        }

        var rowMessages = this._rowMessages[msg.line];
        if (!rowMessages) {
            rowMessages = [];
            this._rowMessages[msg.line] = rowMessages;
        }

        for (var i = 0; i < rowMessages.length; ++i) {
            if (rowMessages[i].isEqual(msg)) {
                this._incrementMessageRepeatCount(rowMessages[i], msg.repeatDelta);
                return;
            }
        }

        rowMessages.push(msg);

        var imageURL;
        switch (msg.level) {
            case WebInspector.ConsoleMessage.MessageLevel.Error:
                messageBubbleElement.addStyleClass("webkit-html-error-message");
                imageURL = "Images/errorIcon.png";
                break;
            case WebInspector.ConsoleMessage.MessageLevel.Warning:
                messageBubbleElement.addStyleClass("webkit-html-warning-message");
                imageURL = "Images/warningIcon.png";
                break;
        }

        var messageLineElement = document.createElement("div");
        messageLineElement.className = "webkit-html-message-line";
        messageBubbleElement.appendChild(messageLineElement);

        // Create the image element in the Inspector's document so we can use relative image URLs.
        var image = document.createElement("img");
        image.src = imageURL;
        image.className = "webkit-html-message-icon";
        messageLineElement.appendChild(image);
        messageLineElement.appendChild(document.createTextNode(msg.message));

        msg._resourceMessageLineElement = messageLineElement;
    },

    _breakpointAdded: function(event)
    {
        var breakpoint = event.data;

        if (!this._shouldDisplayBreakpoint(breakpoint))
            return;

        var resolved = breakpoint.locations.length;
        var location = resolved ? breakpoint.locations[0] : breakpoint;

        var textViewerLineNumber = this._content.actualLocationToSourceFrameLineNumber(location.lineNumber, location.columnNumber);
        if (textViewerLineNumber >= this._textModel.linesCount)
            return;

        var existingBreakpointId = this._textViewerLineNumberToBreakpointId[textViewerLineNumber];
        if (existingBreakpointId) {
            WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
            return;
        }

        this._breakpointIdToTextViewerLineNumber[breakpoint.id] = textViewerLineNumber;
        this._textViewerLineNumberToBreakpointId[textViewerLineNumber] = breakpoint.id;
        this._setBreakpointDecoration(textViewerLineNumber, resolved, breakpoint.enabled, !!breakpoint.condition);
    },

    _breakpointRemoved: function(event)
    {
        var breakpointId = event.data;

        var textViewerLineNumber = this._breakpointIdToTextViewerLineNumber[breakpointId];
        if (textViewerLineNumber === undefined)
            return;

        delete this._breakpointIdToTextViewerLineNumber[breakpointId];
        delete this._textViewerLineNumberToBreakpointId[textViewerLineNumber];
        this._removeBreakpointDecoration(textViewerLineNumber);
    },

    _breakpointResolved: function(event)
    {
        var breakpoint = event.data;
        this._breakpointRemoved({ data: breakpoint.id });
        this._breakpointAdded({ data: breakpoint });
    },

    _setBreakpointDecoration: function(lineNumber, resolved, enabled, hasCondition)
    {
        this._textViewer.beginUpdates();
        this._textViewer.addDecoration(lineNumber, "webkit-breakpoint");
        if (!enabled)
            this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-disabled");
        if (hasCondition)
            this._textViewer.addDecoration(lineNumber, "webkit-breakpoint-conditional");
        this._textViewer.endUpdates();
    },

    _removeBreakpointDecoration: function(lineNumber)
    {
        this._textViewer.beginUpdates();
        this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint");
        this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
        this._textViewer.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
        this._textViewer.endUpdates();
    },

    _contextMenu: function(event)
    {
        if (!WebInspector.panels.scripts)
            return;

        var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
        if (!target)
            return;
        var textViewerLineNumber = target.lineNumber;

        var contextMenu = new WebInspector.ContextMenu();

        contextMenu.appendItem(WebInspector.UIString("Continue to Here"), this._continueToLine.bind(this, textViewerLineNumber));

        var breakpoint = this._findBreakpoint(textViewerLineNumber);
        if (!breakpoint) {
            // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
            contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this._setBreakpoint.bind(this, textViewerLineNumber, "", true));

            function addConditionalBreakpoint()
            {
                this._setBreakpointDecoration(textViewerLineNumber, true, true, true);
                function didEditBreakpointCondition(committed, condition)
                {
                    this._removeBreakpointDecoration(textViewerLineNumber);
                    if (committed)
                        this._setBreakpoint(textViewerLineNumber, condition, true);
                }
                this._editBreakpointCondition(textViewerLineNumber, "", didEditBreakpointCondition.bind(this));
            }
            contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint…"), addConditionalBreakpoint.bind(this));
        } else {
            // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
            function removeBreakpoint()
            {
                WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
            }
            contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint);
            function editBreakpointCondition()
            {
                function didEditBreakpointCondition(committed, condition)
                {
                    if (committed)
                        WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, condition, breakpoint.enabled);
                }
                this._editBreakpointCondition(textViewerLineNumber, breakpoint.condition, didEditBreakpointCondition.bind(this));
            }
            contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint…"), editBreakpointCondition.bind(this));
            function setBreakpointEnabled(enabled)
            {
                WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, breakpoint.condition, enabled);
            }
            if (breakpoint.enabled)
                contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), setBreakpointEnabled.bind(this, false));
            else
                contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), setBreakpointEnabled.bind(this, true));
        }
        contextMenu.show(event);
    },

    _scroll: function(event)
    {
        this._hidePopup();
    },

    _mouseDown: function(event)
    {
        this._resetHoverTimer();
        this._hidePopup();
        if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey)
            return;
        var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
        if (!target)
            return;
        var textViewerLineNumber = target.lineNumber;

        var breakpoint = this._findBreakpoint(textViewerLineNumber);
        if (breakpoint) {
            if (event.shiftKey)
                WebInspector.debuggerModel.updateBreakpoint(breakpoint.id, breakpoint.condition, !breakpoint.enabled);
            else
                WebInspector.debuggerModel.removeBreakpoint(breakpoint.id);
        } else
            this._setBreakpoint(textViewerLineNumber, "", true);
        event.preventDefault();
    },

    _mouseMove: function(event)
    {
        // Pretend that nothing has happened.
        if (this._hoverElement === event.target || event.target.hasStyleClass("source-frame-eval-expression"))
            return;

        this._resetHoverTimer();
        // User has 500ms to reach the popup.
        if (this._popup) {
            var self = this;
            function doHide()
            {
                self._hidePopup();
                delete self._hidePopupTimer;
            }
            if (!("_hidePopupTimer" in this))
                this._hidePopupTimer = setTimeout(doHide, 500);
        }

        this._hoverElement = event.target;

        // Now that cleanup routines are set up above, leave this in case we are not on a break.
        if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
            return;

        // We are interested in identifiers and "this" keyword.
        if (this._hoverElement.hasStyleClass("webkit-javascript-keyword")) {
            if (this._hoverElement.textContent !== "this")
                return;
        } else if (!this._hoverElement.hasStyleClass("webkit-javascript-ident"))
            return;

        const toolTipDelay = this._popup ? 600 : 1000;
        this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
    },

    _resetHoverTimer: function()
    {
        if (this._hoverTimer) {
            clearTimeout(this._hoverTimer);
            delete this._hoverTimer;
        }
    },

    _hidePopup: function()
    {
        if (!this._popup)
            return;

        // Replace higlight element with its contents inplace.
        var parentElement = this._popup.highlightElement.parentElement;
        var child = this._popup.highlightElement.firstChild;
        while (child) {
            var nextSibling = child.nextSibling;
            parentElement.insertBefore(child, this._popup.highlightElement);
            child = nextSibling;
        }
        parentElement.removeChild(this._popup.highlightElement);

        this._popup.hide();
        delete this._popup;
        InspectorBackend.releaseWrapperObjectGroup(0, this._popoverObjectGroup);
    },

    _mouseHover: function(element)
    {
        delete this._hoverTimer;

        if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
            return;

        var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
        if (!lineRow)
            return;

        // Collect tokens belonging to evaluated exression.
        var tokens = [ element ];
        var token = element.previousSibling;
        while (token && (token.className === "webkit-javascript-ident" || token.className === "webkit-javascript-keyword" || token.textContent.trim() === ".")) {
            tokens.push(token);
            token = token.previousSibling;
        }
        tokens.reverse();

        // Wrap them with highlight element.
        var parentElement = element.parentElement;
        var nextElement = element.nextSibling;
        var container = document.createElement("span");
        for (var i = 0; i < tokens.length; ++i)
            container.appendChild(tokens[i]);
        parentElement.insertBefore(container, nextElement);
        this._showPopup(container);
    },

    _showPopup: function(element)
    {
        function killHidePopupTimer()
        {
            if (this._hidePopupTimer) {
                clearTimeout(this._hidePopupTimer);
                delete this._hidePopupTimer;

                // We know that we reached the popup, but we might have moved over other elements.
                // Discard pending command.
                this._resetHoverTimer();
            }
        }

        function showObjectPopup(result)
        {
            if (!WebInspector.panels.scripts.paused)
                return;

            var popupContentElement = null;
            if (result.type !== "object" && result.type !== "node" && result.type !== "array") {
                popupContentElement = document.createElement("span");
                popupContentElement.className = "monospace console-formatted-" + result.type;
                popupContentElement.style.whiteSpace = "pre";
                popupContentElement.textContent = result.description;
                if (result.type === "string")
                    popupContentElement.textContent = "\"" + popupContentElement.textContent + "\"";
                this._popup = new WebInspector.Popover(popupContentElement);
                this._popup.show(element);
            } else {
                var popupContentElement = document.createElement("div");

                var titleElement = document.createElement("div");
                titleElement.className = "source-frame-popover-title monospace";
                titleElement.textContent = result.description;
                popupContentElement.appendChild(titleElement);

                var section = new WebInspector.ObjectPropertiesSection(result, "", null, false);
                section.expanded = true;
                section.element.addStyleClass("source-frame-popover-tree");
                section.headerElement.addStyleClass("hidden");
                popupContentElement.appendChild(section.element);

                this._popup = new WebInspector.Popover(popupContentElement);
                const popupWidth = 300;
                const popupHeight = 250;
                this._popup.show(element, popupWidth, popupHeight);
            }
            this._popup.highlightElement = element;
            this._popup.highlightElement.addStyleClass("source-frame-eval-expression");
            popupContentElement.addEventListener("mousemove", killHidePopupTimer.bind(this), true);
        }

        function evaluateCallback(result)
        {
            if (result.isError())
                return;
            if (!WebInspector.panels.scripts.paused)
                return;
            showObjectPopup.call(this, result);
        }
        WebInspector.panels.scripts.evaluateInSelectedCallFrame(element.textContent, false, this._popoverObjectGroup, false, evaluateCallback.bind(this));
    },

    _editBreakpointCondition: function(lineNumber, condition, callback)
    {
        this._conditionElement = this._createConditionElement(lineNumber);
        this._textViewer.addDecoration(lineNumber, this._conditionElement);

        function finishEditing(committed, element, newText)
        {
            this._textViewer.removeDecoration(lineNumber, this._conditionElement);
            delete this._conditionEditorElement;
            delete this._conditionElement;
            callback(committed, newText);
        }

        WebInspector.startEditing(this._conditionEditorElement, {
            context: null,
            commitHandler: finishEditing.bind(this, true),
            cancelHandler: finishEditing.bind(this, false)
        });
        this._conditionEditorElement.value = condition;
        this._conditionEditorElement.select();
    },

    _createConditionElement: function(lineNumber)
    {
        var conditionElement = document.createElement("div");
        conditionElement.className = "source-frame-breakpoint-condition";

        var labelElement = document.createElement("label");
        labelElement.className = "source-frame-breakpoint-message";
        labelElement.htmlFor = "source-frame-breakpoint-condition";
        labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber)));
        conditionElement.appendChild(labelElement);

        var editorElement = document.createElement("input");
        editorElement.id = "source-frame-breakpoint-condition";
        editorElement.className = "monospace";
        editorElement.type = "text";
        conditionElement.appendChild(editorElement);
        this._conditionEditorElement = editorElement;

        return conditionElement;
    },

    _evalSelectionInCallFrame: function(event)
    {
        if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
            return;

        var selection = this.element.contentWindow.getSelection();
        if (!selection.rangeCount)
            return;

        var expression = selection.getRangeAt(0).toString().trim();
        WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result) {
            WebInspector.showConsole();
            var commandMessage = new WebInspector.ConsoleCommand(expression);
            WebInspector.console.addMessage(commandMessage);
            WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, commandMessage));
        });
    },

    resize: function()
    {
        if (this._textViewer)
            this._textViewer.resize();
    },

    formatSource: function()
    {
        if (!this._content)
            return;

        function didFormat(formattedContent)
        {
            this._content = formattedContent;
            this._textModel.setText(null, formattedContent.text);
            this._setTextViewerDecorations();
        }
        var formatter = new WebInspector.ScriptFormatter();
        formatter.formatContent(this._content, didFormat.bind(this))
    },

    _continueToLine: function(lineNumber)
    {
        var location = this._content.sourceFrameLineNumberToActualLocation(lineNumber);
        if (location.sourceID)
            WebInspector.debuggerModel.continueToLocation(location.sourceID, location.lineNumber, location.columnNumber);
    },

    _doubleClick: function(event)
    {
        if (!Preferences.canEditScriptSource || !this._isScript)
            return;

        var lineRow = event.target.enclosingNodeOrSelfWithClass("webkit-line-content");
        if (!lineRow)
            return;  // Do not trigger editing from line numbers.

        var lineNumber = lineRow.lineNumber;
        var location = this._content.sourceFrameLineNumberToActualLocation(lineNumber);
        if (!location.sourceID)
            return;

        function didEditLine(newContent)
        {
            var lines = [];
            var oldLines = this._content.text.split('\n');
            for (var i = 0; i < oldLines.length; ++i) {
                if (i === lineNumber)
                    lines.push(newContent);
                else
                    lines.push(oldLines[i]);
            }
            WebInspector.debuggerModel.editScriptSource(location.sourceID, lines.join("\n"));
        }
        this._textViewer.editLine(lineRow, didEditLine.bind(this));
    },

    _setBreakpoint: function(lineNumber, condition, enabled)
    {
        var location = this._content.sourceFrameLineNumberToActualLocation(lineNumber);
        if (this._url)
            WebInspector.debuggerModel.setBreakpoint(this._url, location.lineNumber, location.columnNumber, condition, enabled);
        else if (location.sourceID)
            WebInspector.debuggerModel.setBreakpointBySourceId(location.sourceID, location.lineNumber, location.columnNumber, condition, enabled);
        else
            return;

        if (!WebInspector.panels.scripts.breakpointsActivated)
            WebInspector.panels.scripts.toggleBreakpointsClicked();
    },

    _findBreakpoint: function(textViewerLineNumber)
    {
        var breakpointId = this._textViewerLineNumberToBreakpointId[textViewerLineNumber];
        return WebInspector.debuggerModel.breakpointForId(breakpointId);
    }
}

WebInspector.SourceFrame.prototype.__proto__ = WebInspector.View.prototype;


WebInspector.SourceFrameContentProvider = function()
{
}

WebInspector.SourceFrameContentProvider.prototype = {
    requestContent: function(callback)
    {
        // Should be implemented by subclasses.
    }
}
