Chromium Code Reviews| Index: Source/devtools/front_end/sdk/CSSStyleModel.js |
| diff --git a/Source/devtools/front_end/sdk/CSSStyleModel.js b/Source/devtools/front_end/sdk/CSSStyleModel.js |
| index df5827160d332857a26aca705825db12c8a9f9c3..06bb309955cf1359c0fbdc1fc2a09366b1c80b85 100644 |
| --- a/Source/devtools/front_end/sdk/CSSStyleModel.js |
| +++ b/Source/devtools/front_end/sdk/CSSStyleModel.js |
| @@ -667,7 +667,6 @@ WebInspector.CSSStyleDeclaration = function(cssModel, payload) |
| this.__disabledProperties = {}; // DISABLED properties: { index -> CSSProperty } |
| var payloadPropertyCount = payload.cssProperties.length; |
| - |
| for (var i = 0; i < payloadPropertyCount; ++i) { |
| var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]); |
| this._allProperties.push(property); |
| @@ -897,36 +896,47 @@ WebInspector.CSSStyleDeclaration.prototype = { |
| }, |
| /** |
| - * @param {number} index |
| - * @param {string} name |
| - * @param {string} value |
| - * @param {function(?WebInspector.CSSStyleDeclaration)=} userCallback |
| + * @param {string} text |
| + * @param {boolean} majorChange |
| + * @param {function(?WebInspector.CSSStyleDeclaration)} callback |
| */ |
| - insertPropertyAt: function(index, name, value, userCallback) |
| + setText: function(text, majorChange, callback) |
| { |
| + if (!this.styleSheetId) { |
| + callback(null); |
| + return; |
| + } |
| + |
| /** |
| - * @param {?string} error |
| - * @param {!CSSAgent.CSSStyle} payload |
| - * @this {!WebInspector.CSSStyleDeclaration} |
| + * @param {?Protocol.Error} error |
| + * @param {!CSSAgent.CSSStyle} stylePayload |
| + * @this {WebInspector.CSSStyleDeclaration} |
| */ |
| - function callback(error, payload) |
| + function mycallback(error, stylePayload) |
| { |
| this._cssModel._pendingCommandsMajorState.pop(); |
| - if (!userCallback) |
| + if (!error) { |
| + if (majorChange) |
| + this._cssModel._domModel.markUndoableState(); |
| + callback(WebInspector.CSSStyleDeclaration.parsePayload(this._cssModel, stylePayload)); |
| return; |
| - |
| - if (error) { |
| - console.error(error); |
| - userCallback(null); |
| - } else |
| - userCallback(WebInspector.CSSStyleDeclaration.parsePayload(this._cssModel, payload)); |
| + } |
| + callback(null); |
| } |
| - if (!this.styleSheetId) |
| - throw "No stylesheet id"; |
| + this._cssModel._pendingCommandsMajorState.push(majorChange); |
| + this._cssModel._agent.setStyleText(this.styleSheetId, this.range.serializeToObject(), text, mycallback.bind(this)); |
| + }, |
| - this._cssModel._pendingCommandsMajorState.push(true); |
| - this._cssModel._agent.setPropertyText(this.styleSheetId, this._insertionRange(index), name + ": " + value + ";", callback.bind(this)); |
| + /** |
| + * @param {number} index |
| + * @param {string} name |
| + * @param {string} value |
| + * @param {function(?WebInspector.CSSStyleDeclaration)=} userCallback |
| + */ |
| + insertPropertyAt: function(index, name, value, userCallback) |
| + { |
| + this.newBlankProperty(index).setText(name + ": " + value + ";", false, true, userCallback); |
| }, |
| /** |
| @@ -1241,63 +1251,137 @@ WebInspector.CSSProperty.prototype = { |
| */ |
| setText: function(propertyText, majorChange, overwrite, userCallback) |
| { |
| + if (!this.ownerStyle) |
| + throw "No ownerStyle for property"; |
| + |
| + if (!this.ownerStyle.styleSheetId) |
| + throw "No owner style id"; |
| + |
| + if (majorChange) |
| + WebInspector.userMetrics.StyleRuleEdited.record(); |
| + |
| + if (overwrite && propertyText === this.propertyText) { |
| + if (majorChange) |
| + this.ownerStyle._cssModel._domModel.markUndoableState(); |
| + if (userCallback) |
| + userCallback(this.ownerStyle); |
| + return; |
| + } |
| + |
|
lushnikov
2015/06/19 15:34:21
remove typecast
pfeldman
2015/06/19 15:59:28
Done.
|
| + var range = /** @type {!WebInspector.TextRange} */ (this.range).relativeTo(this.ownerStyle.range.startLine, this.ownerStyle.range.startColumn); |
| + var indentation = this.ownerStyle.cssText ? this._detectIndentation(this.ownerStyle.cssText) : WebInspector.moduleSetting("textEditorIndent").get(); |
| + var endIntentation = this.ownerStyle.cssText ? indentation.substring(0, this.ownerStyle.range.endColumn) : ""; |
| + var newStyleText = range.replaceInText(this.ownerStyle.cssText || "", ";" + propertyText); |
| + |
| + this._formatStyle(newStyleText, indentation, endIntentation, setStyleText.bind(this)); |
| + |
| /** |
| - * @param {?WebInspector.CSSStyleDeclaration} style |
| + * @param {string} styleText |
| + * @this {WebInspector.CSSProperty} |
| */ |
| - function enabledCallback(style) |
| + function setStyleText(styleText) |
| { |
| - if (userCallback) |
| - userCallback(style); |
| + this.ownerStyle.setText(styleText, majorChange, callback.bind(this)); |
| } |
| /** |
| - * @param {?string} error |
| - * @param {!CSSAgent.CSSStyle} stylePayload |
| + * @param {?WebInspector.CSSStyleDeclaration} style |
| * @this {WebInspector.CSSProperty} |
| */ |
| - function callback(error, stylePayload) |
| + function callback(style) |
| { |
| - this.ownerStyle._cssModel._pendingCommandsMajorState.pop(); |
| - if (!error) { |
| - if (majorChange) |
| - this.ownerStyle._cssModel._domModel.markUndoableState(); |
| - var style = WebInspector.CSSStyleDeclaration.parsePayload(this.ownerStyle._cssModel, stylePayload); |
| + if (style) { |
| var newProperty = style.allProperties[this.index]; |
| - |
| if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) { |
| newProperty.setDisabled(false, enabledCallback); |
|
lushnikov
2015/06/19 15:34:21
you swear you can remove this
pfeldman
2015/06/19 15:59:28
Done.
|
| return; |
| } |
| - if (userCallback) |
| - userCallback(style); |
| - } else { |
| - if (userCallback) |
| - userCallback(null); |
| } |
| + if (userCallback) |
| + userCallback(style); |
| } |
| - if (!this.ownerStyle) |
| - throw "No ownerStyle for property"; |
| + /** |
| + * @param {?WebInspector.CSSStyleDeclaration} style |
| + */ |
| + function enabledCallback(style) |
| + { |
| + if (userCallback) |
| + userCallback(style); |
| + } |
| + }, |
| - if (!this.ownerStyle.styleSheetId) |
| - throw "No owner style id"; |
| + /** |
| + * @param {string} styleText |
| + * @param {string} indentation |
| + * @param {string} endIndentation |
| + * @param {function(string)} callback |
| + */ |
| + _formatStyle: function(styleText, indentation, endIndentation, callback) |
| + { |
| + self.runtime.instancePromise(WebInspector.TokenizerFactory).then(processTokens); |
| + var result = ""; |
| - if (majorChange) |
| - WebInspector.userMetrics.StyleRuleEdited.record(); |
| + /** |
| + * @param {!WebInspector.TokenizerFactory} tokenizerFactory |
| + */ |
| + function processTokens(tokenizerFactory) |
| + { |
| + var tokenize = tokenizerFactory.createTokenizer("text/css"); |
| + tokenize(styleText, processToken); |
| + callback(result + (indentation ? "\n" + endIndentation : "")); |
| + } |
| - if (overwrite && propertyText === this.propertyText) { |
| - if (majorChange) |
| - this.ownerStyle._cssModel._domModel.markUndoableState(); |
| - if (userCallback) |
| - userCallback(this.ownerStyle); |
| - return; |
| + var lastWasSemicolon = true; |
| + var trimWhitespace = true; |
|
lushnikov
2015/06/19 15:34:21
insideProperty
pfeldman
2015/06/19 15:59:28
Done.
|
| + /** |
| + * @param {string} token |
| + * @param {?string} tokenType |
| + * @param {number} column |
| + * @param {number} newColumn |
| + */ |
| + function processToken(token, tokenType, column, newColumn) |
| + { |
| + var isSemicolon = token === ";"; |
| + if (isSemicolon && lastWasSemicolon) |
| + return; |
| + lastWasSemicolon = isSemicolon || (lastWasSemicolon && tokenType === "css-comment") || (lastWasSemicolon && !token.trim()); |
| + |
| + // No formatting, only remove dupe ; |
| + if (!indentation) { |
| + result += token; |
| + return; |
| + } |
| + |
| + // Format line breaks. |
| + if (trimWhitespace && !token.trim()) |
| + return; |
| + if (tokenType === "css-comment" && token.includes(":") && token.includes(";")) { |
| + result += "\n" + indentation + token; |
| + trimWhitespace = true; |
| + return; |
| + } |
| + |
| + if (isSemicolon) |
| + trimWhitespace = true; |
| + if (tokenType === "css-tag") { |
| + result += "\n" + indentation; |
| + trimWhitespace = false; |
| + } |
| + result += token; |
| } |
| + }, |
| - // An index past all the properties adds a new property to the style. |
| - var cssModel = this.ownerStyle._cssModel; |
| - cssModel._pendingCommandsMajorState.push(majorChange); |
| - var range = /** @type {!WebInspector.TextRange} */ (this.range); |
| - cssModel._agent.setPropertyText(this.ownerStyle.styleSheetId, overwrite ? range : range.collapseToStart(), propertyText, callback.bind(this)); |
| + /** |
| + * @param {string} text |
| + * @return {string} |
| + */ |
| + _detectIndentation: function(text) |
| + { |
| + var lines = text.split("\n"); |
| + if (lines.length < 2) |
| + return ""; |
| + return WebInspector.TextUtils.lineIndent(lines[1]); |
| }, |
| /** |