Changeset 53856 in webkit


Ignore:
Timestamp:
Jan 26, 2010 8:39:19 AM (14 years ago)
Author:
pfeldman@chromium.org
Message:

2010-01-26 Pavel Feldman <pfeldman@chromium.org>

Reviewed by Timothy Hatcher.

Web Inspector: add support for breakpoints, messages and search into the SourceFrame2.

https://bugs.webkit.org/show_bug.cgi?id=34165

Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r53855 r53856  
    112010-01-26  Pavel Feldman  <pfeldman@chromium.org>
    22
    3         Reviewed by Timothy Hather.
     3        Reviewed by Timothy Hatcher.
     4
     5        Web Inspector: add support for breakpoints, messages and search into the SourceFrame2.
     6
     7        https://bugs.webkit.org/show_bug.cgi?id=34165
     8
     9        * inspector/front-end/SourceFrame2.js:
     10        (WebInspector.SourceFrame2):
     11        (WebInspector.SourceFrame2.prototype.get executionLine):
     12        (WebInspector.SourceFrame2.prototype.set executionLine):
     13        (WebInspector.SourceFrame2.prototype.revealLine):
     14        (WebInspector.SourceFrame2.prototype.addBreakpoint):
     15        (WebInspector.SourceFrame2.prototype.removeBreakpoint):
     16        (WebInspector.SourceFrame2.prototype.sizeToFitContentHeight):
     17        (WebInspector.SourceFrame2.prototype.setContent):
     18        (WebInspector.SourceFrame2.prototype.findSearchMatches):
     19        (WebInspector.SourceFrame2.prototype.setSelection):
     20        (WebInspector.SourceFrame2.prototype._addMessageToSource):
     21        (WebInspector.SourceFrame2.prototype._addExistingBreakpointsToSource):
     22        (WebInspector.SourceFrame2.prototype._addBreakpointToSource):
     23        (WebInspector.SourceFrame2.prototype._removeBreakpointFromSource):
     24        (WebInspector.SourceFrame2.prototype._contextMenu.addConditionalBreakpoint):
     25        (WebInspector.SourceFrame2.prototype._contextMenu):
     26        (WebInspector.SourceFrame2.prototype._toggleBreakpoint):
     27        (WebInspector.SourceFrame2.prototype._editBreakpointCondition.committed):
     28        (WebInspector.SourceFrame2.prototype._editBreakpointCondition.dismissed):
     29        (WebInspector.SourceFrame2.prototype._editBreakpointCondition):
     30        (WebInspector.SourceFrame2.prototype._showBreakpointConditionPopup):
     31        (WebInspector.SourceFrame2.prototype._createConditionElement):
     32        (WebInspector.SourceFrame2.prototype._keyDown):
     33        (WebInspector.SourceFrame2.prototype._evalSelectionInCallFrame):
     34        (WebInspector.SourceFrame2.prototype._breakpointChanged):
     35        (WebInspector.SourceFrame2.prototype.resize):
     36        (WebInspector.BreakpointLineNumberDecorator.prototype.decorate):
     37        (WebInspector.BreakpointLineNumberDecorator.prototype._paintBreakpoint):
     38        (WebInspector.BreakpointLineNumberDecorator.prototype.mouseDown):
     39        (WebInspector.BreakpointLineNumberDecorator.prototype.contextMenu):
     40        (WebInspector.ExecutionLineDecorator.prototype.decorate):
     41        * inspector/front-end/TextEditor.js:
     42        (WebInspector.TextEditor):
     43        (WebInspector.TextEditor.prototype.set mimeType):
     44        (WebInspector.TextEditor.prototype.set readOnly):
     45        (WebInspector.TextEditor.prototype.setDivDecoration):
     46        (WebInspector.TextEditor.prototype.reveal):
     47        (WebInspector.TextEditor.prototype.packAndRepaintAll):
     48        (WebInspector.TextEditor.prototype._updateSize):
     49        (WebInspector.TextEditor.prototype.updateCanvasSize):
     50        (WebInspector.TextEditor.prototype.repaintAll):
     51        (WebInspector.TextEditor.prototype._paintLinesContinuation):
     52        (WebInspector.TextEditor.prototype._repaintOnScroll):
     53        (WebInspector.TextEditor.prototype._mouseDown):
     54        (WebInspector.TextEditor.prototype._contextMenu):
     55        (WebInspector.TextEditor.prototype._caretForMouseEvent):
     56        (WebInspector.TextEditor.prototype._columnForOffset):
     57        (WebInspector.TextEditor.prototype._handleNavigationKey):
     58        (WebInspector.TextEditor.prototype._positionDivDecoration):
     59        (WebInspector.TextEditor.prototype._replaceSelectionWith):
     60        (WebInspector.TextEditor.prototype.setCoalescingUpdate):
     61        (WebInspector.TextEditor.prototype._handleUndo):
     62        (WebInspector.TextEditor.prototype._handleRedo):
     63        (WebInspector.TextEditor.prototype._changeFont):
     64        * inspector/front-end/TextEditorHighlighter.js:
     65        (WebInspector.TextEditorHighlighter):
     66        (WebInspector.TextEditorHighlighter.prototype.set mimeType):
     67        * inspector/front-end/inspector.css:
     68        * inspector/front-end/textEditor.css:
     69
     702010-01-26  Pavel Feldman  <pfeldman@chromium.org>
     71
     72        Reviewed by Timothy Hatcher.
    473
    574        Web Inspector: add methods for getting resource content from within frontend.
  • trunk/WebCore/inspector/front-end/SourceFrame2.js

    r53795 r53856  
    2929 */
    3030
    31 WebInspector.SourceFrame2 = function()
     31WebInspector.SourceFrame2 = function(addBreakpointDelegate)
    3232{
    3333    this._editor = new WebInspector.TextEditor(WebInspector.platform);
     
    3939    this._rowMessages = {};
    4040    this._messageBubbles = {};
     41    this.breakpoints = [];
     42    this._shortcuts = {};
    4143    this.element = this._editor.element;
     44    this.element.addEventListener("keydown", this._keyDown.bind(this), true);
     45    this._loaded = false;
     46
     47    this.addBreakpointDelegate = addBreakpointDelegate;
    4248}
    4349
    4450WebInspector.SourceFrame2.prototype = {
    45     set text(text)
    46     {
    47         this._editor.text = text;
     51
     52    get executionLine()
     53    {
     54        return this._executionLine;
     55    },
     56
     57    set executionLine(x)
     58    {
     59        if (this._executionLine === x)
     60            return;
     61        this._executionLine = x;
     62        this._editor.repaintAll();
     63    },
     64
     65    revealLine: function(lineNumber)
     66    {
     67        if (!this._loaded)
     68            this._lineNumberToReveal = lineNumber;
     69        else
     70            this._editor.reveal(lineNumber - 1, 0);
     71    },
     72
     73    addBreakpoint: function(breakpoint)
     74    {
     75        this.breakpoints.push(breakpoint);
     76        breakpoint.addEventListener("enabled", this._breakpointChanged, this);
     77        breakpoint.addEventListener("disabled", this._breakpointChanged, this);
     78        breakpoint.addEventListener("condition-changed", this._breakpointChanged, this);
     79        this._addBreakpointToSource(breakpoint);
     80    },
     81
     82    removeBreakpoint: function(breakpoint)
     83    {
     84        this.breakpoints.remove(breakpoint);
     85        breakpoint.removeEventListener("enabled", null, this);
     86        breakpoint.removeEventListener("disabled", null, this);
     87        breakpoint.removeEventListener("condition-changed", null, this);
     88        this._removeBreakpointFromSource(breakpoint);
    4889    },
    4990
     
    68109        this._messageBubbles = {};
    69110        this._editor.packAndRepaintAll();
     111    },
     112
     113    sizeToFitContentHeight: function()
     114    {
     115        this._editor.packAndRepaintAll();
     116    },
     117
     118    setContent: function(mimeType, content)
     119    {
     120        this._loaded = true;
     121        this._editor.mimeType = mimeType;
     122        this._editor.text = content;
     123
     124        this._addExistingMessagesToSource();
     125        this._addExistingBreakpointsToSource();
     126        if (this._executionLine)
     127            this.revealLine(this._executionLine);
     128
     129        if (this._lineNumberToReveal) {
     130            this.revealLine(this._lineNumberToReveal);
     131            delete this._lineNumberToReveal;
     132        }
     133        this._editor.setCoalescingUpdate(true);
     134        this._editor.updateCanvasSize();
     135        this._editor.packAndRepaintAll();
     136        this._editor.setCoalescingUpdate(false);
     137    },
     138
     139    findSearchMatches: function(query)
     140    {
     141        var ranges = [];
     142        for (var i = 0; i < this._textModel.linesCount; ++i) {
     143            var line = this._textModel.line(i);
     144            var column = line.indexOf(query);
     145            if (column === -1)
     146                continue;
     147            ranges.push(new WebInspector.TextRange(i, column, i, column + query.length));
     148        }
     149        return ranges;
     150    },
     151
     152    setSelection: function(range)
     153    {
     154        this._editor.setSelection(range.startLine, range.startColumn, range.endLine, range.endColumn);
    70155    },
    71156
     
    102187            messageBubbleElement.className = "webkit-html-message-bubble";
    103188            this._messageBubbles[msg.line] = messageBubbleElement;
    104             this._editor.setDivDecoration(msg.line, messageBubbleElement);
     189            this._editor.setDivDecoration(msg.line - 1, messageBubbleElement);
    105190        }
    106191
     
    149234    },
    150235
    151     get executionLine()
    152     {
    153         return this._executionLine;
    154     },
    155 
    156     set executionLine(x)
    157     {
    158         this._executionLine = x;
    159     },
    160 
    161     revealLine: function(lineNumber)
    162     {
    163         this._editor.reveal(lineNumber, 0);
    164     },
    165 
    166     _toggleBreakpoint: function(lineNumber)
    167     {
    168         if (this._textModel.getAttribute(lineNumber, "breakpoint"))
    169             this._textModel.removeAttribute(lineNumber, "breakpoint");
    170         else
    171             this._textModel.setAttribute(lineNumber, "breakpoint", { disabled: false, conditional: false });
     236    _addExistingBreakpointsToSource: function()
     237    {
     238        var length = this.breakpoints.length;
     239        for (var i = 0; i < length; ++i)
     240            this._addBreakpointToSource(this.breakpoints[i]);
     241    },
     242
     243    _addBreakpointToSource: function(breakpoint)
     244    {
     245        this._textModel.setAttribute(breakpoint.line - 1, "breakpoint", breakpoint);
    172246        this._editor.paintLineNumbers();
    173247    },
    174248
     249    _removeBreakpointFromSource: function(breakpoint)
     250    {
     251        this._textModel.removeAttribute(breakpoint.line - 1, "breakpoint");
     252        this._editor.paintLineNumbers();
     253    },
     254
     255    _contextMenu: function(lineNumber, event)
     256    {
     257        if (!this.addBreakpointDelegate)
     258            return;
     259
     260        var contextMenu = new WebInspector.ContextMenu();
     261
     262        var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
     263        if (!breakpoint) {
     264            // This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
     265            contextMenu.appendItem(WebInspector.UIString("Add Breakpoint"), this.addBreakpointDelegate.bind(this, lineNumber + 1));
     266
     267            function addConditionalBreakpoint()
     268            {
     269                this.addBreakpointDelegate(lineNumber + 1);
     270                var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
     271                if (breakpoint)
     272                    this._editBreakpointCondition(breakpoint);
     273            }
     274
     275            contextMenu.appendItem(WebInspector.UIString("Add Conditional Breakpoint..."), addConditionalBreakpoint.bind(this));
     276        } else {
     277            // This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
     278            contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), WebInspector.panels.scripts.removeBreakpoint.bind(WebInspector.panels.scripts, breakpoint));
     279            contextMenu.appendItem(WebInspector.UIString("Edit Breakpoint..."), this._editBreakpointCondition.bind(this, breakpoint));
     280            if (breakpoint.enabled)
     281                contextMenu.appendItem(WebInspector.UIString("Disable Breakpoint"), function() { breakpoint.enabled = false; });
     282            else
     283                contextMenu.appendItem(WebInspector.UIString("Enable Breakpoint"), function() { breakpoint.enabled = true; });
     284        }
     285        contextMenu.show(event);
     286    },
     287
     288    _toggleBreakpoint: function(lineNumber, event)
     289    {
     290        if (event.button != 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey)
     291            return;
     292        var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
     293        if (breakpoint)
     294            WebInspector.panels.scripts.removeBreakpoint(breakpoint);
     295        else if (this.addBreakpointDelegate)
     296            this.addBreakpointDelegate(lineNumber + 1);
     297        event.preventDefault();
     298    },
     299
     300    _editBreakpointCondition: function(breakpoint)
     301    {
     302        this._showBreakpointConditionPopup(breakpoint.line);
     303
     304        function committed(element, newText)
     305        {
     306            breakpoint.condition = newText;
     307            this._editor.paintLineNumbers();
     308            dismissed.call(this);
     309        }
     310
     311        function dismissed()
     312        {
     313            this._editor.setDivDecoration(breakpoint.line - 1, null);
     314            delete this._conditionEditorElement;
     315        }
     316
     317        var dismissedHandler = dismissed.bind(this);
     318        this._conditionEditorElement.addEventListener("blur", dismissedHandler, false);
     319
     320        WebInspector.startEditing(this._conditionEditorElement, committed.bind(this), dismissedHandler);
     321        this._conditionEditorElement.value = breakpoint.condition;
     322        this._conditionEditorElement.select();
     323    },
     324
     325    _showBreakpointConditionPopup: function(lineNumber)
     326    {
     327        var conditionElement = this._createConditionElement(lineNumber);
     328        this._editor.setDivDecoration(lineNumber - 1, conditionElement);
     329    },
     330
     331    _createConditionElement: function(lineNumber)
     332    {
     333        var conditionElement = document.createElement("div");
     334        conditionElement.className = "source-breakpoint-condition";
     335
     336        var labelElement = document.createElement("label");
     337        labelElement.className = "source-breakpoint-message";
     338        labelElement.htmlFor = "source-breakpoint-condition";
     339        labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber)));
     340        conditionElement.appendChild(labelElement);
     341
     342        var editorElement = document.createElement("input");
     343        editorElement.id = "source-breakpoint-condition";
     344        editorElement.type = "text"
     345        conditionElement.appendChild(editorElement);
     346        this._conditionEditorElement = editorElement;
     347
     348        return conditionElement;
     349    },
     350
     351    _keyDown: function(event)
     352    {
     353        var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
     354        var handler = this._shortcuts[shortcut];
     355        if (handler) {
     356            handler(event);
     357            event.preventDefault();
     358        } else {
     359            WebInspector.documentKeyDown(event);
     360        }
     361    },
     362
     363    _evalSelectionInCallFrame: function(event)
     364    {
     365        if (!WebInspector.panels.scripts || !WebInspector.panels.scripts.paused)
     366            return;
     367
     368        var selection = this.element.contentWindow.getSelection();
     369        if (!selection.rangeCount)
     370            return;
     371
     372        var expression = selection.getRangeAt(0).toString().trimWhitespace();
     373        WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, "console", function(result, exception) {
     374            WebInspector.showConsole();
     375            var commandMessage = new WebInspector.ConsoleCommand(expression);
     376            WebInspector.console.addMessage(commandMessage);
     377            WebInspector.console.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
     378        });
     379    },
     380
     381    _breakpointChanged: function(event)
     382    {
     383        this._editor.paintLineNumbers();
     384    },
     385
    175386    resize: function()
    176387    {
    177         this._editor.packAndRepaintAll();
     388        this._editor.updateCanvasSize();
    178389    }
    179390}
     
    191402    {
    192403        var breakpoint = this._textModel.getAttribute(lineNumber, "breakpoint");
    193         var isExecutionLine = lineNumber === this._sourceFrame._executionLine;
     404        var isExecutionLine = lineNumber + 1 === this._sourceFrame._executionLine;
    194405        if (breakpoint || isExecutionLine) {
    195406            ctx.save();
     
    199410   
    200411            if (breakpoint)
    201                 this._paintBreakpoint(ctx, breakpointWidth, breakpointHeight, breakpoint.conditional, breakpoint.disabled);
     412                this._paintBreakpoint(ctx, breakpointWidth, breakpointHeight, breakpoint);
    202413   
    203414            if (isExecutionLine)
     
    216427    },
    217428
    218     _paintBreakpoint: function(ctx, width, height, conditional, disabled)
     429    _paintBreakpoint: function(ctx, width, height, breakpoint)
    219430    {
    220431        ctx.beginPath();
     
    227438        ctx.lineTo(0, height - 2);
    228439        ctx.closePath();
    229         ctx.fillStyle = conditional ? "rgb(217, 142, 1)" : "rgb(1, 142, 217)";
    230         ctx.strokeStyle = conditional ? "rgb(205, 103, 0)" : "rgb(0, 103, 205)";
     440        ctx.fillStyle = breakpoint.condition ? "rgb(217, 142, 1)" : "rgb(1, 142, 217)";
     441        ctx.strokeStyle = breakpoint.condition ? "rgb(205, 103, 0)" : "rgb(0, 103, 205)";
    231442        ctx.lineWidth = 3;
    232443        ctx.fill();
     
    237448        ctx.restore();
    238449
    239         if (disabled) {
     450        if (!breakpoint.enabled) {
    240451            ctx.save();
    241452            ctx.globalCompositeOperation = "destination-out";
    242453            ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
    243             ctx.fillRect(0, 0, breakpointWidth, breakpointHeight);
     454            ctx.fillRect(0, 0, width, height);
    244455            ctx.restore();
    245456        }
     
    276487    mouseDown: function(lineNumber, e)
    277488    {
    278         this._sourceFrame._toggleBreakpoint(lineNumber);
     489        this._sourceFrame._toggleBreakpoint(lineNumber, e);
     490        return true;
     491    },
     492
     493    contextMenu: function(lineNumber, e)
     494    {
     495        this._sourceFrame._contextMenu(lineNumber, e);
    279496        return true;
    280497    }
     
    289506    decorate: function(lineNumber, ctx, x, y, width, height, lineHeight)
    290507    {
    291         if (this._sourceFrame._executionLine !== lineNumber)
     508        if (this._sourceFrame._executionLine !== lineNumber + 1)
    292509            return;
    293510        ctx.save();
  • trunk/WebCore/inspector/front-end/TextEditor.js

    r53795 r53856  
    6565    this._sheet.addEventListener("mouseout", this._mouseOut.bind(this), false);
    6666    this._sheet.addEventListener("dblclick", this._dblClick.bind(this), false);
     67    this._sheet.addEventListener("contextmenu", this._contextMenu.bind(this), false);
    6768    this.element.addEventListener("keydown", this._keyDown.bind(this), false);
    6869    this.element.addEventListener("textInput", this._textInput.bind(this), false);
     
    111112    },
    112113
     114    set mimeType(mimeType)
     115    {
     116        this._highlighter.mimeType = mimeType;
     117    },
     118
    113119    get textModel()
    114120    {
     
    119125    {
    120126        this._readOnly = readOnly;
     127        if (readOnly)
     128            this.element.addStyleClass("text-editor-readonly")
     129        else
     130            this.element.removeStyleClass("text-editor-readonly")
    121131    },
    122132
     
    143153        if (divDecoration && divDecoration.element && divDecoration.element.parentNode)
    144154            divDecoration.element.parentNode.removeChild(divDecoration.element);
    145 
    146         divDecoration = { element: element };
    147         this.element.appendChild(element);
    148 
    149         this._textModel.setAttribute(lineNumber, "div-decoration", divDecoration);
     155        this._textModel.removeAttribute(lineNumber, "div-decoration");
     156
     157        if (element) {
     158            divDecoration = { element: element };
     159            this.element.appendChild(element);
     160   
     161            this._textModel.setAttribute(lineNumber, "div-decoration", divDecoration);
     162        }
     163
    150164        this.packAndRepaintAll();
    151165    },
     
    203217        var minScrollTop = maxScrollTop + this._lineHeight(line) - this._canvas.height;
    204218        if (this._scrollTop > maxScrollTop)
    205             this._container.scrollTop = maxScrollTop;
     219            this._container.scrollTop = maxScrollTop - this._textLineHeight * 2;
    206220        else if (this._scrollTop < minScrollTop)
    207             this._container.scrollTop = minScrollTop;
     221            this._container.scrollTop = minScrollTop + this._textLineHeight * 2;
    208222
    209223        var firstColumn = this._columnForOffset(line, this._scrollLeft);
     
    265279    packAndRepaintAll: function()
    266280    {
    267         this._setCoalescingUpdate(true);
     281        this.setCoalescingUpdate(true);
    268282        this._lineOffsetsCache = [0];
    269283        this._updateSize(0, this._textModel.linesCount);
    270         this._repaintAll();
    271         this._setCoalescingUpdate(false);
     284        this.repaintAll();
     285        this.setCoalescingUpdate(false);
    272286    },
    273287
    274288    _updateSize: function(startLine, endLine)
    275289    {
    276         this._setCoalescingUpdate(true);
     290        this.setCoalescingUpdate(true);
    277291        var guardedEndLine = Math.min(this._textModel.linesCount, endLine + 1);
    278292        var newMaximum = false;
     
    308322        if (newLineNumberDigits !== this._lineNumberDigits) {
    309323            this._lineNumberDigits = newLineNumberDigits;
    310             this._repaintAll();
     324            this.repaintAll();
    311325        }
    312326
    313327        // Changes to size can change the client area (scrollers can appear/disappear)
    314328        this.updateCanvasSize();
    315         this._setCoalescingUpdate(false);
     329        this.setCoalescingUpdate(false);
    316330    },
    317331
     
    321335            this._canvas.width = this._container.clientWidth;
    322336            this._canvas.height = this._container.clientHeight;
    323             this._repaintAll();
    324         }
    325     },
    326 
    327     _repaintAll: function()
     337            this.repaintAll();
     338        }
     339    },
     340
     341    repaintAll: function()
    328342    {
    329343        this._invalidateLines(0, this._textModel.linesCount);
     
    430444            }
    431445
     446            if (line.length > 1000) {
     447                // Optimization: no need to paint decorations outside visible area.
     448                var firstColumn = this._columnForOffset(i, this._scrollLeft);
     449                var lastColumn = this._columnForOffset(i, this._scrollLeft + this._canvas.width);
     450            }
    432451            var highlighterState = this._textModel.getAttribute(i, "highlighter-state");
    433452            var plainTextStart = -1;
    434453            for (var j = 0; j < line.length;) {
    435454                var attribute = highlighterState && highlighterState.attributes[j];
     455                if (attribute && firstColumn && j + attribute.length < firstColumn) {
     456                    j += attribute.length;
     457                    continue;
     458                }
     459                if (attribute && lastColumn && j > lastColumn)
     460                    break;
    436461                if (!attribute || !attribute.style) {
    437462                    if (plainTextStart === -1)
     
    451476            if (plainTextStart !== -1) {
    452477                this._ctx.fillStyle = "rgb(0,0,0)";
    453                 this._ctx.fillText(line.substring(plainTextStart, line.length), this._lineNumberWidth - this._scrollLeft + this._columnToOffset(i, plainTextStart), lineOffset + this._textLineHeight);
     478                this._ctx.fillText(line.substring(plainTextStart, j), this._lineNumberWidth - this._scrollLeft + this._columnToOffset(i, plainTextStart), lineOffset + this._textLineHeight);
    454479            }
    455480        }
     
    498523            this._scrollTop = this._container.scrollTop;
    499524            this._scrollLeft = this._container.scrollLeft;
    500             this._repaintAll();
     525            this.repaintAll();
    501526        }
    502527    },
     
    511536        var location = this._caretForMouseEvent(e);
    512537
    513         if (e.x < this._lineNumberWidth && this._lineNumberDecorator) {
     538        if (e.offsetX < this._lineNumberWidth && this._lineNumberDecorator) {
    514539            if (this._lineNumberDecorator.mouseDown(location.line, e))           
    515540                return;
     
    543568    },
    544569
     570    _contextMenu: function(e)
     571    {
     572        if (e.offsetX < this._lineNumberWidth && this._lineNumberDecorator) {
     573            var location = this._caretForMouseEvent(e);
     574            var line = location.line;
     575            if (this._lineNumberDecorator.contextMenu(location.line, e))
     576                return;
     577        }
     578    },
     579
    545580    _caretForMouseEvent: function(e)
    546581    {
    547         var lineNumber = Math.max(0, this._offsetToLine(e.y + this._scrollTop) - 1);
     582        var lineNumber = Math.max(0, this._offsetToLine(e.offsetY) - 1);
    548583        var line = this._textModel.line(lineNumber);
    549         var offset = e.x + this._scrollLeft - this._lineNumberWidth - this._digitWidth;
     584        var offset = e.offsetX + this._scrollLeft - this._lineNumberWidth - this._digitWidth;
    550585        return { line: lineNumber, column: this._columnForOffset(lineNumber, offset) };
    551586    },
     
    553588    _columnForOffset: function(lineNumber, offset)
    554589    {
     590        var length = 0;
    555591        var line = this._textModel.line(lineNumber);
    556592        for (var column = 0; column < line.length; ++column) {
    557             if (this._ctx.measureText(line.substring(0, column)).width > offset)
     593            if (length > offset)
    558594                break;
     595            length += this._ctx.measureText(line.charAt(column)).width;
    559596        }
    560597        return column;
     
    646683                    }
    647684                }
     685                break;
     686            case keyCodes.Home:
     687                if (this._isMetaCtrl(e))
     688                    arrowAction.call(this, 0, 0, true);
     689                else
     690                    arrowAction.call(this, this._selection.endLine, 0);
     691                break;
     692            case keyCodes.End:
     693                if (this._isMetaCtrl(e))
     694                    arrowAction.call(this, this._textModel.linesCount - 1, this._textModel.lineLength(this._textModel.linesCount - 1), true);
     695                else
     696                    arrowAction.call(this, this._selection.endLine, this._textModel.lineLength(this._selection.endLine));
    648697                break;
    649698            case keyCodes.Left:
     
    735784        divDecoration.element.style.top = this._lineToOffset(lineNumber) - this._scrollTop + this._textLineHeight + "px";
    736785        divDecoration.element.style.left = this._lineNumberWidth + "px";
    737         divDecoration.element.style.setProperty("max-width", (this._canvas.width - 200) + "px");
     786        divDecoration.element.style.setProperty("max-width", this._canvas.width + "px");
    738787    },
    739788
     
    840889    {
    841890        var range = overrideRange || this._selection.range();
    842         this._setCoalescingUpdate(true);
     891        this.setCoalescingUpdate(true);
    843892        var newRange = this._textModel.setText(range, newText);
    844893        this._setCaretLocation(newRange.endLine, newRange.endColumn);
    845         this._setCoalescingUpdate(false);
    846     },
    847 
    848     _setCoalescingUpdate: function(enabled)
     894        this.setCoalescingUpdate(false);
     895    },
     896
     897    setCoalescingUpdate: function(enabled)
    849898    {
    850899        if (enabled)
     
    908957    _handleUndo: function()
    909958    {
    910         this._setCoalescingUpdate(true);
     959        this.setCoalescingUpdate(true);
    911960        var range = this._textModel.undo();
    912961        if (range)
    913962            this._setCaretLocation(range.endLine, range.endColumn);
    914         this._setCoalescingUpdate(false);
     963        this.setCoalescingUpdate(false);
    915964    },
    916965
    917966    _handleRedo: function()
    918967    {
    919         this._setCoalescingUpdate(true);
     968        this.setCoalescingUpdate(true);
    920969        var range = this._textModel.redo();
    921970        if (range)
    922971            this._setCaretLocation(range.endLine, range.endColumn);
    923         this._setCoalescingUpdate(false);
     972        this.setCoalescingUpdate(false);
    924973    },
    925974
     
    9861035        this._initFont(sansSerif, fontSize);
    9871036        this._updateSize(0, this._textModel.linesCount);
    988         this._repaintAll();
     1037        this.repaintAll();
    9891038    },
    9901039
  • trunk/WebCore/inspector/front-end/TextEditorHighlighter.js

    r53846 r53856  
    3333{
    3434    this._textModel = textModel;
    35     this._tokenizer = new WebInspector.SourceCSSTokenizer();
    3635
    3736    this._styles = [];
     
    6059    this._styles["js-number"] = "rgb(28, 0, 207)";
    6160
     61    this._tokenizers = {};
     62    this._tokenizerConstructors = {
     63        "text/css": WebInspector.SourceCSSTokenizer,
     64        "text/html": WebInspector.SourceHTMLTokenizer,
     65        "text/javascript": WebInspector.SourceJavaScriptTokenizer
     66    };
     67
     68    this.mimeType = "text/html";
    6269    this._damageCallback = damageCallback;   
    6370}
    6471
    6572WebInspector.TextEditorHighlighter.prototype = {
     73    set mimeType(mimeType)
     74    {
     75        if (!this._tokenizerConstructors[mimeType])
     76            return;
     77        this._tokenizer = this._tokenizers[mimeType];
     78        if (!this._tokenizer) {
     79            this._tokenizer = new this._tokenizerConstructors[mimeType]();
     80            this._tokenizers[mimeType] = this._tokenizer;
     81        }
     82    },
     83
    6684    highlight: function(endLine)
    6785    {
  • trunk/WebCore/inspector/front-end/inspector.css

    r53806 r53856  
    38013801}
    38023802
    3803 .text-editor {
    3804     position: absolute;
    3805     top:0;
    3806     left:0;
    3807     right:0;
    3808     bottom:0;
    3809     -webkit-user-select: text;
    3810     -webkit-user-modify: read-write-plaintext-only;
    3811 }
    3812 
    3813 .text-editor-canvas {
    3814     position: absolute;
    3815     top:0;
    3816     left:0;
    3817     right:0;
    3818     bottom:0;
    3819     z-index: 10;
    3820     pointer-events: none;
    3821 }
    3822 
    3823 .text-editor-container {
    3824     position: absolute;
    3825     top:0;
    3826     left:0;
    3827     right:0;
    3828     bottom:0;
    3829     overflow: auto;
    3830 }
    3831 
    3832 .text-editor-clip {
    3833     opacity: 0;
    3834     position: absolute;
    3835     top:0;
    3836     left:0;
    3837     pointer-events: none;
    3838 }
    3839 
    3840 .text-editor-cursor {
    3841     -webkit-user-select: none;
    3842     -webkit-user-modify: none;
    3843     position: absolute;
    3844     top:0;
    3845     left:0;
    3846     width:1px;
    3847     height: 14px;
    3848     z-index: 20;
    3849     background-color: black;
    3850     pointer-events: none;
    3851 }
     3803.source-breakpoint-condition {
     3804    position: absolute;
     3805    z-index: 30;
     3806    padding: 4px;
     3807    background-color: rgb(203, 226, 255);
     3808    -webkit-border-radius: 7px;
     3809    border: 2px solid rgb(169, 172, 203);
     3810    width: 90%;
     3811}
     3812
     3813.source-breakpoint-message {
     3814    background-color: transparent;
     3815    font-family: Lucida Grande, sans-serif;
     3816    font-weight: normal;
     3817    font-size: 11px;
     3818    text-align: left;
     3819    text-shadow: none;
     3820    color: rgb(85, 85, 85);
     3821    cursor: default;
     3822    margin: 0 0 2px 0;
     3823}
     3824
     3825#source-breakpoint-condition {
     3826    font-family: monospace;
     3827    margin: 0;
     3828    border: 1px inset rgb(190, 190, 190) !important;
     3829    width: 100%;
     3830    box-shadow: none !important;
     3831    outline: none !important;
     3832    -webkit-user-modify: read-write;
     3833}
  • trunk/WebCore/inspector/front-end/textEditor.css

    r53795 r53856  
     1.text-editor {
     2    position: absolute;
     3    top:0;
     4    left:0;
     5    right:0;
     6    bottom:0;
     7    -webkit-user-select: text;
     8    -webkit-user-modify: read-write-plaintext-only;
     9}
     10
     11.text-editor-readonly {
     12    -webkit-user-modify: read-only;
     13}
     14
     15.text-editor-canvas {
     16    position: absolute;
     17    top:0;
     18    left:0;
     19    right:0;
     20    bottom:0;
     21    z-index: 10;
     22    pointer-events: none;
     23}
     24
     25.text-editor-container {
     26    position: absolute;
     27    top:0;
     28    left:0;
     29    right:0;
     30    bottom:0;
     31    overflow: auto;
     32}
     33
     34.text-editor-clip {
     35    opacity: 0;
     36    position: absolute;
     37    top:0;
     38    left:0;
     39    pointer-events: none;
     40}
     41
     42.text-editor-cursor {
     43    -webkit-user-select: none;
     44    -webkit-user-modify: none;
     45    position: absolute;
     46    top:0;
     47    left:0;
     48    width:1px;
     49    height: 14px;
     50    z-index: 20;
     51    background-color: black;
     52    pointer-events: none;
     53}
     54
    155.webkit-html-message-bubble {
    256    -webkit-box-shadow: black 0px 2px 5px;
Note: See TracChangeset for help on using the changeset viewer.