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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@86430 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e191da4f
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):
2011-05-13 Adam Roben <aroben@apple.com>
Build fix after r86418
......@@ -44,7 +44,7 @@ WebInspector.DOMSyntaxHighlighter.prototype = {
syntaxHighlightNode: function(node)
{
this._tokenizer.condition = this._tokenizer.initialCondition;
this._tokenizer.condition = this._tokenizer.createInitialCondition();
var lines = node.textContent.split("\n");
node.removeChildren();
......
/* Generated by re2c 0.13.5 on Mon Dec 20 18:44:30 2010 */
/* Generated by re2c 0.13.5 on Fri May 6 13:46:34 2011 */
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
......@@ -45,7 +45,7 @@ WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);
this._propertyKeywords = WebInspector.cssNameCompletions ? WebInspector.cssNameCompletions.keySet() : {};
this._propertyKeywords = WebInspector.cssNameCompletions.keySet();
this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
......@@ -118,10 +118,15 @@ WebInspector.SourceCSSTokenizer = function()
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;
this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }
this.condition = this.createInitialCondition();
}
WebInspector.SourceCSSTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},
_stringToken: function(cursor, stringEnds)
{
if (this._isPropertyValue())
......
......@@ -117,10 +117,15 @@ WebInspector.SourceCSSTokenizer = function()
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;
this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL }
this.condition = this.createInitialCondition();
}
WebInspector.SourceCSSTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},
_stringToken: function(cursor, stringEnds)
{
if (this._isPropertyValue())
......
/* Generated by re2c 0.13.5 on Thu Apr 14 15:53:19 2011 */
/* Generated by re2c 0.13.5 on Fri May 6 13:47:06 2011 */
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
......@@ -71,19 +71,23 @@ WebInspector.SourceHTMLTokenizer = function()
STYLE: 32
};
this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
this.condition = this.initialCondition;
this.condition = this.createInitialCondition();
}
WebInspector.SourceHTMLTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},
set line(line) {
if (this._internalJavaScriptTokenizer) {
if (this._condition.internalJavaScriptTokenizerCondition) {
var match = /<\/script/i.exec(line);
if (match) {
this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
} else
this._internalJavaScriptTokenizer.line = line;
} else if (this._internalCSSTokenizer) {
} else if (this._condition.internalCSSTokenizerCondition) {
var match = /<\/style/i.exec(line);
if (match) {
this._internalCSSTokenizer.line = line.substring(0, match.index);
......@@ -139,12 +143,19 @@ WebInspector.SourceHTMLTokenizer.prototype = {
return "html-attribute-value";
},
get _internalJavaScriptTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
},
get _internalCSSTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
},
scriptStarted: function(cursor)
{
if (!this._internalJavaScriptTokenizer) {
this._internalJavaScriptTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.initialCondition;
}
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
},
scriptEnded: function(cursor)
......@@ -153,10 +164,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
styleSheetStarted: function(cursor)
{
if (!this._internalCSSTokenizer) {
this._internalCSSTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.initialCondition;
}
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
},
styleSheetEnded: function(cursor)
......@@ -165,7 +173,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
nextToken: function(cursor)
{
if (this._internalJavaScriptTokenizer) {
if (this._condition.internalJavaScriptTokenizerCondition) {
// Re-set line to force </script> detection first.
this.line = this._line;
if (cursor !== this._internalJavaScriptTokenizer._line.length) {
......@@ -176,8 +184,8 @@ WebInspector.SourceHTMLTokenizer.prototype = {
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._internalJavaScriptTokenizer;
} else if (this._internalCSSTokenizer) {
delete this._condition.internalJavaScriptTokenizerCondition;
} else if (this._condition.internalCSSTokenizerCondition) {
// Re-set line to force </style> detection first.
this.line = this._line;
if (cursor !== this._internalCSSTokenizer._line.length) {
......@@ -188,7 +196,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._internalCSSTokenizer;
delete this._condition.internalCSSTokenizerCondition;
}
var cursorOnEnter = cursor;
......@@ -585,6 +593,7 @@ case 83:
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
this.styleSheetEnded(cursor - 7);
return cursor;
}
/* *********************************** */
......
......@@ -70,19 +70,23 @@ WebInspector.SourceHTMLTokenizer = function()
STYLE: 32
};
this.initialCondition = { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
this.condition = this.initialCondition;
this.condition = this.createInitialCondition();
}
WebInspector.SourceHTMLTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},
set line(line) {
if (this._internalJavaScriptTokenizer) {
if (this._condition.internalJavaScriptTokenizerCondition) {
var match = /<\/script/i.exec(line);
if (match) {
this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
} else
this._internalJavaScriptTokenizer.line = line;
} else if (this._internalCSSTokenizer) {
} else if (this._condition.internalCSSTokenizerCondition) {
var match = /<\/style/i.exec(line);
if (match) {
this._internalCSSTokenizer.line = line.substring(0, match.index);
......@@ -138,12 +142,19 @@ WebInspector.SourceHTMLTokenizer.prototype = {
return "html-attribute-value";
},
get _internalJavaScriptTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
},
get _internalCSSTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
},
scriptStarted: function(cursor)
{
if (!this._internalJavaScriptTokenizer) {
this._internalJavaScriptTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.initialCondition;
}
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
},
scriptEnded: function(cursor)
......@@ -152,10 +163,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
styleSheetStarted: function(cursor)
{
if (!this._internalCSSTokenizer) {
this._internalCSSTokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.initialCondition;
}
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
},
styleSheetEnded: function(cursor)
......@@ -164,7 +172,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
nextToken: function(cursor)
{
if (this._internalJavaScriptTokenizer) {
if (this._condition.internalJavaScriptTokenizerCondition) {
// Re-set line to force </script> detection first.
this.line = this._line;
if (cursor !== this._internalJavaScriptTokenizer._line.length) {
......@@ -175,8 +183,8 @@ WebInspector.SourceHTMLTokenizer.prototype = {
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._internalJavaScriptTokenizer;
} else if (this._internalCSSTokenizer) {
delete this._condition.internalJavaScriptTokenizerCondition;
} else if (this._condition.internalCSSTokenizerCondition) {
// Re-set line to force </style> detection first.
this.line = this._line;
if (cursor !== this._internalCSSTokenizer._line.length) {
......@@ -187,7 +195,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._internalCSSTokenizer;
delete this._condition.internalCSSTokenizerCondition;
}
var cursorOnEnter = cursor;
......@@ -284,7 +292,7 @@ WebInspector.SourceHTMLTokenizer.prototype = {
{
this.tokenType = "html-tag";
this._condition.parseCondition = this._parseConditions.INITIAL;
this.styleEnded(cursor - 7);
this.styleSheetEnded(cursor - 7);
return cursor;
}
......
/* Generated by re2c 0.13.5 on Thu Feb 25 21:44:55 2010 */
/* Generated by re2c 0.13.5 on Fri May 6 13:56:13 2011 */
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
......@@ -68,11 +68,15 @@ WebInspector.SourceJavaScriptTokenizer = function()
this.case_SSTRING = 1004;
this.case_REGEX = 1005;
this.initialCondition = { lexCondition: this._lexConditions.NODIV }
this.condition = this.initialCondition;
this.condition = this.createInitialCondition();
}
WebInspector.SourceJavaScriptTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.NODIV };
},
nextToken: function(cursor)
{
var cursorOnEnter = cursor;
......
......@@ -67,11 +67,15 @@ WebInspector.SourceJavaScriptTokenizer = function()
this.case_SSTRING = 1004;
this.case_REGEX = 1005;
this.initialCondition = { lexCondition: this._lexConditions.NODIV }
this.condition = this.initialCondition;
this.condition = this.createInitialCondition();
}
WebInspector.SourceJavaScriptTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.NODIV };
},
nextToken: function(cursor)
{
var cursorOnEnter = cursor;
......
......@@ -90,7 +90,7 @@ WebInspector.SourceTokenizer.Registry.prototype = {
var tokenizer = this._tokenizers[tokenizerClass];
if (!tokenizer) {
tokenizer = new WebInspector[tokenizerClass]();
this._tokenizers[mimeType] = tokenizer;
this._tokenizers[tokenizerClass] = tokenizer;
}
return tokenizer;
}
......
......@@ -141,7 +141,7 @@ WebInspector.TextEditorHighlighter.prototype = {
{
// Restore highlighter context taken from previous line.
var state = this._textModel.getAttribute(startLine - 1, "highlight");
var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.initialCondition);
var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition());
var tokensCount = 0;
for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment