Changeset 147415 in webkit


Ignore:
Timestamp:
Apr 2, 2013 3:49:31 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: Separate JavaScriptSourceFrame popover from knowledge of editor's DOM
https://bugs.webkit.org/show_bug.cgi?id=113412

Patch by Andrey Lushnikov <lushnikov@chromium.org> on 2013-04-02
Reviewed by Pavel Feldman.

  • Use TextEditor.coordinatesToCursorPosition,

TextEditor.cursorPositionToCoordinates and TextEditor.tokenAtTextPosition to figure out
hovering area and create popover anchor.

  • Use TextEditor.highlightRange/TextEditor.removeHighlight methods to

highlight hovering text in editor.

No new tests: no change in behaviour.

  • inspector/front-end/DefaultTextEditor.js:
  • inspector/front-end/JavaScriptSourceFrame.js:

(WebInspector.JavaScriptSourceFrame):
(WebInspector.JavaScriptSourceFrame.prototype.willHide):
(WebInspector.JavaScriptSourceFrame.prototype._getPopoverAnchor):
(WebInspector.JavaScriptSourceFrame.prototype.):
(WebInspector.JavaScriptSourceFrame.prototype._resolveObjectForPopover):
(WebInspector.JavaScriptSourceFrame.prototype._onHidePopover):

  • inspector/front-end/inspector.css:

