diff options
author | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 10:00:22 +0000 |
---|---|---|
committer | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 10:00:22 +0000 |
commit | e91a73a43d79d437c59a5a44396e919628f3f707 (patch) | |
tree | 8ce266f9e73111a80fde6d913ca0e0f36cfb67c4 /webkit | |
parent | 028b8e5430ac280daf75c962020464e36e1f5a3f (diff) | |
download | chromium_src-e91a73a43d79d437c59a5a44396e919628f3f707.zip chromium_src-e91a73a43d79d437c59a5a44396e919628f3f707.tar.gz chromium_src-e91a73a43d79d437c59a5a44396e919628f3f707.tar.bz2 |
DevTools: Implement styles editing.
Review URL: http://codereview.chromium.org/100199
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14936 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/devtools/js/devtools.js | 23 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools_host_stub.js | 5 | ||||
-rw-r--r-- | webkit/glue/devtools/js/dom_agent.js | 51 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inject.js | 204 |
4 files changed, 235 insertions, 48 deletions
diff --git a/webkit/glue/devtools/js/devtools.js b/webkit/glue/devtools/js/devtools.js index 972ca02..2d387e4 100644 --- a/webkit/glue/devtools/js/devtools.js +++ b/webkit/glue/devtools/js/devtools.js @@ -564,12 +564,29 @@ WebInspector.ScopeChainSidebarPane.TreeElement.prototype.didResolveChildren_ = */ WebInspector.StylePropertyTreeElement.prototype.toggleEnabled = function(event) { - var disabled = !event.target.checked; - var self = this; - devtools.tools.getDomAgent().toggleNodeStyleAsync(this.style, !disabled, + var enabled = event.target.checked; + devtools.tools.getDomAgent().toggleNodeStyleAsync( + this.style, + enabled, this.name, function() { WebInspector.panels.elements.sidebarPanes.styles.needsUpdate = true; WebInspector.panels.elements.updateStyles(true); }); }; + + +/** + * @override + */ +WebInspector.StylePropertyTreeElement.prototype.applyStyleText = function( + styleText, updateInterface) { + devtools.tools.getDomAgent().applyStyleTextAsync(this.style, this.name, + styleText, + function() { + if (updateInterface) { + WebInspector.panels.elements.sidebarPanes.styles.needsUpdate = true; + WebInspector.panels.elements.updateStyles(true); + } + }); +}; diff --git a/webkit/glue/devtools/js/devtools_host_stub.js b/webkit/glue/devtools/js/devtools_host_stub.js index 60cf583..33b8535 100644 --- a/webkit/glue/devtools/js/devtools_host_stub.js +++ b/webkit/glue/devtools/js/devtools_host_stub.js @@ -185,8 +185,9 @@ RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId, } ] }; - } else if (functionName == 'toggleNodeStyle') { - alert('toggleNodeStyle ' + args); + } else if (functionName == 'toggleNodeStyle' || + functionName == 'applyStyleText') { + alert(functionName + '(' + args + ')'); } else { alert('Unexpected utility function:' + functionName); } diff --git a/webkit/glue/devtools/js/dom_agent.js b/webkit/glue/devtools/js/dom_agent.js index d0c8f70..5f50fa1 100644 --- a/webkit/glue/devtools/js/dom_agent.js +++ b/webkit/glue/devtools/js/dom_agent.js @@ -829,9 +829,7 @@ devtools.DomAgent.prototype.getSearchResultNode = function(index) { */ devtools.DomAgent.prototype.getNodePropertiesAsync = function(nodeId, path, protoDepth, callback) { - var mycallback = - goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); - var callbackId = devtools.Callback.wrap(mycallback); + var callbackId = this.utilityFunctionCallbackWrapper_(callback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, 'getProperties', nodeId, goog.json.serialize([path, protoDepth])); @@ -845,9 +843,7 @@ devtools.DomAgent.prototype.getNodePropertiesAsync = function(nodeId, */ devtools.DomAgent.prototype.getNodePrototypesAsync = function(nodeId, callback) { - var mycallback = - goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); - var callbackId = devtools.Callback.wrap(mycallback); + var callbackId = this.utilityFunctionCallbackWrapper_(callback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, 'getPrototypes', nodeId, '[]'); }; @@ -861,9 +857,7 @@ devtools.DomAgent.prototype.getNodePrototypesAsync = function(nodeId, */ devtools.DomAgent.prototype.getNodeStylesAsync = function(node, authorOnly, callback) { - var mycallback = - goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); - var callbackId = devtools.Callback.wrap(mycallback); + var callbackId = this.utilityFunctionCallbackWrapper_(callback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, 'getStyles', node.id_, @@ -880,9 +874,7 @@ devtools.DomAgent.prototype.getNodeStylesAsync = function(node, */ devtools.DomAgent.prototype.toggleNodeStyleAsync = function( style, enabled, name, callback) { - var mycallback = - goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); - var callbackId = devtools.Callback.wrap(mycallback); + var callbackId = this.utilityFunctionCallbackWrapper_(callback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, 'toggleNodeStyle', style.nodeId_, @@ -891,15 +883,38 @@ devtools.DomAgent.prototype.toggleNodeStyleAsync = function( /** + * Applies new text to a style. + * @param {devtools.CSSStyleDeclaration} style Style to edit. + * @param {string} name Property name to edit. + * @param {string} styleText Text to set the style from. + * @param {Function} callback. + */ +devtools.DomAgent.prototype.applyStyleTextAsync = function( + style, name, styleText, callback) { + var callbackId = this.utilityFunctionCallbackWrapper_(callback); + RemoteToolsAgent.ExecuteUtilityFunction( + callbackId, + 'applyStyleText', + style.nodeId_, + goog.json.serialize([style.id_, name, styleText])); +}; + + +/** * Dumps exception if something went wrong in ExecuteUtilityFunction. + * @param {Function} callback Callback to wrap. + * @return {number} Callback id. */ devtools.DomAgent.prototype.utilityFunctionCallbackWrapper_ = - function(callback, result, exception) { - if (exception && exception.length) { - debugPrint('Exception in ExecuteUtilityFunction styles:' + exception); - return; - } - callback(result); + function(callback) { + var mycallback = function(result, exception) { + if (exception && exception.length) { + debugPrint('Exception in ExecuteUtilityFunction styles:' + exception); + return; + } + callback(result); + }; + return devtools.Callback.wrap(mycallback); }; diff --git a/webkit/glue/devtools/js/inject.js b/webkit/glue/devtools/js/inject.js index 1ef97b0..a6d7d0b 100644 --- a/webkit/glue/devtools/js/inject.js +++ b/webkit/glue/devtools/js/inject.js @@ -111,28 +111,28 @@ devtools.Injected.prototype.getStyles = function(node, authorOnly) { if (!node.nodeType == Node.ELEMENT_NODE) { return {}; } - var matchedRules = window.getMatchedCSSRules(node, '', authorOnly); + var matchedRules = window.getMatchedCSSRules(node, '', false); var matchedCSSRulesObj = []; for (var i = 0; matchedRules && i < matchedRules.length; ++i) { - var rule = matchedRules[i]; - var style = this.serializeStyle_(rule.style); + var rule = matchedRules[i]; + var parentStyleSheet = rule.parentStyleSheet; + var isUserAgent = parentStyleSheet && !parentStyleSheet.ownerNode && + !parentStyleSheet.href; + var isUser = parentStyleSheet && parentStyleSheet.ownerNode && + parentStyleSheet.ownerNode.nodeName == '#document'; + + var style = this.serializeStyle_(rule.style, !isUserAgent && !isUser); var ruleValue = { 'selector' : rule.selectorText, 'style' : style }; - if (rule.parentStyleSheet) { + if (parentStyleSheet) { ruleValue['parentStyleSheet'] = { - 'href' : rule.parentStyleSheet.href, - 'ownerNodeName' : rule.parentStyleSheet.ownerNode ? - rule.parentStyleSheet.ownerNode.name : null + 'href' : parentStyleSheet.href, + 'ownerNodeName' : parentStyleSheet.ownerNode ? + parentStyleSheet.ownerNode.name : null }; } - var parentStyleSheetHref = (rule.parentStyleSheet ? - rule.parentStyleSheet.href : undefined); - var parentStyleSheetOwnerNodeName; - if (rule.parentStyleSheet && rule.parentStyleSheet.ownerNode) { - parentStyleSheetOwnerNodeName = rule.parentStyleSheet.ownerNode.name; - } matchedCSSRulesObj.push(ruleValue); } @@ -141,12 +141,11 @@ devtools.Injected.prototype.getStyles = function(node, authorOnly) { for (var i = 0; attributes && i < attributes.length; ++i) { if (attributes[i].style) { attributeStyles[attributes[i].name] = - this.serializeStyle_(attributes[i].style); + this.serializeStyle_(attributes[i].style, true); } } - var result = { - 'inlineStyle' : this.serializeStyle_(node.style), + 'inlineStyle' : this.serializeStyle_(node.style, true), 'computedStyle' : this.serializeStyle_( window.getComputedStyle(node, '')), 'matchedCSSRules' : matchedCSSRulesObj, @@ -189,19 +188,21 @@ devtools.Injected.prototype.getStyleForId_ = function(node, id) { /** * Converts given style into serializable object. * @param {CSSStyleDeclaration} style Style to serialize. + * @param {boolean} opt_bind Determins whether this style should be bound. * @return {Array<Object>} Serializable object. * @private */ -devtools.Injected.prototype.serializeStyle_ = function(style) { +devtools.Injected.prototype.serializeStyle_ = function(style, opt_bind) { if (!style) { return []; } - if (!style.__id) { - style.__id = this.lastStyleId_++; + var id = style.__id; + if (opt_bind && !id) { + id = style.__id = this.lastStyleId_++; this.styles_.push(style); } var result = [ - style.__id, + id, style.__disabledProperties, style.__disabledPropertyValues, style.__disabledPropertyPriorities @@ -270,11 +271,75 @@ devtools.Injected.prototype.toggleNodeStyle = function(node, styleId, enabled, /** - * Returns longhand proeprties for a given shorthand one. - * @param {CSSStyleDeclaration} style Style declaration to use for lookup. - * @param {string} shorthandProperty Shorthand property to get longhands for. - * @return {Array.<string>} Array with longhand properties. - * @private + * Applies given text to a style. + * @param {Node} node Node to get prorotypes for. + * @param {number} styleId Id of style to toggle. + * @param {string} name Style element name. + * @param {string} styleText New style text. + * @return {boolean} True iff style has been edited successfully. + */ +devtools.Injected.prototype.applyStyleText = function(node, styleId, + name, styleText) { + var style = this.getStyleForId_(node, styleId); + if (!style) { + return false; + } + + var styleTextLength = this.trimWhitespace_(styleText).length; + + // Create a new element to parse the user input CSS. + var parseElement = document.createElement("span"); + parseElement.setAttribute("style", styleText); + + var tempStyle = parseElement.style; + if (tempStyle.length || !styleTextLength) { + // The input was parsable or the user deleted everything, so remove the + // original property from the real style declaration. If this represents + // a shorthand remove all the longhand properties. + if (style.getPropertyShorthand(name)) { + var longhandProperties = this.getLonghandProperties_(style, name); + for (var i = 0; i < longhandProperties.length; ++i) { + style.removeProperty(longhandProperties[i]); + } + } else { + style.removeProperty(name); + } + } + if (!tempStyle.length) { + // The user typed something, but it didn't parse. Just abort and restore + // the original title for this property. + return false; + } + + // Iterate of the properties on the test element's style declaration and + // add them to the real style declaration. We take care to move shorthands. + var foundShorthands = {}; + var uniqueProperties = this.getUniqueStyleProperties_(tempStyle); + for (var i = 0; i < uniqueProperties.length; ++i) { + var name = uniqueProperties[i]; + var shorthand = tempStyle.getPropertyShorthand(name); + + if (shorthand && shorthand in foundShorthands) { + continue; + } + + if (shorthand) { + var value = this.getShorthandValue_(tempStyle, shorthand); + var priority = this.getShorthandPriority_(tempStyle, shorthand); + foundShorthands[shorthand] = true; + } else { + var value = tempStyle.getPropertyValue(name); + var priority = tempStyle.getPropertyPriority(name); + } + // Set the property on the real style declaration. + style.setProperty((shorthand || name), value, priority); + } + return true; +}; + + +/** + * Taken from utilities.js as is for injected evaluation. */ devtools.Injected.prototype.getLonghandProperties_ = function(style, shorthandProperty) { @@ -292,3 +357,92 @@ devtools.Injected.prototype.getLonghandProperties_ = function(style, } return properties; }; + + +/** + * Taken from utilities.js as is for injected evaluation. + */ +devtools.Injected.prototype.getShorthandValue_ = function(style, + shorthandProperty) { + var value = style.getPropertyValue(shorthandProperty); + if (!value) { + // Some shorthands (like border) return a null value, so compute a + // shorthand value. + // FIXME: remove this when http://bugs.webkit.org/show_bug.cgi?id=15823 + // is fixed. + + var foundProperties = {}; + for (var i = 0; i < style.length; ++i) { + var individualProperty = style[i]; + if (individualProperty in foundProperties || + style.getPropertyShorthand(individualProperty) !== + shorthandProperty) { + continue; + } + + var individualValue = style.getPropertyValue(individualProperty); + if (style.isPropertyImplicit(individualProperty) || + individualValue === "initial") { + continue; + } + + foundProperties[individualProperty] = true; + + if (!value) { + value = ""; + } else if (value.length) { + value += " "; + } + value += individualValue; + } + } + return value; +}; + + +/** + * Taken from utilities.js as is for injected evaluation. + */ +devtools.Injected.prototype.getShorthandPriority_ = function(style, + shorthandProperty) { + var priority = style.getPropertyPriority(shorthandProperty); + if (!priority) { + for (var i = 0; i < style.length; ++i) { + var individualProperty = style[i]; + if (style.getPropertyShorthand(individualProperty) !== + shorthandProperty) { + continue; + } + priority = style.getPropertyPriority(individualProperty); + break; + } + } + return priority; +}; + + +/** + * Taken from utilities.js as is for injected evaluation. + */ +devtools.Injected.prototype.trimWhitespace_ = function(str) { + return str.replace(/^[\s\xA0]+|[\s\xA0]+$/g, ''); +}; + + +/** + * Taken from utilities.js as is for injected evaluation. + */ +devtools.Injected.prototype.getUniqueStyleProperties_ = function(style) { + var properties = []; + var foundProperties = {}; + + for (var i = 0; i < style.length; ++i) { + var property = style[i]; + if (property in foundProperties) { + continue; + } + foundProperties[property] = true; + properties.push(property); + } + return properties; +}; |