diff options
author | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-29 13:07:14 +0000 |
---|---|---|
committer | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-29 13:07:14 +0000 |
commit | f6a2f61481761768352fafff68faca28c9a73bd1 (patch) | |
tree | e3f2f3aaf7d0b37203215d23de8248cb42416ab8 /webkit/glue/devtools/js | |
parent | 251d1dbb34d1e365c78f81bac17ed71ec32cd6c5 (diff) | |
download | chromium_src-f6a2f61481761768352fafff68faca28c9a73bd1.zip chromium_src-f6a2f61481761768352fafff68faca28c9a73bd1.tar.gz chromium_src-f6a2f61481761768352fafff68faca28c9a73bd1.tar.bz2 |
DevTools: Implement styles toggle:
1. Split inject.js into injected object and the dispatch.
2. Surround utility function call with try/catch, pass potential exception all way to the client.
3. Fix user and user agent scripts detection
4. Introduce toggleStyle
5. Remove __defineGetter__ from the styles code: make things simple
6. Beautify code.
Review URL: http://codereview.chromium.org/99184
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14839 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/devtools/js')
-rw-r--r-- | webkit/glue/devtools/js/devtools.js | 17 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools_host_stub.js | 22 | ||||
-rw-r--r-- | webkit/glue/devtools/js/dom_agent.js | 163 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inject.js | 440 | ||||
-rw-r--r-- | webkit/glue/devtools/js/inject_dispatch.js | 33 |
5 files changed, 445 insertions, 230 deletions
diff --git a/webkit/glue/devtools/js/devtools.js b/webkit/glue/devtools/js/devtools.js index f263962..53581d1 100644 --- a/webkit/glue/devtools/js/devtools.js +++ b/webkit/glue/devtools/js/devtools.js @@ -549,7 +549,7 @@ WebInspector.ScopeChainSidebarPane.TreeElement.prototype.onpopulate = /** * Callback function used with the resolveChildren. */ - WebInspector.ScopeChainSidebarPane.TreeElement.prototype.didResolveChildren_ = +WebInspector.ScopeChainSidebarPane.TreeElement.prototype.didResolveChildren_ = function(object) { this.removeChildren(); @@ -558,3 +558,18 @@ WebInspector.ScopeChainSidebarPane.TreeElement.prototype.onpopulate = this.appendChild(new constructor(object, name)); } }; + + +/** + * @override + */ +WebInspector.StylePropertyTreeElement.prototype.toggleEnabled = + function(event) { + var disabled = !event.target.checked; + var self = this; + devtools.tools.getDomAgent().toggleNodeStyleAsync(this.style, !disabled, + this.name, + function() { + 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 89885d5..60cf583 100644 --- a/webkit/glue/devtools/js/devtools_host_stub.js +++ b/webkit/glue/devtools/js/devtools_host_stub.js @@ -158,7 +158,7 @@ RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId, functionName, nodeId, args) { setTimeout(function() { var result = []; - if (functionName == 'devtools$$getProperties') { + if (functionName == 'getProperties') { result = [ 'undefined', 'undefined_key', undefined, 'string', 'string_key', 'value', @@ -168,28 +168,30 @@ RemoteToolsAgentStub.prototype.ExecuteUtilityFunction = function(callId, 'boolean', 'boolean_key', true, 'number', 'num_key', 911, 'date', 'date_key', new Date() ]; - } else if (functionName == 'devtools$$getPrototypes') { + } else if (functionName == 'getPrototypes') { result = ['Proto1', 'Proto2', 'Proto3']; - } else if (functionName == 'devtools$$getStyles') { + } else if (functionName == 'getStyles') { result = { - 'computedStyle' : [['display', false, false, '', 'none']], - 'inlineStyle' : [['display', false, false, '', 'none']], + 'computedStyle' : [0, null, null, null, ['display', false, false, '', 'none']], + 'inlineStyle' : [1, null, null, null, ['display', false, false, '', 'none']], 'styleAttributes' : { - attr: [['display', false, false, '', 'none']] + attr: [2, null, null, null, ['display', false, false, '', 'none']] }, 'matchedCSSRules' : [ { 'selector' : 'S', - 'style' : [['display', false, false, '', 'none']], - 'parentStyleSheetHref' : 'http://localhost', - 'parentStyleSheetOwnerNodeName' : 'DIV' + 'style' : [3, null, null, null, ['display', false, false, '', 'none']], + 'parentStyleSheet' : { 'href' : 'http://localhost', + 'ownerNodeName' : 'DIV' } } ] }; + } else if (functionName == 'toggleNodeStyle') { + alert('toggleNodeStyle ' + args); } else { alert('Unexpected utility function:' + functionName); } RemoteToolsAgent.DidExecuteUtilityFunction(callId, - goog.json.serialize(result)); + goog.json.serialize(result), ''); }, 0); }; diff --git a/webkit/glue/devtools/js/dom_agent.js b/webkit/glue/devtools/js/dom_agent.js index ce7740e..d0c8f70 100644 --- a/webkit/glue/devtools/js/dom_agent.js +++ b/webkit/glue/devtools/js/dom_agent.js @@ -56,7 +56,6 @@ devtools.DomNode = function(doc, payload) { this.firstChild = null; this.parentNode = null; - this.styles_ = null; this.disabledStyleProperties_ = {}; if (payload.length > devtools.PayloadIndex.CHILD_NODES) { @@ -64,6 +63,10 @@ devtools.DomNode = function(doc, payload) { this.setChildrenPayload_( payload[devtools.PayloadIndex.CHILD_NODES]); } + + this.computedStyle_ = null; + this.style = null; + this.matchedCSSRules_ = []; }; @@ -222,13 +225,9 @@ devtools.DomNode.prototype.setAttribute = function(name, value) { */ devtools.DomNode.prototype.addAttribute_ = function(name, value) { var attr = { - 'name': name, - 'value': value, - node_: this, - /* Must be called after node.setStyles_. */ - get style() { - return this.node_.styles_.attributes[this.name]; - } + 'name': name, + 'value': value, + node_: this }; this.attributesMap_[name] = attr; @@ -255,15 +254,6 @@ devtools.DomNode.prototype.removeAttribute = function(name) { /** - * Returns inline style (if styles has loaded). Must be called after - * node.setStyles_. - */ -devtools.DomNode.prototype.__defineGetter__('style', function() { - return this.styles_.inlineStyle; -}); - - -/** * Makes available the following methods and properties: * - node.style property * - node.document.defaultView.getComputedStyles(node) @@ -281,40 +271,37 @@ devtools.DomNode.prototype.__defineGetter__('style', function() { */ devtools.DomNode.prototype.setStyles = function(computedStyle, inlineStyle, styleAttributes, matchedCSSRules) { - var styles = {}; - styles.computedStyle = this.makeStyle_(computedStyle); - styles.inlineStyle = this.makeStyle_(inlineStyle); + this.computedStyle_ = this.makeStyle_(computedStyle); + this.style = this.makeStyle_(inlineStyle); - styles.attributes = {}; for (var name in styleAttributes) { - var style = this.makeStyle_(styleAttributes[name]); - styles.attributes[name] = style; + if (this.attributesMap_[name]) { + this.attributesMap_[name].style = + this.makeStyle_(styleAttributes[name]); + } } - styles.matchedCSSRules = []; + this.matchedCSSRules_ = []; for (var i = 0; i < matchedCSSRules.length; i++) { var descr = matchedCSSRules[i]; - var selector = descr.selector; - var style = this.makeStyle_(descr.style); - var parentStyleSheet = undefined; - if (descr.parentStyleSheetHref) { - parentStyleSheet = {href: descr.parentStyleSheetHref}; - - if (descr.parentStyleSheetOwnerNodeName) { - parentStyleSheet.ownerNode = - {nodeName: descr.parentStyleSheetOwnerNodeName}; + var rule = {}; + rule.selectorText = descr['selector']; + rule.style = this.makeStyle_(descr['style']); + + if (descr['parentStyleSheet']) { + var parentStyleMock = {}; + parentStyleMock.href = descr['parentStyleSheet']['href']; + var nodeName = descr['parentStyleSheet']['ownerNodeName']; + if (nodeName) { + parentStyleMock.ownerNode = { + 'nodeName': nodeName + }; } + rule.parentStyleSheet = parentStyleMock; } - - styles.matchedCSSRules.push({ - 'selectorText': selector, - 'style': style, - 'parentStyleSheet': parentStyleSheet - }); + this.matchedCSSRules_.push(rule); } - - this.styles_ = styles; }; @@ -325,17 +312,24 @@ devtools.DomNode.prototype.setStyles = function(computedStyle, inlineStyle, * @see devtools.CSSStyleDeclaration */ devtools.DomNode.prototype.makeStyle_ = function(payload) { - return payload && new devtools.CSSStyleDeclaration(payload); + var style = new devtools.CSSStyleDeclaration(payload); + style.nodeId_ = this.id_; + return style; }; /** * Remove references to the style information to release * resources when styles are not going to be used. - * @see setStyles_. + * @see setStyles. */ devtools.DomNode.prototype.clearStyles = function() { - this.styles_ = null; + this.computedStyle = null; + this.style = null; + for (var name in this.attributesMap_) { + this.attributesMap_[name].style = null; + } + this.matchedCSSRules_ = null; }; @@ -450,19 +444,17 @@ devtools.DomWindow.prototype.Object = function() { /** - * Simulates the DOM interface for styles. Must be called after - * node.setStyles_. + * Simulates the DOM interface for styles. * @param {devtools.DomNode} node * @return {CSSStyleDescription} */ devtools.DomWindow.prototype.getComputedStyle = function(node) { - return node.styles_.computedStyle; + return node.computedStyle_; }; /** - * Simulates the DOM interface for styles. Must be called after - * node.setStyles_. + * Simulates the DOM interface for styles. * @param {devtools.DomNode} nodeStyles * @param {string} pseudoElement assumed to be empty string. * @param {boolean} authorOnly assumed to be equal to authorOnly argument of @@ -471,7 +463,7 @@ devtools.DomWindow.prototype.getComputedStyle = function(node) { */ devtools.DomWindow.prototype.getMatchedCSSRules = function(node, pseudoElement, authorOnly) { - return node.styles_.matchedCSSRules; + return node.matchedCSSRules_; }; @@ -837,9 +829,11 @@ devtools.DomAgent.prototype.getSearchResultNode = function(index) { */ devtools.DomAgent.prototype.getNodePropertiesAsync = function(nodeId, path, protoDepth, callback) { - var callbackId = devtools.Callback.wrap(callback); + var mycallback = + goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); + var callbackId = devtools.Callback.wrap(mycallback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, - 'devtools$$getProperties', nodeId, + 'getProperties', nodeId, goog.json.serialize([path, protoDepth])); }; @@ -851,9 +845,11 @@ devtools.DomAgent.prototype.getNodePropertiesAsync = function(nodeId, */ devtools.DomAgent.prototype.getNodePrototypesAsync = function(nodeId, callback) { - var callbackId = devtools.Callback.wrap(callback); + var mycallback = + goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); + var callbackId = devtools.Callback.wrap(mycallback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, - 'devtools$$getPrototypes', nodeId, ''); + 'getPrototypes', nodeId, '[]'); }; @@ -865,37 +861,76 @@ devtools.DomAgent.prototype.getNodePrototypesAsync = function(nodeId, */ devtools.DomAgent.prototype.getNodeStylesAsync = function(node, authorOnly, callback) { - var callbackId = devtools.Callback.wrap(callback); + var mycallback = + goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); + var callbackId = devtools.Callback.wrap(mycallback); RemoteToolsAgent.ExecuteUtilityFunction(callbackId, - 'devtools$$getStyles', + 'getStyles', node.id_, - goog.json.serialize(authorOnly)); + goog.json.serialize([authorOnly])); +}; + + +/** + * Toggles style with given id on/off. + * @param {devtools.CSSStyleDeclaration} style Style to toggle. + * @param {boolean} enabled True if style should be enabled. + * @param {string} name Style name. + * @param {Function} callback. + */ +devtools.DomAgent.prototype.toggleNodeStyleAsync = function( + style, enabled, name, callback) { + var mycallback = + goog.bind(this.utilityFunctionCallbackWrapper_, this, callback); + var callbackId = devtools.Callback.wrap(mycallback); + RemoteToolsAgent.ExecuteUtilityFunction(callbackId, + 'toggleNodeStyle', + style.nodeId_, + goog.json.serialize([style.id_, enabled, name])); +}; + + +/** + * Dumps exception if something went wrong in ExecuteUtilityFunction. + */ +devtools.DomAgent.prototype.utilityFunctionCallbackWrapper_ = + function(callback, result, exception) { + if (exception && exception.length) { + debugPrint('Exception in ExecuteUtilityFunction styles:' + exception); + return; + } + callback(result); }; /** * Represents remote CSSStyleDeclaration for using in StyleSidebarPane. - * @param {Array<Object>} payload built by devtools$$getStyle from the injected - * js. - * @consctuctor + * @param {id, Array<Object>} payload built by inject's getStyle from the + * injected js. + * @constructor */ devtools.CSSStyleDeclaration = function(payload) { - this.length = payload.length; + this.id_ = payload[0]; + this.__disabledProperties = payload[1]; + this.__disabledPropertyValues = payload[2]; + this.__disabledPropertyPriorities = payload[3]; + + this.length = payload.length - 4; this.priority_ = {}; this.implicit_ = {}; this.shorthand_ = {}; this.value_ = {}; - for (var i = 0; i < payload.length; ++i) { + for (var i = 4; i < payload.length; ++i) { var p = payload[i]; var name = p[0]; - + this.priority_[name] = p[1]; this.implicit_[name] = p[2]; this.shorthand_[name] = p[3]; this.value_[name] = p[4]; - this[i] = name; + this[i - 4] = name; } }; diff --git a/webkit/glue/devtools/js/inject.js b/webkit/glue/devtools/js/inject.js index 5cbb1a8..f19e470 100644 --- a/webkit/glue/devtools/js/inject.js +++ b/webkit/glue/devtools/js/inject.js @@ -1,155 +1,285 @@ -// Copyright (c) 2009 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. - -/** - * @fileoverview Javascript that is being injected into the inspectable page - * while debugging. - */ -goog.require('goog.json'); - -/** - * Returns JSON-serialized array of properties for a given node - * on a given path. - * @param {Node} node Node to get property value for. - * @param {string} args JSON-serialized {Array.<string>} Path to the - * nested object, {number} Depth to the actual proto to inspect]. - * @return {string} JSON-serialized array where each property is represented - * by the tree entryies [{string} type, {string} name, {Object} value]. - */ -function devtools$$getProperties(node, args) { - // Parse parameters. - var parsedArgs = goog.json.parse(args); - var path = parsedArgs[0]; - var protoDepth = parsedArgs[1]; - - var result = []; - var obj = node; - - // Follow the path. - for (var i = 0; obj && i < path.length; ++i) { - obj = obj[path[i]]; - } - - if (!obj) { - return '[]'; - } - - // Get to the necessary proto layer. - for (var i = 0; obj && i < protoDepth; ++i) { - obj = obj.__proto__; - } - - if (!obj) { - return '[]'; - } - - // Go over properties, prepare results. - for (var name in obj) { - if (protoDepth != -1 && 'hasOwnProperty' in obj && - !obj.hasOwnProperty(name)) { - continue; - } - var type = typeof obj[name]; - result.push(type); - result.push(name); - if (type == 'string') { - var str = obj[name]; - result.push(str.length > 99 ? str.substr(0, 99) + '...' : str); - } else if (type != 'object' && type != 'array' && - type != 'function') { - result.push(obj[name]); - } else { - result.push(undefined); - } - } - return goog.json.serialize(result); -} - - -/** - * Returns JSON-serialized array of prototypes for a given node. - * @param {Node} node Node to get prorotypes for. - * @return {string} JSON-serialized array where each item is a proto name. - */ -function devtools$$getPrototypes(node, args) { - var result = []; - for (var prototype = node; prototype; prototype = prototype.__proto__) { - var description = Object.prototype.toString.call(prototype); - result.push(description.replace(/^\[object (.*)\]$/i, '$1')); - } - return goog.json.serialize(result); -} - - -/** - * Returns JSON-serialized style information that is used in devtools.js. - * @param {Node} node Node to get prorotypes for. - * @param {string} args JSON-serialized boolean authorOnly that determines - * whether only author styles need to be added. - * @return {string} JSON-serialized style collection descriptor. - */ -function devtools$$getStyles(node, args) { - var authorOnly = goog.json.parse(args); - if (!node.nodeType == Node.ELEMENT_NODE) { - return '{}'; - } - var matchedRules = window.getMatchedCSSRules(node, '', authorOnly); - var matchedCSSRulesObj = []; - for (var i = 0; matchedRules && i < matchedRules.length; ++i) { - var rule = matchedRules[i]; - var style = devtools$$serializeStyle_(rule.style); - var parentStyleSheetHref = (rule.parentStyleSheet ? - rule.parentStyleSheet.href : undefined); - var parentStyleSheetOwnerNodeName; - if (rule.parentStyleSheet && rule.parentStyleSheet.ownerNode) { - parentStyleSheetOwnerNodeName = rule.parentStyleSheet.ownerNode.name; - } - matchedCSSRulesObj.push({ - 'selector' : rule.selectorText, - 'style' : style, - 'parentStyleSheetHref' : parentStyleSheetHref, - 'parentStyleSheetOwnerNodeName' : parentStyleSheetOwnerNodeName - }); - } - - var attributeStyles = {}; - var attributes = node.attributes; - for (var i = 0; attributes && i < attributes.length; ++i) { - if (attributes[i].style) { - attributeStyles[attributes[i].name] = - devtools$$serializeStyle_(attributes[i].style); - } - } - - var result = { - 'inlineStyle' : devtools$$serializeStyle_(node.style), - 'computedStyle' : devtools$$serializeStyle_( - window.getComputedStyle(node, '')), - 'matchedCSSRules' : matchedCSSRulesObj, - 'styleAttributes' : attributeStyles - }; - return goog.json.serialize(result); -} - - -/** - * Converts given style into serializable object. - * @param {CSSStyleDeclaration} style Style to serialize. - * @return {Array<Object>} Serializable object. - * @private - */ -function devtools$$serializeStyle_(style) { - var result = []; - for (var i = 0; style && i < style.length; ++i) { - var name = style[i]; - result.push([ - name, - style.getPropertyPriority(name), - style.isPropertyImplicit(name), - style.getPropertyShorthand(name), - style.getPropertyValue(name) - ]); - } - return result; -} +// Copyright (c) 2009 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.
+
+/**
+ * @fileoverview Javascript that is being injected into the inspectable page
+ * while debugging.
+ */
+goog.require('goog.json');
+goog.provide('devtools.Injected');
+
+
+/**
+ * Main injected object.
+ * @constructor.
+ */
+devtools.Injected = function() {
+ /**
+ * Unique style id generator.
+ * @type {number}
+ * @private
+ */
+ this.lastStyleId_ = 1;
+};
+
+
+/**
+ * Returns array of properties for a given node on a given path.
+ * @param {Node} node Node to get property value for.
+ * @param {Array.<string>} path Path to the nested object.
+ * @param {number} protoDepth Depth of the actual proto to inspect.
+ * @return {Array.<Object>} Array where each property is represented
+ * by the tree entries [{string} type, {string} name, {Object} value].
+ */
+devtools.Injected.prototype.getProperties = function(node, path, protoDepth) {
+ var result = [];
+ var obj = node;
+
+ // Follow the path.
+ for (var i = 0; obj && i < path.length; ++i) {
+ obj = obj[path[i]];
+ }
+
+ if (!obj) {
+ return [];
+ }
+
+ // Get to the necessary proto layer.
+ for (var i = 0; obj && i < protoDepth; ++i) {
+ obj = obj.__proto__;
+ }
+
+ if (!obj) {
+ return [];
+ }
+
+ // Go over properties, prepare results.
+ for (var name in obj) {
+ if (protoDepth != -1 && 'hasOwnProperty' in obj &&
+ !obj.hasOwnProperty(name)) {
+ continue;
+ }
+ var type = typeof obj[name];
+ result.push(type);
+ result.push(name);
+ if (type == 'string') {
+ var str = obj[name];
+ result.push(str.length > 99 ? str.substr(0, 99) + '...' : str);
+ } else if (type != 'object' && type != 'array' &&
+ type != 'function') {
+ result.push(obj[name]);
+ } else {
+ result.push(undefined);
+ }
+ }
+ return result;
+};
+
+
+/**
+ * Returns array of prototypes for a given node.
+ * @param {Node} node Node to get prorotypes for.
+ * @return {Array<string>} Array of proto names.
+ */
+devtools.Injected.prototype.getPrototypes = function(node) {
+ var result = [];
+ for (var prototype = node; prototype; prototype = prototype.__proto__) {
+ var description = Object.prototype.toString.call(prototype);
+ result.push(description.replace(/^\[object (.*)\]$/i, '$1'));
+ }
+ return result;
+};
+
+
+/**
+ * Returns style information that is used in devtools.js.
+ * @param {Node} node Node to get prorotypes for.
+ * @param {boolean} authorOnly Determines whether only author styles need to
+ * be added.
+ * @return {string} Style collection descriptor.
+ */
+devtools.Injected.prototype.getStyles = function(node, authorOnly) {
+ if (!node.nodeType == Node.ELEMENT_NODE) {
+ return {};
+ }
+ var matchedRules = window.getMatchedCSSRules(node, '', authorOnly);
+ var matchedCSSRulesObj = [];
+ for (var i = 0; matchedRules && i < matchedRules.length; ++i) {
+ var rule = matchedRules[i];
+ var style = this.serializeStyle_(rule.style);
+ var ruleValue = {
+ 'selector' : rule.selectorText,
+ 'style' : style
+ };
+ if (rule.parentStyleSheet) {
+ ruleValue['parentStyleSheet'] = {
+ 'href' : rule.parentStyleSheet.href,
+ 'ownerNodeName' : rule.parentStyleSheet.ownerNode ?
+ rule.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);
+ }
+
+ var attributeStyles = {};
+ var attributes = node.attributes;
+ for (var i = 0; attributes && i < attributes.length; ++i) {
+ if (attributes[i].style) {
+ attributeStyles[attributes[i].name] =
+ this.serializeStyle_(attributes[i].style);
+ }
+ }
+
+ var result = {
+ 'inlineStyle' : this.serializeStyle_(node.style),
+ 'computedStyle' : this.serializeStyle_(
+ window.getComputedStyle(node, '')),
+ 'matchedCSSRules' : matchedCSSRulesObj,
+ 'styleAttributes' : attributeStyles
+ };
+ return result;
+};
+
+
+/**
+ * Returns style decoration object for given id.
+ * @param {Node} node Node to get prorotypes for.
+ * @param {number} id Style id.
+ * @return {Object} Style object.
+ * @private
+ */
+devtools.Injected.prototype.getStyleForId_ = function(node, id) {
+ var matchedRules = window.getMatchedCSSRules(node, '', false);
+ for (var i = 0; matchedRules && i < matchedRules.length; ++i) {
+ var rule = matchedRules[i];
+ if (rule.style.__id == id) {
+ return rule.style;
+ }
+ }
+ var attributes = node.attributes;
+ for (var i = 0; attributes && i < attributes.length; ++i) {
+ if (attributes[i].style && attributes[i].style.__id == id) {
+ return attributes[i].style;
+ }
+ }
+ if (node.style.__id == id) {
+ return node.style;
+ }
+ return null;
+};
+
+
+
+
+/**
+ * Converts given style into serializable object.
+ * @param {CSSStyleDeclaration} style Style to serialize.
+ * @return {Array<Object>} Serializable object.
+ * @private
+ */
+devtools.Injected.prototype.serializeStyle_ = function(style) {
+ if (!style) {
+ return [];
+ }
+ if (!style.__id) {
+ style.__id = this.lastStyleId_++;
+ }
+ var result = [
+ style.__id,
+ style.__disabledProperties,
+ style.__disabledPropertyValues,
+ style.__disabledPropertyPriorities
+ ];
+ for (var i = 0; i < style.length; ++i) {
+ var name = style[i];
+ result.push([
+ name,
+ style.getPropertyPriority(name),
+ style.isPropertyImplicit(name),
+ style.getPropertyShorthand(name),
+ style.getPropertyValue(name)
+ ]);
+ }
+ return result;
+};
+
+
+/**
+ * Toggles style with given id on/off.
+ * @param {Node} node Node to get prorotypes for.
+ * @param {number} styleId Id of style to toggle.
+ * @param {boolean} enabled Determines value to toggle to,
+ * @param {string} name Name of the property.
+ */
+devtools.Injected.prototype.toggleNodeStyle = function(node, styleId, enabled,
+ name) {
+ var style = this.getStyleForId_(node, styleId);
+ if (!style) {
+ return false;
+ }
+
+ if (!enabled) {
+ if (!style.__disabledPropertyValues ||
+ !style.__disabledPropertyPriorities) {
+ style.__disabledProperties = {};
+ style.__disabledPropertyValues = {};
+ style.__disabledPropertyPriorities = {};
+ }
+
+ style.__disabledPropertyValues[name] = style.getPropertyValue(name);
+ style.__disabledPropertyPriorities[name] = style.getPropertyPriority(name);
+
+ if (style.getPropertyShorthand(name)) {
+ var longhandProperties = this.getLonghandProperties_(style, name);
+ for (var i = 0; i < longhandProperties.length; ++i) {
+ style.__disabledProperties[longhandProperties[i]] = true;
+ style.removeProperty(longhandProperties[i]);
+ }
+ } else {
+ style.__disabledProperties[name] = true;
+ style.removeProperty(name);
+ }
+ } else if (style.__disabledProperties &&
+ style.__disabledProperties[name]) {
+ var value = style.__disabledPropertyValues[name];
+ var priority = style.__disabledPropertyPriorities[name];
+ style.setProperty(name, value, priority);
+
+ delete style.__disabledProperties[name];
+ delete style.__disabledPropertyValues[name];
+ delete style.__disabledPropertyPriorities[name];
+ }
+ return true;
+};
+
+
+/**
+ * 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
+ */
+devtools.Injected.prototype.getLonghandProperties_ = function(style,
+ shorthandProperty) {
+ var properties = [];
+ var foundProperties = {};
+
+ for (var i = 0; i < style.length; ++i) {
+ var individualProperty = style[i];
+ if (individualProperty in foundProperties ||
+ style.getPropertyShorthand(individualProperty) != shorthandProperty) {
+ continue;
+ }
+ foundProperties[individualProperty] = true;
+ properties.push(individualProperty);
+ }
+ return properties;
+};
diff --git a/webkit/glue/devtools/js/inject_dispatch.js b/webkit/glue/devtools/js/inject_dispatch.js new file mode 100644 index 0000000..0b5df80 --- /dev/null +++ b/webkit/glue/devtools/js/inject_dispatch.js @@ -0,0 +1,33 @@ +// Copyright (c) 2009 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.
+
+/**
+ * @fileoverview Injects 'injected' object into the inspectable page.
+ */
+
+/**
+ * Dispatches host calls into the injected function calls.
+ */
+goog.require('devtools.Injected');
+
+
+/**
+ * Injected singleton.
+ */
+var devtools$$obj = new devtools.Injected();
+
+
+/**
+ * Main dispatch method, all calls from the host go through this one.
+ * @param {string} functionName Function to call
+ * @param {Node} node Node context of the call.
+ * @param {string} json_args JSON-serialized call parameters.
+ * @return {string} JSON-serialized result of the dispatched call.
+ */
+function devtools$$dispatch(functionName, node, json_args) {
+ var params = goog.json.parse(json_args);
+ params.splice(0, 0, node);
+ var result = devtools$$obj[functionName].apply(devtools$$obj, params);
+ return goog.json.serialize(result);
+};
|