| Index: Source/devtools/front_end/ScriptFormatterWorker.js | 
| diff --git a/Source/devtools/front_end/ScriptFormatterWorker.js b/Source/devtools/front_end/ScriptFormatterWorker.js | 
| index a8d6586a8f1d9fa8371d3bf701be2dc2dd9856e2..536ecac2ec2671e22022bdc862b22d9f25fffd1c 100644 | 
| --- a/Source/devtools/front_end/ScriptFormatterWorker.js | 
| +++ b/Source/devtools/front_end/ScriptFormatterWorker.js | 
| @@ -34,32 +34,43 @@ importScripts("cm/javascript.js"); | 
| importScripts("cm/xml.js"); | 
| importScripts("cm/htmlmixed.js"); | 
| WebInspector = {}; | 
| +FormatterWorker = {}; | 
| importScripts("CodeMirrorUtils.js"); | 
|  | 
| -onmessage = function(event) { | 
| +var onmessage = function(event) { | 
| if (!event.data.method) | 
| return; | 
|  | 
| -    self[event.data.method](event.data.params); | 
| +    FormatterWorker[event.data.method](event.data.params); | 
| }; | 
|  | 
| -function format(params) | 
| +/** | 
| + * @param {Object} params | 
| + */ | 
| +FormatterWorker.format = function(params) | 
| { | 
| // Default to a 4-space indent. | 
| var indentString = params.indentString || "    "; | 
| var result = {}; | 
|  | 
| if (params.mimeType === "text/html") { | 
| -        var formatter = new HTMLScriptFormatter(indentString); | 
| +        var formatter = new FormatterWorker.HTMLFormatter(indentString); | 
| result = formatter.format(params.content); | 
| +    } else if (params.mimeType === "text/css") { | 
| +        result.mapping = { original: [0], formatted: [0] }; | 
| +        result.content = FormatterWorker._formatCSS(params.content, result.mapping, 0, 0, indentString); | 
| } else { | 
| result.mapping = { original: [0], formatted: [0] }; | 
| -        result.content = formatScript(params.content, result.mapping, 0, 0, indentString); | 
| +        result.content = FormatterWorker._formatScript(params.content, result.mapping, 0, 0, indentString); | 
| } | 
| postMessage(result); | 
| } | 
|  | 
| -function getChunkCount(totalLength, chunkSize) | 
| +/** | 
| + * @param {number} totalLength | 
| + * @param {number} chunkSize | 
| + */ | 
| +FormatterWorker._chunkCount = function(totalLength, chunkSize) | 
| { | 
| if (totalLength <= chunkSize) | 
| return 1; | 
| @@ -69,12 +80,15 @@ function getChunkCount(totalLength, chunkSize) | 
| return (partialLength / chunkSize) + (remainder ? 1 : 0); | 
| } | 
|  | 
| -function outline(params) | 
| +/** | 
| + * @param {Object} params | 
| + */ | 
| +FormatterWorker.outline = function(params) | 
| { | 
| const chunkSize = 100000; // characters per data chunk | 
| const totalLength = params.content.length; | 
| const lines = params.content.split("\n"); | 
| -    const chunkCount = getChunkCount(totalLength, chunkSize); | 
| +    const chunkCount = FormatterWorker._chunkCount(totalLength, chunkSize); | 
| var outlineChunk = []; | 
| var previousIdentifier = null; | 
| var previousToken = null; | 
| @@ -142,13 +156,21 @@ function outline(params) | 
| postMessage({ chunk: outlineChunk, total: chunkCount, index: chunkCount }); | 
| } | 
|  | 
| -function formatScript(content, mapping, offset, formattedOffset, indentString) | 
| +/** | 
| + * @param {string} content | 
| + * @param {{original: Array.<number>, formatted: Array.<number>}} mapping | 
| + * @param {number} offset | 
| + * @param {number} formattedOffset | 
| + * @param {string} indentString | 
| + * @return {string} | 
| + */ | 
| +FormatterWorker._formatScript = function(content, mapping, offset, formattedOffset, indentString) | 
| { | 
| var formattedContent; | 
| try { | 
| -        var tokenizer = new Tokenizer(content); | 
| -        var builder = new FormattedContentBuilder(tokenizer.content(), mapping, offset, formattedOffset, indentString); | 
| -        var formatter = new JavaScriptFormatter(tokenizer, builder); | 
| +        var tokenizer = new FormatterWorker.JavaScriptTokenizer(content); | 
| +        var builder = new FormatterWorker.JavaScriptFormattedContentBuilder(tokenizer.content(), mapping, offset, formattedOffset, indentString); | 
| +        var formatter = new FormatterWorker.JavaScriptFormatter(tokenizer, builder); | 
| formatter.format(); | 
| formattedContent = builder.content(); | 
| } catch (e) { | 
| @@ -157,20 +179,41 @@ function formatScript(content, mapping, offset, formattedOffset, indentString) | 
| return formattedContent; | 
| } | 
|  | 
| -Array.prototype.keySet = function() | 
| +/** | 
| + * @param {string} content | 
| + * @param {{original: Array.<number>, formatted: Array.<number>}} mapping | 
| + * @param {number} offset | 
| + * @param {number} formattedOffset | 
| + * @param {string} indentString | 
| + * @return {string} | 
| + */ | 
| +FormatterWorker._formatCSS = function(content, mapping, offset, formattedOffset, indentString) | 
| { | 
| -    var keys = {}; | 
| -    for (var i = 0; i < this.length; ++i) | 
| -        keys[this[i]] = true; | 
| -    return keys; | 
| -}; | 
| +    var formattedContent; | 
| +    try { | 
| +        var builder = new FormatterWorker.CSSFormattedContentBuilder(content, mapping, offset, formattedOffset, indentString); | 
| +        var formatter = new FormatterWorker.CSSFormatter(content, builder); | 
| +        formatter.format(); | 
| +        formattedContent = builder.content(); | 
| +    } catch (e) { | 
| +        formattedContent = content; | 
| +    } | 
| +    return formattedContent; | 
| +} | 
|  | 
| -HTMLScriptFormatter = function(indentString) | 
| +/** | 
| + * @constructor | 
| + * @param {string} indentString | 
| + */ | 
| +FormatterWorker.HTMLFormatter = function(indentString) | 
| { | 
| this._indentString = indentString; | 
| } | 
|  | 
| -HTMLScriptFormatter.prototype = { | 
| +FormatterWorker.HTMLFormatter.prototype = { | 
| +    /** | 
| +     * @param {string} content | 
| +     */ | 
| format: function(content) | 
| { | 
| this.line = content; | 
| @@ -180,15 +223,25 @@ HTMLScriptFormatter.prototype = { | 
| this._position = 0; | 
|  | 
| var scriptOpened = false; | 
| +        var styleOpened = false; | 
| var tokenizer = WebInspector.CodeMirrorUtils.createTokenizer("text/html"); | 
| function processToken(tokenValue, tokenType, tokenStart, tokenEnd) { | 
| -            if (tokenValue.toLowerCase() === "<script" && tokenType === "xml-tag") { | 
| +            if (tokenType !== "xml-tag") | 
| +                return; | 
| +            if (tokenValue.toLowerCase() === "<script") { | 
| scriptOpened = true; | 
| -            } else if (scriptOpened && tokenValue === ">" && tokenType === "xml-tag") { | 
| +            } else if (scriptOpened && tokenValue === ">") { | 
| scriptOpened = false; | 
| this._scriptStarted(tokenEnd); | 
| -            } else if (tokenValue.toLowerCase() === "</script" && tokenType === "xml-tag") { | 
| +            } else if (tokenValue.toLowerCase() === "</script") { | 
| this._scriptEnded(tokenStart); | 
| +            } else if (tokenValue.toLowerCase() === "<style") { | 
| +                styleOpened = true; | 
| +            } else if (styleOpened && tokenValue === ">") { | 
| +                styleOpened = false; | 
| +                this._styleStarted(tokenEnd); | 
| +            } else if (tokenValue.toLowerCase() === "</style") { | 
| +                this._styleEnded(tokenStart); | 
| } | 
| } | 
| tokenizer(content, processToken.bind(this)); | 
| @@ -197,14 +250,53 @@ HTMLScriptFormatter.prototype = { | 
| return { content: this._formattedContent, mapping: this._mapping }; | 
| }, | 
|  | 
| +    /** | 
| +     * @param {number} cursor | 
| +     */ | 
| _scriptStarted: function(cursor) | 
| { | 
| +        this._handleSubFormatterStart(cursor); | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {number} cursor | 
| +     */ | 
| +    _scriptEnded: function(cursor) | 
| +    { | 
| +        this._handleSubFormatterEnd(FormatterWorker._formatScript, cursor); | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {number} cursor | 
| +     */ | 
| +    _styleStarted: function(cursor) | 
| +    { | 
| +        this._handleSubFormatterStart(cursor); | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {number} cursor | 
| +     */ | 
| +    _styleEnded: function(cursor) | 
| +    { | 
| +        this._handleSubFormatterEnd(FormatterWorker._formatCSS, cursor); | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {number} cursor | 
| +     */ | 
| +    _handleSubFormatterStart: function(cursor) | 
| +    { | 
| this._formattedContent += this._content.substring(this._position, cursor); | 
| this._formattedContent += "\n"; | 
| this._position = cursor; | 
| }, | 
|  | 
| -    _scriptEnded: function(cursor) | 
| +    /** | 
| +     * @param {function(string, {formatted: Array.<number>, original: Array.<number>}, number, number, string)} formatFunction | 
| +     * @param {number} cursor | 
| +     */ | 
| +    _handleSubFormatterEnd: function(formatFunction, cursor) | 
| { | 
| if (cursor === this._position) | 
| return; | 
| @@ -212,20 +304,32 @@ HTMLScriptFormatter.prototype = { | 
| var scriptContent = this._content.substring(this._position, cursor); | 
| this._mapping.original.push(this._position); | 
| this._mapping.formatted.push(this._formattedContent.length); | 
| -        var formattedScriptContent = formatScript(scriptContent, this._mapping, this._position, this._formattedContent.length, this._indentString); | 
| +        var formattedScriptContent = formatFunction(scriptContent, this._mapping, this._position, this._formattedContent.length, this._indentString); | 
|  | 
| this._formattedContent += formattedScriptContent; | 
| this._position = cursor; | 
| -    }, | 
| +    } | 
| } | 
|  | 
| +Array.prototype.keySet = function() | 
| +{ | 
| +    var keys = {}; | 
| +    for (var i = 0; i < this.length; ++i) | 
| +        keys[this[i]] = true; | 
| +    return keys; | 
| +}; | 
| + | 
| function require() | 
| { | 
| return parse; | 
| } | 
|  | 
| -var exports = {}; | 
| +/** | 
| + * @type {{tokenizer}} | 
| + */ | 
| +var exports = { tokenizer: null }; | 
| importScripts("UglifyJS/parse-js.js"); | 
| var parse = exports; | 
|  | 
| importScripts("JavaScriptFormatter.js"); | 
| +importScripts("CSSFormatter.js"); | 
|  |