Changeset 142091 in webkit


Ignore:
Timestamp:
Feb 7, 2013 3:51:08 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: highlight matching braces in DTE.
https://bugs.webkit.org/show_bug.cgi?id=108697

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

Source/WebCore:

Implement BraceMatcher class which for given position in textModel
will respond with enclosing brace pair for that position.
Make use of this class in DefaultTextEditor by handling
selectionChange event. Make use of this class in "_closingBlockOffset"
method of TextEditorMainPanel as this method implements similar
functionality.

New test: inspector/editor/brace-matcher.html

  • inspector/front-end/DefaultTextEditor.js:

(WebInspector.TextEditorMainPanel):
(WebInspector.TextEditorMainPanel.prototype._applyDomUpdates):
(WebInspector.TextEditorMainPanel.prototype._closingBlockOffset):
(WebInspector.TextEditorMainPanel.prototype._handleSelectionChange):
(WebInspector.TextEditorMainPanel.BraceHighlightController):
(WebInspector.TextEditorMainPanel.BraceHighlightController.prototype.handleSelectionChange):

  • inspector/front-end/TextEditorHighlighter.js:

(WebInspector.TextEditorHighlighter.prototype._highlightLines):

  • inspector/front-end/TextEditorModel.js:

(WebInspector.TextEditorModel.endsWithBracketRegex):
(WebInspector.TextEditorModel.endsWithBracketRegex.):

  • inspector/front-end/textEditor.css:

(.text-editor-brace-match):

LayoutTests:

