Changeset 86430 in webkit


Ignore:
Timestamp:
May 13, 2011 7:56:24 AM (13 years ago)
Author:
podivilov@chromium.org
Message:

2011-05-06 Pavel Podivilov <podivilov@chromium.org>

Reviewed by Yury Semikhatsky.

Web Inspector: fix incremental html highlight.
https://bugs.webkit.org/show_bug.cgi?id=60163

SourceTokenizers for html, js, and css are declared to be stateless. However they store some state in
various ways (like using _internalJavaScriptTokenizer field in html tokenizer, or modifying "static"
initialCondition object via condition link). This all worked because of another bug in tokenizers registry
that always returned new tokenizer object.
For incremental highlighting, we need to be able to stringify tokenizers state and then restore the
state from string. That's why we need tokenizers to be truly stateless.

  • inspector/front-end/DOMSyntaxHighlighter.js: (WebInspector.DOMSyntaxHighlighter.prototype.syntaxHighlightNode):
  • inspector/front-end/SourceCSSTokenizer.js: (WebInspector.SourceCSSTokenizer): (WebInspector.SourceCSSTokenizer.prototype.createInitialCondition):
  • inspector/front-end/SourceCSSTokenizer.re2js:
  • inspector/front-end/SourceHTMLTokenizer.js: (WebInspector.SourceHTMLTokenizer): (WebInspector.SourceHTMLTokenizer.prototype.createInitialCondition): (WebInspector.SourceHTMLTokenizer.prototype.set line): (WebInspector.SourceHTMLTokenizer.prototype.get _internalJavaScriptTokenizer): (WebInspector.SourceHTMLTokenizer.prototype.get _internalCSSTokenizer): (WebInspector.SourceHTMLTokenizer.prototype.scriptStarted): (WebInspector.SourceHTMLTokenizer.prototype.styleSheetStarted): (WebInspector.SourceHTMLTokenizer.prototype.nextToken):
  • inspector/front-end/SourceHTMLTokenizer.re2js:
  • inspector/front-end/SourceJavaScriptTokenizer.js: (WebInspector.SourceJavaScriptTokenizer): (WebInspector.SourceJavaScriptTokenizer.prototype.createInitialCondition):
  • inspector/front-end/SourceJavaScriptTokenizer.re2js:
  • inspector/front-end/SourceTokenizer.js: (WebInspector.SourceTokenizer.Registry.prototype.getTokenizer):
  • inspector/front-end/TextEditorHighlighter.js: (WebInspector.TextEditorHighlighter.prototype._highlightLines):
Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r86428 r86430  
     12011-05-06  Pavel Podivilov  <podivilov@chromium.org>
     2
     3        Reviewed by Yury Semikhatsky.
     4
     5        Web Inspector: fix incremental html highlight.
     6        https://bugs.webkit.org/show_bug.cgi?id=60163
     7
     8        SourceTokenizers for html, js, and css are declared to be stateless. However they store some state in
     9        various ways (like using _internalJavaScriptTokenizer field in html tokenizer, or modifying "static"
     10        initialCondition object via condition link). This all worked because of another bug in tokenizers registry
     11        that always returned new tokenizer object.
     12        For incremental highlighting, we need to be able to stringify tokenizers state and then restore the
     13        state from string. That's why we need tokenizers to be truly stateless.
     14
     15        * inspector/front-end/DOMSyntaxHighlighter.js:
     16        (WebInspector.DOMSyntaxHighlighter.prototype.syntaxHighlightNode):
     17        * inspector/front-end/SourceCSSTokenizer.js:
     18        (WebInspector.SourceCSSTokenizer):
     19        (WebInspector.SourceCSSTokenizer.prototype.createInitialCondition):
     20        * inspector/front-end/SourceCSSTokenizer.re2js:
     21        * inspector/front-end/SourceHTMLTokenizer.js:
     22        (WebInspector.SourceHTMLTokenizer):
     23        (WebInspector.SourceHTMLTokenizer.prototype.createInitialCondition):
     24        (WebInspector.SourceHTMLTokenizer.prototype.set line):
     25        (WebInspector.SourceHTMLTokenizer.prototype.get _internalJavaScriptTokenizer):
     26        (WebInspector.SourceHTMLTokenizer.prototype.get _internalCSSTokenizer):
     27        (WebInspector.SourceHTMLTokenizer.prototype.scriptStarted):
     28        (WebInspector.SourceHTMLTokenizer.prototype.styleSheetStarted):
     29        (WebInspector.SourceHTMLTokenizer.prototype.nextToken):
     30        * inspector/front-end/SourceHTMLTokenizer.re2js:
     31        * inspector/front-end/SourceJavaScriptTokenizer.js:
     32        (WebInspector.SourceJavaScriptTokenizer):
     33        (WebInspector.SourceJavaScriptTokenizer.prototype.createInitialCondition):
     34        * inspector/front-end/SourceJavaScriptTokenizer.re2js:
     35        * inspector/front-end/SourceTokenizer.js:
     36        (WebInspector.SourceTokenizer.Registry.prototype.getTokenizer):
     37        * inspector/front-end/TextEditorHighlighter.js:
     38        (WebInspector.TextEditorHighlighter.prototype._highlightLines):
     39
    1402011-05-13  Adam Roben  <aroben@apple.com>
    241
  • trunk/Source/WebCore/inspector/front-end/DOMSyntaxHighlighter.js

    r54053 r86430  
    4545    syntaxHighlightNode: function(node)
    4646    {
    47         this._tokenizer.condition = this._tokenizer.initialCondition;
     47        this._tokenizer.condition = this._tokenizer.createInitialCondition();
    4848        var lines = node.textContent.split("\n");
    4949        node.removeChildren();
  • trunk/Source/WebCore/inspector/front-end/SourceCSSTokenizer.js

    r84483 r86430  
    1 /* Generated by re2c 0.13.5 on Mon Dec 20 18:44:30 2010 */
     1/* Generated by re2c 0.13.5 on Fri May  6 13:46:34 2011 */
    22/*
    33 * Copyright (C) 2009 Google Inc. All rights reserved.
     
    4646    WebInspector.SourceTokenizer.call(this);
    4747
    48     this._propertyKeywords = WebInspector.cssNameCompletions ? WebInspector.cssNameCompletions.keySet() : {};
     48    this._propertyKeywords = WebInspector.cssNameCompletions.keySet();
    4949
    5050    this._valueKeywords = [
     
    119119    this.case_SSTRING = 1004;
    120120
    121     this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }
     121    this.condition = this.createInitialCondition();
    122122}
    123123
    124124WebInspector.SourceCSSTokenizer.prototype = {
     125    createInitialCondition: function()
     126    {
     127        return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
     128    },
     129
    125130    _stringToken: function(cursor, stringEnds)
    126131    {
  • trunk/Source/WebCore/inspector/front-end/SourceCSSTokenizer.re2js

    r74352 r86430  
    118118    this.case_SSTRING = 1004;
    119119
    120     this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }
     120    this.condition = this.createInitialCondition();
    121121}
    122122
    123123WebInspector.SourceCSSTokenizer.prototype = {
     124    createInitialCondition: function()
     125    {
     126        return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
     127    },
     128
    124129    _stringToken: function(cursor, stringEnds)
    125130    {
  • trunk/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.js

    r84625 r86430  
    1 /* Generated by re2c 0.13.5 on Thu Apr 14 15:53:19 2011 */
     1/* Generated by re2c 0.13.5 on Fri May  6 13:47:06 2011 */
    22/*
    33 * Copyright (C) 2009 Google Inc. All rights reserved.
     
    7272    };
    7373
    74     this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
    75     this.condition = this.initialCondition;
     74    this.condition = this.createInitialCondition();
    7675}
    7776
    7877WebInspector.SourceHTMLTokenizer.prototype = {
     78    createInitialCondition: function()
     79    {
     80        return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
     81    },
     82
    7983    set line(line) {
    80         if (this._internalJavaScriptTokenizer) {
     84        if (this._condition.internalJavaScriptTokenizerCondition) {
    8185            var match = /<\/script/i.exec(line);
    8286            if (match) {
     
    8488            } else
    8589                this._internalJavaScriptTokenizer.line = line;
    86         } else if (this._internalCSSTokenizer) {
     90        } else if (this._condition.internalCSSTokenizerCondition) {
    8791            var match = /<\/style/i.exec(line);
    8892            if (match) {
     
    140144    },
    141145
     146    get _internalJavaScriptTokenizer()
     147    {
     148        return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
     149    },
     150
     151    get _internalCSSTokenizer()
     152    {
     153        return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
     154    },
     155
    142156    scriptStarted: function(cursor)
    143157    {
    144         if (!this._internalJavaScriptTokenizer) {
    145             this._internalJavaScriptTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
    146             this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.initialCondition;
    147         }
     158        this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
    148159    },
    149160
     
    154165    styleSheetStarted: function(cursor)
    155166    {
    156         if (!this._internalCSSTokenizer) {
    157             this._internalCSSTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
    158             this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.initialCondition;
    159         }
     167        this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
    160168    },
    161169
     
    166174    nextToken: function(cursor)
    167175    {
    168         if (this._internalJavaScriptTokenizer) {
     176        if (this._condition.internalJavaScriptTokenizerCondition) {
    169177            // Re-set line to force </script> detection first.
    170178            this.line = this._line;
     
    177185                return result;
    178186            } else if (cursor !== this._line.length)
    179                 delete this._internalJavaScriptTokenizer;
    180         } else if (this._internalCSSTokenizer) {
     187                delete this._condition.internalJavaScriptTokenizerCondition;
     188        } else if (this._condition.internalCSSTokenizerCondition) {
    181189            // Re-set line to force </style> detection first.
    182190            this.line = this._line;
     
    189197                return result;
    190198            } else if (cursor !== this._line.length)
    191                 delete this._internalCSSTokenizer;
     199                delete this._condition.internalCSSTokenizerCondition;
    192200        }
    193201
     
    586594                    this.tokenType = "html-tag";
    587595                    this._condition.parseCondition = this._parseConditions.INITIAL;
     596                    this.styleSheetEnded(cursor - 7);
    588597                    return cursor;
    589598                }
  • trunk/Source/WebCore/inspector/front-end/SourceHTMLTokenizer.re2js

    r84625 r86430  
    7171    };
    7272
    73     this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
    74     this.condition = this.initialCondition;
     73    this.condition = this.createInitialCondition();
    7574}
    7675
    7776WebInspector.SourceHTMLTokenizer.prototype = {
     77    createInitialCondition: function()
     78    {
     79        return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
     80    },
     81
    7882    set line(line) {
    79         if (this._internalJavaScriptTokenizer) {
     83        if (this._condition.internalJavaScriptTokenizerCondition) {
    8084            var match = /<\/script/i.exec(line);
    8185            if (match) {
     
    8387            } else
    8488                this._internalJavaScriptTokenizer.line = line;
    85         } else if (this._internalCSSTokenizer) {
     89        } else if (this._condition.internalCSSTokenizerCondition) {
    8690            var match = /<\/style/i.exec(line);
    8791            if (match) {
     
    139143    },
    140144
     145    get _internalJavaScriptTokenizer()
     146    {
     147        return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
     148    },
     149
     150    get _internalCSSTokenizer()
     151    {
     152        return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
     153    },
     154
    141155    scriptStarted: function(cursor)
    142156    {
    143         if (!this._internalJavaScriptTokenizer) {
    144             this._internalJavaScriptTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
    145             this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.initialCondition;
    146         }
     157        this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
    147158    },
    148159
     
    153164    styleSheetStarted: function(cursor)
    154165    {
    155         if (!this._internalCSSTokenizer) {
    156             this._internalCSSTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
    157             this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.initialCondition;
    158         }
     166        this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
    159167    },
    160168
     
    165173    nextToken: function(cursor)
    166174    {
    167         if (this._internalJavaScriptTokenizer) {
     175        if (this._condition.internalJavaScriptTokenizerCondition) {
    168176            // Re-set line to force </script> detection first.
    169177            this.line = this._line;
     
    176184                return result;
    177185            } else if (cursor !== this._line.length)
    178                 delete this._internalJavaScriptTokenizer;
    179         } else if (this._internalCSSTokenizer) {
     186                delete this._condition.internalJavaScriptTokenizerCondition;
     187        } else if (this._condition.internalCSSTokenizerCondition) {
    180188            // Re-set line to force </style> detection first.
    181189            this.line = this._line;
     
    188196                return result;
    189197            } else if (cursor !== this._line.length)
    190                 delete this._internalCSSTokenizer;
     198                delete this._condition.internalCSSTokenizerCondition;
    191199        }
    192200
     
    285293                    this.tokenType = "html-tag";
    286294                    this._condition.parseCondition = this._parseConditions.INITIAL;
    287                     this.styleEnded(cursor - 7);
     295                    this.styleSheetEnded(cursor - 7);
    288296                    return cursor;
    289297                }
  • trunk/Source/WebCore/inspector/front-end/SourceJavaScriptTokenizer.js

    r55248 r86430  
    1 /* Generated by re2c 0.13.5 on Thu Feb 25 21:44:55 2010 */
     1/* Generated by re2c 0.13.5 on Fri May  6 13:56:13 2011 */
    22/*
    33 * Copyright (C) 2009 Google Inc. All rights reserved.
     
    6969    this.case_REGEX = 1005;
    7070
    71     this.initialCondition = { lexCondition: this._lexConditions.NODIV }
    72     this.condition = this.initialCondition;
     71    this.condition = this.createInitialCondition();
    7372}
    7473
    7574WebInspector.SourceJavaScriptTokenizer.prototype = {
     75    createInitialCondition: function()
     76    {
     77        return { lexCondition: this._lexConditions.NODIV };
     78    },
     79
    7680    nextToken: function(cursor)
    7781    {
  • trunk/Source/WebCore/inspector/front-end/SourceJavaScriptTokenizer.re2js

    r55248 r86430  
    6868    this.case_REGEX = 1005;
    6969
    70     this.initialCondition = { lexCondition: this._lexConditions.NODIV }
    71     this.condition = this.initialCondition;
     70    this.condition = this.createInitialCondition();
    7271}
    7372
    7473WebInspector.SourceJavaScriptTokenizer.prototype = {
     74    createInitialCondition: function()
     75    {
     76        return { lexCondition: this._lexConditions.NODIV };
     77    },
     78
    7579    nextToken: function(cursor)
    7680    {
  • trunk/Source/WebCore/inspector/front-end/SourceTokenizer.js

    r78815 r86430  
    9191        if (!tokenizer) {
    9292            tokenizer = new WebInspector[tokenizerClass]();
    93             this._tokenizers[mimeType] = tokenizer;
     93            this._tokenizers[tokenizerClass] = tokenizer;
    9494        }
    9595        return tokenizer;
  • trunk/Source/WebCore/inspector/front-end/TextEditorHighlighter.js

    r80704 r86430  
    142142        // Restore highlighter context taken from previous line.
    143143        var state = this._textModel.getAttribute(startLine - 1, "highlight");
    144         var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.initialCondition);
     144        var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition());
    145145
    146146        var tokensCount = 0;
Note: See TracChangeset for help on using the changeset viewer.