Index: third_party/WebKit/Source/devtools/front_end/formatter_worker/FormattedContentBuilder.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormattedContentBuilder.js b/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormattedContentBuilder.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..98fb0634c47b855043ee522745f9149f4e643972 |
--- /dev/null |
+++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/FormattedContentBuilder.js |
@@ -0,0 +1,160 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @constructor |
+ * @param {!{original: !Array.<number>, formatted: !Array.<number>}} mapping |
+ * @param {number} originalOffset |
+ * @param {number} formattedOffset |
+ * @param {string} indentString |
+ */ |
+FormatterWorker.FormattedContentBuilder = function(mapping, originalOffset, formattedOffset, indentString) |
+{ |
+ this._originalOffset = originalOffset; |
+ this._lastOriginalPosition = 0; |
+ |
+ this._formattedContent = []; |
+ this._formattedContentLength = 0; |
+ this._formattedOffset = formattedOffset; |
+ this._lastFormattedPosition = 0; |
+ |
+ this._mapping = mapping; |
+ |
+ this._lineNumber = 0; |
+ this._nestingLevel = 0; |
+ this._indentString = indentString; |
+ /** @type {!Map<number, string>} */ |
+ this._cachedIndents = new Map(); |
+ |
+ this._newLines = 0; |
+ this._softSpace = false; |
+ this._hardSpaces = 0; |
+} |
+ |
+FormatterWorker.FormattedContentBuilder.prototype = { |
+ /** |
+ * @param {string} token |
+ * @param {number} startPosition |
+ * @param {number} startLine |
+ * @param {number} endLine |
+ */ |
+ addToken: function(token, startPosition, startLine, endLine) |
+ { |
+ if (this._lineNumber < startLine) |
+ this._newLines = Math.max(this._newLines, startLine - this._lineNumber); |
+ |
+ var last = this._formattedContent.peekLast(); |
+ if (last && /\w/.test(last[last.length - 1]) && /\w/.test(token)) |
+ this.addSoftSpace(); |
+ |
+ this._appendFormatting(); |
+ |
+ // Insert token. |
+ this._addMappingIfNeeded(startPosition); |
+ this._addText(token); |
+ this._lineNumber = endLine; |
+ }, |
+ |
+ addSoftSpace: function() |
+ { |
+ if (!this._hardSpaces) |
+ this._softSpace = true; |
+ }, |
+ |
+ addHardSpace: function() |
+ { |
+ this._softSpace = false; |
+ ++this._hardSpaces; |
+ }, |
+ |
+ /** |
+ * @param {boolean=} noSquash |
+ */ |
+ addNewLine: function(noSquash) |
+ { |
+ if (noSquash) |
+ ++this._newLines; |
+ else |
+ this._newLines = this._newLines || 1; |
+ }, |
+ |
+ increaseNestingLevel: function() |
+ { |
+ this._nestingLevel += 1; |
+ }, |
+ |
+ decreaseNestingLevel: function() |
+ { |
+ if (this._nestingLevel > 0) |
+ this._nestingLevel -= 1; |
+ }, |
+ |
+ _appendFormatting: function() |
+ { |
+ if (this._newLines) { |
+ for (var i = 0; i < this._newLines; ++i) |
+ this._addText("\n"); |
+ this._addText(this._indent()); |
+ } else if (this._softSpace) { |
+ this._addText(" "); |
+ } |
+ if (this._hardSpaces) { |
+ for (var i = 0; i < this._hardSpaces; ++i) |
+ this._addText(" "); |
+ } |
+ this._newLines = 0; |
+ this._softSpace = false; |
+ this._hardSpaces = 0; |
+ }, |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ content: function() |
+ { |
+ return this._formattedContent.join("") + (this._newLines ? "\n" : ""); |
+ }, |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ _indent: function() |
+ { |
+ var cachedValue = this._cachedIndents.get(this._nestingLevel) |
+ if (cachedValue) |
+ return cachedValue; |
+ |
+ var fullIndent = ""; |
+ for (var i = 0; i < this._nestingLevel; ++i) |
+ fullIndent += this._indentString; |
+ |
+ // Cache a maximum of 20 nesting level indents. |
+ if (this._nestingLevel <= 20) |
+ this._cachedIndents.set(this._nestingLevel, fullIndent); |
+ return fullIndent; |
+ }, |
+ |
+ /** |
+ * @param {string} text |
+ */ |
+ _addText: function(text) |
+ { |
+ this._formattedContent.push(text); |
+ this._formattedContentLength += text.length; |
+ }, |
+ |
+ /** |
+ * @param {number} originalPosition |
+ */ |
+ _addMappingIfNeeded: function(originalPosition) |
+ { |
+ if (originalPosition - this._lastOriginalPosition === this._formattedContentLength - this._lastFormattedPosition) |
+ return; |
+ this._mapping.original.push(this._originalOffset + originalPosition); |
+ this._lastOriginalPosition = originalPosition; |
+ this._mapping.formatted.push(this._formattedOffset + this._formattedContentLength); |
+ this._lastFormattedPosition = this._formattedContentLength; |
+ } |
+} |
+ |