New layout test to verify brace matching functionality. Fix some
layout test expectations as the patch removes braces from highlight
ranges.

  • inspector/editor/brace-matcher-expected.txt: Added.
  • inspector/editor/brace-matcher.html: Added.
  • inspector/editor/highlighter-basics-expected.txt:
  • inspector/editor/text-editor-long-line-expected.txt:
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r142084 r142091  
     12013-02-07  Andrey Lushnikov  <lushnikov@chromium.org>
     2
     3        Web Inspector: highlight matching braces in DTE.
     4        https://bugs.webkit.org/show_bug.cgi?id=108697
     5
     6        Reviewed by Pavel Feldman.
     7
     8        New layout test to verify brace matching functionality. Fix some
     9        layout test expectations as the patch removes braces from highlight
     10        ranges.
     11
     12        * inspector/editor/brace-matcher-expected.txt: Added.
     13        * inspector/editor/brace-matcher.html: Added.
     14        * inspector/editor/highlighter-basics-expected.txt:
     15        * inspector/editor/text-editor-long-line-expected.txt:
     16
    1172013-02-07  Matt Falkenhagen  <falken@chromium.org>
    218
  • trunk/LayoutTests/inspector/editor/highlighter-basics-expected.txt

    r141987 r142091  
    929216 :  * line #7 : whitespace[0-1] whitespace[2-3] javascript-ident[3-7] whitespace[7-8] javascript-number[9-10]
    939317 :  * line #8 : whitespace[0-1] whitespace[2-3] javascript-ident[3-7] whitespace[7-8] javascript-number[9-10]
    94 18 :  * var a = new A(); //*/ : whitespace[0-1] whitespace[2-3] javascript-keyword[3-6] whitespace[6-7] javascript-ident[7-8] whitespace[8-9] whitespace[10-11] javascript-keyword[11-14] whitespace[14-15] javascript-ident[15-16] brace-start[16-17] brace-end[17-18] whitespace[19-20] javascript-comment[20-24]
     9418 :  * var a = new A(); //*/ : whitespace[0-1] whitespace[2-3] javascript-keyword[3-6] whitespace[6-7] javascript-ident[7-8] whitespace[8-9] whitespace[10-11] javascript-keyword[11-14] whitespace[14-15] javascript-ident[15-16] whitespace[19-20] javascript-comment[20-24]
    959519 : some text : javascript-ident[0-4] whitespace[4-5] javascript-ident[5-9]
    969620 :  :
     
    11411416 :  * line #7 : whitespace[0-1] whitespace[2-3] javascript-ident[3-7] whitespace[7-8] javascript-number[9-10]
    11511517 :  * line #8 : whitespace[0-1] whitespace[2-3] javascript-ident[3-7] whitespace[7-8] javascript-number[9-10]
    116 18 :  * var a = new A(); //*/ : whitespace[0-1] whitespace[2-3] javascript-keyword[3-6] whitespace[6-7] javascript-ident[7-8] whitespace[8-9] whitespace[10-11] javascript-keyword[11-14] whitespace[14-15] javascript-ident[15-16] brace-start[16-17] brace-end[17-18] whitespace[19-20] javascript-comment[20-24]
     11618 :  * var a = new A(); //*/ : whitespace[0-1] whitespace[2-3] javascript-keyword[3-6] whitespace[6-7] javascript-ident[7-8] whitespace[8-9] whitespace[10-11] javascript-keyword[11-14] whitespace[14-15] javascript-ident[15-16] whitespace[19-20] javascript-comment[20-24]
    11711719 : some text : javascript-ident[0-4] whitespace[4-5] javascript-ident[5-9]
    11811820 :  :
  • trunk/LayoutTests/inspector/editor/text-editor-long-line-expected.txt

    r141987 r142091  
    33
    44<div class="inner-container" tabindex="0">
    5 <div class="webkit-line-content"><span class="webkit-javascript-comment">/* START */</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">this</span>.<span class="webkit-javascript-ident">field</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-string">"foo"</span>;<span class="webkit-whitespace"> </span><span class="webkit-javascript-comment">/* comment */</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">function</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-ident">bar</span><span class="webkit-brace-start">(</span><span class="webkit-brace-end">)</span><span class="webkit-whitespace"> </span><span class="webkit-block-start">{</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">return</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">null</span>;<span class="webkit-whitespace"> </span><span class="webkit-block-end">}</span><span class="webkit-javascript-keyword">this</span>.<span class="webkit-javascript-ident">field</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-string">"foo"</span>;<span class="webkit-whitespace"> </span><span class="webkit-javascript-comment">/* comment */</span> function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }/* FINISH */</div></div>
     5<div class="webkit-line-content"><span class="webkit-javascript-comment">/* START */</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">this</span>.<span class="webkit-javascript-ident">field</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-string">"foo"</span>;<span class="webkit-whitespace"> </span><span class="webkit-javascript-comment">/* comment */</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">function</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-ident">bar</span>()<span class="webkit-whitespace"> </span>{<span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">return</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-keyword">null</span>;<span class="webkit-whitespace"> </span>}<span class="webkit-javascript-keyword">this</span>.<span class="webkit-javascript-ident">field</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-string">"foo"</span>;<span class="webkit-whitespace"> </span><span class="webkit-javascript-comment">/* comment */</span> function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }this.field = "foo"; /* comment */ function bar() { return null; }/* FINISH */</div></div>
    66
  • trunk/Source/WebCore/ChangeLog

    r142087 r142091  
     12013-02-07  Andrey Lushnikov  <lushnikov@chromium.org>
     2
     3        Web Inspector: highlight matching braces in DTE.
     4        https://bugs.webkit.org/show_bug.cgi?id=108697
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Implement BraceMatcher class which for given position in textModel
     9        will respond with enclosing brace pair for that position.
     10        Make use of this class in DefaultTextEditor by handling
     11        selectionChange event. Make use of this class in "_closingBlockOffset"
     12        method of TextEditorMainPanel as this method implements similar
     13        functionality.
     14
     15        New test: inspector/editor/brace-matcher.html
     16
     17        * inspector/front-end/DefaultTextEditor.js:
     18        (WebInspector.TextEditorMainPanel):
     19        (WebInspector.TextEditorMainPanel.prototype._applyDomUpdates):
     20        (WebInspector.TextEditorMainPanel.prototype._closingBlockOffset):
     21        (WebInspector.TextEditorMainPanel.prototype._handleSelectionChange):
     22        (WebInspector.TextEditorMainPanel.BraceHighlightController):
     23        (WebInspector.TextEditorMainPanel.BraceHighlightController.prototype.handleSelectionChange):
     24        * inspector/front-end/TextEditorHighlighter.js:
     25        (WebInspector.TextEditorHighlighter.prototype._highlightLines):
     26        * inspector/front-end/TextEditorModel.js:
     27        (WebInspector.TextEditorModel.endsWithBracketRegex):
     28        (WebInspector.TextEditorModel.endsWithBracketRegex.):
     29        * inspector/front-end/textEditor.css:
     30        (.text-editor-brace-match):
     31
    1322013-02-05  Eunmi Lee  <eunmi15.lee@samsung.com> and Raphael Kubo da Costa  <raphael.kubo.da.costa@intel.com>
    233
  • trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js

    r141986 r142091  
    13701370
    13711371    this._tokenHighlighter = new WebInspector.TextEditorMainPanel.TokenHighlighter(this, textModel);
     1372    this._braceMatcher = new WebInspector.TextEditorModel.BraceMatcher(textModel);
     1373    this._braceHighlighter = new WebInspector.TextEditorMainPanel.BraceHighlightController(this, textModel, this._braceMatcher);
    13721374
    13731375    this._freeCachedElements();
     
    24022404        // Unindent after block
    24032405        if (editInfo.text === "}" && editInfo.range.isEmpty() && selection.isEmpty() && !this._textModel.line(editInfo.range.endLine).trim()) {
    2404             var offset = this._closingBlockOffset(editInfo.range, selection);
     2406            var offset = this._closingBlockOffset(editInfo.range);
    24052407            if (offset >= 0) {
    24062408                editInfo.range.startColumn = offset;
     
    24922494    /**
    24932495     * @param {WebInspector.TextRange} oldRange
    2494      * @param {WebInspector.TextRange} selection
    24952496     * @return {number}
    24962497     */
    2497     _closingBlockOffset: function(oldRange, selection)
    2498     {
    2499         var nestingLevel = 1;
    2500         for (var i = oldRange.endLine; i >= 0; --i) {
    2501             var attribute = this._textModel.getAttribute(i, "highlight");
    2502             if (!attribute)
    2503                 continue;
    2504             var ranges = attribute.ranges;
    2505             for (var j = ranges.length - 1; j >= 0; j--) {
    2506                 var token = ranges[j].token;
    2507                 if (token === "block-start") {
    2508                     if (!(--nestingLevel)) {
    2509                         var lineContent = this._textModel.line(i);
    2510                         return lineContent.length - lineContent.trimLeft().length;
    2511                     }
    2512                 }
    2513                 if (token === "block-end")
    2514                     ++nestingLevel;
    2515             }
    2516         }
    2517         return -1;
     2498    _closingBlockOffset: function(oldRange)
     2499    {
     2500        var leftBrace = this._braceMatcher.findLeftCandidate(oldRange.startLine, oldRange.startColumn);
     2501        if (!leftBrace || leftBrace.token !== "block-start")
     2502            return -1;
     2503        var lineContent = this._textModel.line(leftBrace.lineNumber);
     2504        return lineContent.length - lineContent.trimLeft().length;
    25182505    },
    25192506
     
    26812668
    26822669        this._tokenHighlighter.handleSelectionChange(textRange);
     2670        this._braceHighlighter.handleSelectionChange(textRange);
    26832671        this._delegate.selectionChanged(textRange);
    26842672    },
     
    33603348}
    33613349
     3350/**
     3351 * @constructor
     3352 * @param {WebInspector.TextEditorMainPanel} textEditor
     3353 * @param {WebInspector.TextEditorModel} textModel
     3354 * @param {WebInspector.TextEditorModel.BraceMatcher} braceMatcher
     3355 */
     3356WebInspector.TextEditorMainPanel.BraceHighlightController = function(textEditor, textModel, braceMatcher)
     3357{
     3358    this._textEditor = textEditor;
     3359    this._textModel = textModel;
     3360    this._braceMatcher = braceMatcher;
     3361    this._highlightDescriptors = [];
     3362}
     3363
     3364WebInspector.TextEditorMainPanel.BraceHighlightController.prototype = {
     3365    /**
     3366     * @param {WebInspector.TextRange} selectionRange
     3367     */
     3368    handleSelectionChange: function(selectionRange)
     3369    {
     3370        if (!selectionRange || !selectionRange.isEmpty()) {
     3371            this._removeHighlight();
     3372            return;
     3373        }
     3374
     3375        if (this._highlightedRange && this._highlightedRange.compareTo(selectionRange) === 0)
     3376            return;
     3377
     3378        this._removeHighlight();
     3379        var lineNumber = selectionRange.startLine;
     3380        var column = selectionRange.startColumn;
     3381        var line = this._textModel.line(lineNumber);
     3382        if (column > 0 && /[)}]/.test(line.charAt(column - 1)))
     3383            --column;
     3384
     3385        var enclosingBraces = this._braceMatcher.enclosingBraces(lineNumber, column);
     3386        if (!enclosingBraces)
     3387            return;
     3388
     3389        this._highlightedRange = selectionRange;
     3390        this._highlightDescriptors.push(this._textEditor.highlightRange(WebInspector.TextRange.createFromLocation(enclosingBraces.leftBrace.lineNumber, enclosingBraces.leftBrace.column), "text-editor-brace-match"));
     3391        this._highlightDescriptors.push(this._textEditor.highlightRange(WebInspector.TextRange.createFromLocation(enclosingBraces.rightBrace.lineNumber, enclosingBraces.rightBrace.column), "text-editor-brace-match"));
     3392    },
     3393
     3394    _removeHighlight: function()
     3395    {
     3396        if (!this._highlightDescriptors.length)
     3397            return;
     3398
     3399        for(var i = 0; i < this._highlightDescriptors.length; ++i)
     3400            this._textEditor.removeHighlight(this._highlightDescriptors[i]);
     3401
     3402        this._highlightDescriptors = [];
     3403        delete this._highlightedRange;
     3404    }
     3405}
     3406
    33623407WebInspector.debugDefaultTextEditor = false;
  • trunk/Source/WebCore/inspector/front-end/TextEditorHighlighter.js

    r140421 r142091  
    186186                // Highlight line.
    187187                state.ranges = state.ranges || [];
     188                state.braces = state.braces || [];
    188189                do {
    189190                    var newColumn = this._tokenizer.nextToken(lastHighlightedColumn);
    190191                    var tokenType = this._tokenizer.tokenType;
    191                     if (tokenType && lastHighlightedColumn < this._highlightLineLimit)
    192                         state.ranges.push({
    193                             startColumn: lastHighlightedColumn,
    194                             endColumn: newColumn - 1,
    195                             token: tokenType
    196                         });
     192                    if (tokenType && lastHighlightedColumn < this._highlightLineLimit) {
     193                        if (tokenType === "brace-start" || tokenType === "brace-end" || tokenType === "block-start" || tokenType === "block-end") {
     194                            state.braces.push({
     195                                startColumn: lastHighlightedColumn,
     196                                endColumn: newColumn - 1,
     197                                token: tokenType
     198                            });
     199                        } else {
     200                            state.ranges.push({
     201                                startColumn: lastHighlightedColumn,
     202                                endColumn: newColumn - 1,
     203                                token: tokenType
     204                            });
     205                        }
     206                    }
    197207                    lastHighlightedColumn = newColumn;
    198208                    if (++tokensCount > this._highlightChunkLimit)
  • trunk/Source/WebCore/inspector/front-end/TextEditorModel.js

    r135574 r142091  
    657657    __proto__: WebInspector.Object.prototype
    658658}
     659
     660/**
     661 * @constructor
     662 * @param {WebInspector.TextEditorModel} textModel
     663 */
     664WebInspector.TextEditorModel.BraceMatcher = function(textModel)
     665{
     666    this._textModel = textModel;
     667}
     668
     669WebInspector.TextEditorModel.BraceMatcher.prototype = {
     670    /**
     671     * @param {number} lineNumber
     672     * @return {Array.<{startColumn: number, endColumn: number, token: string}>}
     673     */
     674    _braceRanges: function(lineNumber)
     675    {
     676        if (lineNumber >= this._textModel.linesCount || lineNumber < 0)
     677            return null;
     678
     679        var attribute = this._textModel.getAttribute(lineNumber, "highlight");
     680        if (!attribute)
     681            return null;
     682        else
     683            return attribute.braces;
     684    },
     685
     686    /**
     687     * @param {string} braceTokenLeft
     688     * @param {string} braceTokenRight
     689     * @return {boolean}
     690     */
     691    _matches: function(braceTokenLeft, braceTokenRight)
     692    {
     693        return ((braceTokenLeft === "brace-start" && braceTokenRight === "brace-end") || (braceTokenLeft === "block-start" && braceTokenRight === "block-end"));
     694    },
     695
     696    /**
     697     * @param {number} lineNumber
     698     * @param {number} column
     699     * @param {number=} maxBraceIteration
     700     * @return {?{lineNumber: number, column: number, token: string}}
     701     */
     702    findLeftCandidate: function(lineNumber, column, maxBraceIteration)
     703    {
     704        var braces = this._braceRanges(lineNumber);
     705        if (!braces)
     706            return null;
     707
     708        var braceIndex = braces.length - 1;
     709        while (braceIndex >= 0 && braces[braceIndex].startColumn > column)
     710            --braceIndex;
     711
     712        var brace = braceIndex >= 0 ? braces[braceIndex] : null;
     713        if (brace && brace.startColumn === column && (brace.token === "block-end" || brace.token === "brace-end"))
     714            --braceIndex;
     715
     716        var stack = [];
     717        maxBraceIteration = maxBraceIteration || Number.MAX_VALUE;
     718        while (--maxBraceIteration) {
     719            if (braceIndex < 0) {
     720                while ((braces = this._braceRanges(--lineNumber)) && !braces.length) {};
     721                if (!braces)
     722                    return null;
     723                braceIndex = braces.length - 1;
     724            }
     725            brace = braces[braceIndex];
     726            if (brace.token === "block-end" || brace.token === "brace-end")
     727                stack.push(brace.token);
     728            else if (stack.length === 0)
     729                return {
     730                    lineNumber: lineNumber,
     731                    column: brace.startColumn,
     732                    token: brace.token
     733                };
     734            else if (!this._matches(brace.token, stack.pop()))
     735                return null;
     736
     737            --braceIndex;
     738        }
     739        return null;
     740    },
     741
     742    /**
     743     * @param {number} lineNumber
     744     * @param {number} column
     745     * @param {number=} maxBraceIteration
     746     * @return {?{lineNumber: number, column: number, token: string}}
     747     */
     748    findRightCandidate: function(lineNumber, column, maxBraceIteration)
     749    {
     750        var braces = this._braceRanges(lineNumber);
     751        if (!braces)
     752            return null;
     753
     754        var braceIndex = 0;
     755        while (braceIndex < braces.length && braces[braceIndex].startColumn < column)
     756            ++braceIndex;
     757
     758        var brace = braceIndex < braces.length ? braces[braceIndex] : null;
     759        if (brace && brace.startColumn === column && (brace.token === "block-start" || brace.token === "brace-start"))
     760            ++braceIndex;
     761
     762        var stack = [];
     763        maxBraceIteration = maxBraceIteration || Number.MAX_VALUE;
     764        while (--maxBraceIteration) {
     765            if (braceIndex >= braces.length) {
     766                while ((braces = this._braceRanges(++lineNumber)) && !braces.length) {};
     767                if (!braces)
     768                    return null;
     769                braceIndex = 0;
     770            }
     771            brace = braces[braceIndex];
     772            if (brace.token === "block-start" || brace.token === "brace-start")
     773                stack.push(brace.token);
     774            else if (stack.length === 0)
     775                return {
     776                    lineNumber: lineNumber,
     777                    column: brace.startColumn,
     778                    token: brace.token
     779                };
     780            else if (!this._matches(stack.pop(), brace.token))
     781                return null;
     782            ++braceIndex;
     783        }
     784        return null;
     785    },
     786
     787    /**
     788     * @param {number} lineNumber
     789     * @param {number} column
     790     * @param {number=} maxBraceIteration
     791     * @return {?{leftBrace: {lineNumber: number, column: number, token: string}, rightBrace: {lineNumber: number, column: number, token: string}}}
     792     */
     793    enclosingBraces: function(lineNumber, column, maxBraceIteration)
     794    {
     795        var leftBraceLocation = this.findLeftCandidate(lineNumber, column, maxBraceIteration);
     796        if (!leftBraceLocation)
     797            return null;
     798
     799        var rightBraceLocation = this.findRightCandidate(lineNumber, column, maxBraceIteration);
     800        if (!rightBraceLocation)
     801            return null;
     802
     803        if (!this._matches(leftBraceLocation.token, rightBraceLocation.token))
     804            return null;
     805
     806        return {
     807            leftBrace: leftBraceLocation,
     808            rightBrace: rightBraceLocation
     809        };
     810    },
     811}
  • trunk/Source/WebCore/inspector/front-end/textEditor.css

    r141414 r142091  
    4141    border: 1px solid gray;
    4242    border-radius: 3px;
     43}
     44
     45.text-editor-brace-match {
     46    border-bottom: 1px solid black;
    4347}
    4448
Note: See TracChangeset for help on using the changeset viewer.