(.popover-anchor):
(.source-frame-eval-expression):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r147414 r147415  
     12013-04-02  Andrey Lushnikov  <lushnikov@chromium.org>
     2
     3        Web Inspector: Separate JavaScriptSourceFrame popover from knowledge of editor's DOM
     4        https://bugs.webkit.org/show_bug.cgi?id=113412
     5
     6        Reviewed by Pavel Feldman.
     7
     8        - Use TextEditor.coordinatesToCursorPosition,
     9        TextEditor.cursorPositionToCoordinates and TextEditor.tokenAtTextPosition to figure out
     10        hovering area and create popover anchor.
     11        - Use TextEditor.highlightRange/TextEditor.removeHighlight methods to
     12        highlight hovering text in editor.
     13
     14        No new tests: no change in behaviour.
     15
     16        * inspector/front-end/DefaultTextEditor.js:
     17        * inspector/front-end/JavaScriptSourceFrame.js:
     18        (WebInspector.JavaScriptSourceFrame):
     19        (WebInspector.JavaScriptSourceFrame.prototype.willHide):
     20        (WebInspector.JavaScriptSourceFrame.prototype._getPopoverAnchor):
     21        (WebInspector.JavaScriptSourceFrame.prototype.):
     22        (WebInspector.JavaScriptSourceFrame.prototype._resolveObjectForPopover):
     23        (WebInspector.JavaScriptSourceFrame.prototype._onHidePopover):
     24        * inspector/front-end/inspector.css:
     25        (.popover-anchor):
     26        (.source-frame-eval-expression):
     27
    1282013-04-02  Mihnea Ovidenie  <mihnea@adobe.com>
    229
  • trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js

    r147322 r147415  
    641641
    642642    /**
    643      * @param {Element} element
    644      * @param {Object} skipClasses
    645      * @param {Object} skipTokens
    646      * @return {Element}
    647      */
    648     highlightExpression: function(element, skipClasses, skipTokens)
    649     {
    650         // Collect tokens belonging to evaluated expression.
    651         var tokens = [element];
    652         var token = element.previousSibling;
    653         while (token && (skipClasses[token.className] || skipTokens[token.textContent.trim()])) {
    654             tokens.push(token);
    655             token = token.previousSibling;
    656         }
    657         tokens.reverse();
    658 
    659         // Wrap them with highlight element.
    660         this._mainPanel.beginDomUpdates();
    661         var parentElement = element.parentElement;
    662         var nextElement = element.nextSibling;
    663         var container = document.createElement("span");
    664         for (var i = 0; i < tokens.length; ++i)
    665             container.appendChild(tokens[i]);
    666         parentElement.insertBefore(container, nextElement);
    667         this._mainPanel.endDomUpdates();
    668         return container;
    669     },
    670 
    671     /**
    672      * @param {Element} highlightElement
    673      */
    674     hideHighlightedExpression: function(highlightElement)
    675     {
    676         this._mainPanel.beginDomUpdates();
    677         var parentElement = highlightElement.parentElement;
    678         if (parentElement) {
    679             var child = highlightElement.firstChild;
    680             while (child) {
    681                 var nextSibling = child.nextSibling;
    682                 parentElement.insertBefore(child, highlightElement);
    683                 child = nextSibling;
    684             }
    685             parentElement.removeChild(highlightElement);
    686         }
    687         this._mainPanel.endDomUpdates();
    688     },
    689 
    690     /**
    691643     * @param {number} scrollTop
    692644     * @param {number} clientHeight
  • trunk/Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js

    r147106 r147415  
    6161    this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
    6262    this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
    63    
     63
    6464    this._updateScriptFile();
    6565}
     
    222222        if (window.getSelection().type === "Range")
    223223            return null;
    224         var lineElement = element.enclosingNodeOrSelfWithClass("webkit-line-content");
    225         if (!lineElement)
     224
     225        var textPosition = this.textEditor.coordinatesToCursorPosition(event.x, event.y);
     226        if (!textPosition)
    226227            return null;
    227228
    228         if (element.hasStyleClass("webkit-javascript-ident"))
    229             return element;
    230 
    231         if (element.hasStyleClass("source-frame-token"))
    232             return element;
    233 
    234         // We are interested in identifiers and "this" keyword.
    235         if (element.hasStyleClass("webkit-javascript-keyword"))
    236             return element.textContent === "this" ? element : null;
    237 
    238         if (element !== lineElement || lineElement.childElementCount)
     229        var token = this.textEditor.tokenAtTextPosition(textPosition.startLine, textPosition.startColumn);
     230        if (!token)
    239231            return null;
    240 
    241         // Handle non-highlighted case
    242         // 1. Collect ranges of identifier suspects
    243         var lineContent = lineElement.textContent;
    244         var ranges = [];
    245         var regex = new RegExp("[a-zA-Z_\$0-9]+", "g");
    246         var match;
    247         while (regex.lastIndex < lineContent.length && (match = regex.exec(lineContent)))
    248             ranges.push({offset: match.index, length: regex.lastIndex - match.index});
    249 
    250         // 2. 'highlight' them with artificial style to detect word boundaries
    251         var changes = [];
    252         this.textEditor.highlightRangesWithStyleClass(lineElement, ranges, "source-frame-token", changes);
    253         var lineOffsetLeft = lineElement.totalOffsetLeft();
    254         for (var child = lineElement.firstChild; child; child = child.nextSibling) {
    255             if (child.nodeType !== Node.ELEMENT_NODE || !child.hasStyleClass("source-frame-token"))
    256                 continue;
    257             if (event.x > lineOffsetLeft + child.offsetLeft && event.x < lineOffsetLeft + child.offsetLeft + child.offsetWidth) {
    258                 var text = child.textContent;
    259                 return (text === "this" || !WebInspector.SourceJavaScriptTokenizer.Keywords[text]) ? child : null;
    260             }
    261         }
    262         return null;
    263     },
    264 
    265     _resolveObjectForPopover: function(element, showCallback, objectGroupName)
    266     {
    267         this._highlightElement = this._highlightExpression(element);
    268 
     232        var lineNumber = textPosition.startLine;
     233        var line = this.textEditor.line(lineNumber);
     234        var tokenContent = line.substring(token.startColumn, token.endColumn + 1);
     235        if (token.type !== "javascript-ident" && (token.type !== "javascript-keyword" || tokenContent !== "this"))
     236            return null;
     237
     238        var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.startColumn);
     239        var rightCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.endColumn + 1);
     240        var anchorBox = new AnchorBox(leftCorner.x, leftCorner.y, rightCorner.x - leftCorner.x, leftCorner.height);
     241
     242        anchorBox.token = token;
     243        anchorBox.lineNumber = lineNumber;
     244
     245        return anchorBox;
     246    },
     247
     248    _resolveObjectForPopover: function(anchorBox, showCallback, objectGroupName)
     249    {
    269250        /**
    270251         * @param {?RuntimeAgent.RemoteObject} result
     
    277258                return;
    278259            }
    279             showCallback(WebInspector.RemoteObject.fromPayload(result), wasThrown, this._highlightElement);
     260            this._popoverAnchorBox = anchorBox;
     261            showCallback(WebInspector.RemoteObject.fromPayload(result), wasThrown, this._popoverAnchorBox);
    280262            // Popover may have been removed by showCallback().
    281             if (this._highlightElement)
    282                 this._highlightElement.addStyleClass("source-frame-eval-expression");
     263            if (this._popoverAnchorBox) {
     264                var highlightRange = new WebInspector.TextRange(anchorBox.lineNumber, startHighlight, anchorBox.lineNumber, endHighlight);
     265                this._popoverAnchorBox._highlightDescriptor = this.textEditor.highlightRange(highlightRange, "source-frame-eval-expression");
     266            }
    283267        }
    284268
     
    287271            return;
    288272        }
     273
     274        var startHighlight = anchorBox.token.startColumn;
     275        var endHighlight = anchorBox.token.endColumn;
     276        var line = this.textEditor.line(anchorBox.lineNumber);
     277        while (startHighlight > 1 && line.charAt(startHighlight - 1) === '.')
     278            startHighlight = this.textEditor.tokenAtTextPosition(anchorBox.lineNumber, startHighlight - 2).startColumn;
     279        var evaluationText = line.substring(startHighlight, endHighlight + 1);
     280
    289281        var selectedCallFrame = WebInspector.debuggerModel.selectedCallFrame();
    290         selectedCallFrame.evaluate(this._highlightElement.textContent, objectGroupName, false, true, false, false, showObjectPopover.bind(this));
     282        selectedCallFrame.evaluate(evaluationText, objectGroupName, false, true, false, false, showObjectPopover.bind(this));
    291283    },
    292284
    293285    _onHidePopover: function()
    294286    {
    295         // Replace higlight element with its contents inplace.
    296         var highlightElement = this._highlightElement;
    297         if (!highlightElement)
    298             return;
    299         // FIXME: the text editor should maintain highlight on its own. The check below is a workaround for
    300         // the case when highlight element is detached from DOM by the TextEditor when re-building the DOM.
    301         this.textEditor.hideHighlightedExpression(highlightElement);
    302         delete this._highlightElement;
    303     },
    304 
    305     /**
    306      * @param {Element} element
    307      * @return {Element}
    308      */
    309     _highlightExpression: function(element)
    310     {
    311         return this.textEditor.highlightExpression(element, { "webkit-javascript-ident": true, "source-frame-token": true, "webkit-javascript-keyword": true }, { ".": true });
     287        if (!this._popoverAnchorBox)
     288            return;
     289        if (this._popoverAnchorBox._highlightDescriptor)
     290            this.textEditor.removeHighlight(this._popoverAnchorBox._highlightDescriptor);
     291        delete this._popoverAnchorBox;
    312292    },
    313293
  • trunk/Source/WebCore/inspector/front-end/inspector.css

    r147275 r147415  
    23302330
    23312331.source-frame-eval-expression {
    2332     border: 1px solid rgb(163, 41, 34);
    2333     margin: -1px;
     2332    outline: 1px solid rgb(163, 41, 34);
    23342333    background-color: rgb(255, 255, 194);
    23352334}
Note: See TracChangeset for help on using the changeset viewer.