Changeset 46972 in webkit
- Timestamp:
- Aug 10, 2009 3:02:48 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r46969 r46972 1 2009-08-10 Pavel Feldman <pfeldman@chromium.org> 2 3 Reviewed by Timothy Hatcher. 4 5 WebInspector: Make properties inspection serialized. 6 7 https://bugs.webkit.org/show_bug.cgi?id=28078 8 9 * inspector/front-end/DOMAgent.js: 10 (InspectorController.getPrototypes): 11 (InspectorController.getProperties): 12 * inspector/front-end/InjectedScript.js: 13 (InjectedScript.getPrototypes): 14 (InjectedScript.getProperties): 15 (InjectedScript.setPropertyValue): 16 * inspector/front-end/ObjectPropertiesSection.js: 17 (WebInspector.ObjectRef): 18 (WebInspector.ObjectPropertyRef): 19 (WebInspector.ObjectPropertiesSection.prototype.onpopulate): 20 (WebInspector.ObjectPropertiesSection.prototype.update.callback): 21 (WebInspector.ObjectPropertiesSection.prototype.update): 22 (WebInspector.ObjectPropertiesSection.prototype._update): 23 (WebInspector.ObjectPropertyTreeElement.prototype.onpopulate.callback): 24 (WebInspector.ObjectPropertyTreeElement.prototype.onpopulate): 25 (WebInspector.ObjectPropertyTreeElement.prototype.onattach): 26 (WebInspector.ObjectPropertyTreeElement.prototype.update): 27 * inspector/front-end/PropertiesSidebarPane.js: 28 (WebInspector.PropertiesSidebarPane.prototype.update.callback): 29 (WebInspector.PropertiesSidebarPane.prototype.update): 30 1 31 2009-08-09 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com> 2 32 -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r46943 r46972 30880 30880 </File> 30881 30881 <File 30882 RelativePath="..\inspector\front-end\Console.js" 30882 RelativePath="..\inspector\front-end\ChangesView.js" 30883 > 30884 </File> 30885 <File 30886 RelativePath="..\inspector\front-end\Color.js" 30887 > 30888 </File> 30889 <File 30890 RelativePath="..\inspector\front-end\ConsoleView.js" 30883 30891 > 30884 30892 </File> … … 30920 30928 </File> 30921 30929 <File 30930 RelativePath="..\inspector\front-end\Drawer.js" 30931 > 30932 </File> 30933 <File 30922 30934 RelativePath="..\inspector\front-end\ElementsPanel.js" 30923 30935 > … … 30932 30944 </File> 30933 30945 <File 30946 RelativePath="..\inspector\front-end\InjectedScript.js" 30947 > 30948 </File> 30949 <File 30934 30950 RelativePath="..\inspector\front-end\inspector.css" 30935 30951 > … … 30953 30969 <File 30954 30970 RelativePath="..\inspector\front-end\ObjectPropertiesSection.js" 30971 > 30972 </File> 30973 <File 30974 RelativePath="..\inspector\front-end\ObjectProxy.js" 30955 30975 > 30956 30976 </File> -
trunk/WebCore/inspector/front-end/ConsoleView.js
r46886 r46972 514 514 _formatobject: function(obj, elem) 515 515 { 516 elem.appendChild(new WebInspector.ObjectPropertiesSection( obj, null, null, null, true).element);516 elem.appendChild(new WebInspector.ObjectPropertiesSection(new WebInspector.ObjectProxy(obj), Object.describe(obj, true), null, null, true).element); 517 517 }, 518 518 -
trunk/WebCore/inspector/front-end/DOMAgent.js
r46848 r46972 704 704 }, 0) 705 705 } 706 707 InspectorController.getPrototypes = function(objectProxy, callback) { 708 setTimeout(function() { 709 callback(InjectedScript.getPrototypes(objectProxy)); 710 }, 0) 711 } 712 713 InspectorController.getProperties = function(objectProxy, ignoreHasOwnProperty, callback) { 714 setTimeout(function() { 715 callback(InjectedScript.getProperties(objectProxy, ignoreHasOwnProperty)); 716 }, 0) 717 } 718 719 InspectorController.setPropertyValue = function(objectProxy, propertyName, expression, callback) { 720 setTimeout(function() { 721 callback(InjectedScript.setPropertyValue(objectProxy, propertyName, expression)); 722 }, 0) 723 } 724 -
trunk/WebCore/inspector/front-end/InjectedScript.js
r46848 r46972 39 39 var node = InjectedScript._nodeForId(nodeId); 40 40 if (!node) 41 return null;41 return false; 42 42 var matchedRules = InjectedScript._window().getMatchedCSSRules(node, "", authorOnly); 43 43 var matchedCSSRules = []; … … 382 382 } 383 383 384 InjectedScript.getPrototypes = function(nodeId) 385 { 386 var node = InjectedScript._nodeForId(nodeId); 387 if (!node) 388 return false; 389 390 var result = []; 391 for (var prototype = node; prototype; prototype = prototype.__proto__) { 392 var title = Object.describe(prototype); 393 if (title.match(/Prototype$/)) { 394 title = title.replace(/Prototype$/, ""); 395 } 396 result.push(title); 397 } 398 return result; 399 } 400 401 InjectedScript.getProperties = function(objectProxy, ignoreHasOwnProperty) 402 { 403 var object = InjectedScript._resolveObject(objectProxy); 404 if (!object) 405 return false; 406 407 var properties = []; 408 // Go over properties, prepare results. 409 for (var propertyName in object) { 410 if (!ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName)) 411 continue; 412 413 //TODO: remove this once object becomes really remote. 414 if (propertyName === "__treeElementIdentifier") 415 continue; 416 var property = {}; 417 property.name = propertyName; 418 var isGetter = object["__lookupGetter__"] && object.__lookupGetter__(propertyName); 419 if (!property.isGetter) { 420 var childObject = object[propertyName]; 421 property.type = typeof childObject; 422 property.textContent = Object.describe(childObject, true); 423 property.parentObjectProxy = objectProxy; 424 var parentPath = objectProxy.path.slice(); 425 property.childObjectProxy = { 426 objectId : objectProxy.objectId, 427 path : parentPath.splice(parentPath.length, 0, propertyName), 428 protoDepth : objectProxy.protoDepth 429 }; 430 if (childObject && (property.type === "object" || property.type === "function")) { 431 for (var subPropertyName in childObject) { 432 if (propertyName === "__treeElementIdentifier") 433 continue; 434 property.hasChildren = true; 435 break; 436 } 437 } 438 } else { 439 // FIXME: this should show something like "getter" (bug 16734). 440 property.textContent = "\u2014"; // em dash 441 property.isGetter = true; 442 } 443 properties.push(property); 444 } 445 return properties; 446 } 447 448 InjectedScript.setPropertyValue = function(objectProxy, propertyName, expression) 449 { 450 var object = InjectedScript._resolveObject(objectProxy); 451 if (!object) 452 return false; 453 454 var expressionLength = expression.length; 455 if (!expressionLength) { 456 delete object[propertyName]; 457 return !(propertyName in object); 458 } 459 460 try { 461 // Surround the expression in parenthesis so the result of the eval is the result 462 // of the whole expression not the last potential sub-expression. 463 464 // There is a regression introduced here: eval is now happening against global object, 465 // not call frame while on a breakpoint. 466 // TODO: bring evaluation against call frame back. 467 var result = InjectedScript._window().eval("(" + expression + ")"); 468 // Store the result in the property. 469 object[propertyName] = result; 470 return true; 471 } catch(e) { 472 try { 473 var result = InjectedScript._window().eval("\"" + expression.escapeCharacters("\"") + "\""); 474 object[propertyName] = result; 475 return true; 476 } catch(e) { 477 return false; 478 } 479 } 480 } 481 482 InjectedScript._resolveObject = function(objectProxy) 483 { 484 var object = InjectedScript._objectForId(objectProxy.objectId); 485 var path = objectProxy.path; 486 var protoDepth = objectProxy.protoDepth; 487 488 // Follow the property path. 489 for (var i = 0; object && i < path.length; ++i) 490 object = object[path[i]]; 491 492 // Get to the necessary proto layer. 493 for (var i = 0; object && i < protoDepth; ++i) 494 object = object.__proto__; 495 496 return object; 497 } 498 384 499 InjectedScript._window = function() 385 500 { 501 // TODO: replace with 'return window;' once this script is injected into 502 // the page's context. 386 503 return InspectorController.inspectedWindow(); 387 504 } … … 389 506 InjectedScript._nodeForId = function(nodeId) 390 507 { 508 // TODO: replace with node lookup in the InspectorDOMAgent once DOMAgent nodes are used. 391 509 return nodeId; 392 510 } 511 512 InjectedScript._objectForId = function(objectId) 513 { 514 // TODO: replace with node lookups for node ids and evaluation result lookups for the rest of ids. 515 return objectId; 516 } -
trunk/WebCore/inspector/front-end/ObjectPropertiesSection.js
r46391 r46972 27 27 WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor) 28 28 { 29 if (!title) {30 title = Object.describe(object);31 if (title.match(/Prototype$/)) {32 title = title.replace(/Prototype$/, "");33 if (!subtitle)34 subtitle = WebInspector.UIString("Prototype");35 }36 }37 38 29 this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties")); 39 30 this.object = object; … … 54 45 update: function() 55 46 { 56 var properties = []; 57 for (var prop in this.object) 58 properties.push(prop); 47 var self = this; 48 var callback = function(properties) { 49 if (!properties) 50 return; 51 self._update(properties); 52 }; 53 InspectorController.getProperties(this.object, this.ignoreHasOwnProperty, callback); 54 }, 55 56 _update: function(properties) 57 { 59 58 if (this.extraProperties) 60 59 for (var prop in this.extraProperties) 61 properties.push( prop);60 properties.push(new WebInspector.ObjectPropertyProxy(prop, this.extraProperties[prop])); 62 61 properties.sort(this._displaySort); 63 62 64 63 this.propertiesTreeOutline.removeChildren(); 65 64 66 for (var i = 0; i < properties.length; ++i) { 67 var object = this.object; 68 var propertyName = properties[i]; 69 if (this.extraProperties && propertyName in this.extraProperties) 70 object = this.extraProperties; 71 if (propertyName === "__treeElementIdentifier") 72 continue; 73 if (!this.ignoreHasOwnProperty && "hasOwnProperty" in object && !object.hasOwnProperty(propertyName)) 74 continue; 75 this.propertiesTreeOutline.appendChild(new this.treeElementConstructor(object, propertyName)); 76 } 65 for (var i = 0; i < properties.length; ++i) 66 this.propertiesTreeOutline.appendChild(new this.treeElementConstructor(properties[i])); 77 67 78 68 if (!this.propertiesTreeOutline.children.length) { … … 83 73 }, 84 74 85 _displaySort: function(a,b) { 75 _displaySort: function(propertyA, propertyB) { 76 var a = propertyA.name; 77 var b = propertyB.name; 86 78 87 79 // if used elsewhere make sure to … … 124 116 WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype; 125 117 126 WebInspector.ObjectPropertyTreeElement = function(p arentObject, propertyName)118 WebInspector.ObjectPropertyTreeElement = function(property) 127 119 { 128 this.parentObject = parentObject; 129 this.propertyName = propertyName; 120 this.property = property; 130 121 131 122 // Pass an empty title, the title gets made later in onattach. … … 146 137 return; 147 138 148 this.removeChildren(); 149 150 var childObject = this.safePropertyValue(this.parentObject, this.propertyName); 151 var properties = Object.sortedProperties(childObject, WebInspector.ObjectPropertiesSection.prototype._displaySort); 152 for (var i = 0; i < properties.length; ++i) { 153 var propertyName = properties[i]; 154 if (propertyName === "__treeElementIdentifier") 155 continue; 156 this.appendChild(new this.treeOutline.section.treeElementConstructor(childObject, propertyName)); 157 } 139 var self = this; 140 var callback = function(properties) { 141 self.removeChildren(); 142 if (!properties) 143 return; 144 145 properties.sort(self._displaySort); 146 for (var i = 0; i < properties.length; ++i) { 147 self.appendChild(new self.treeOutline.section.treeElementConstructor(properties[i])); 148 } 149 }; 150 InspectorController.getProperties(this.property.childObjectProxy, false, callback); 158 151 }, 159 152 … … 170 163 update: function() 171 164 { 172 var childObject = this.safePropertyValue(this.parentObject, this.propertyName);173 var isGetter = ("__lookupGetter__" in this.parentObject && this.parentObject.__lookupGetter__(this.propertyName));174 175 165 var nameElement = document.createElement("span"); 176 166 nameElement.className = "name"; 177 nameElement.textContent = this.property Name;167 nameElement.textContent = this.property.name; 178 168 179 169 this.valueElement = document.createElement("span"); 180 170 this.valueElement.className = "value"; 181 if (!isGetter) { 182 this.valueElement.textContent = Object.describe(childObject, true); 183 } else { 184 // FIXME: this should show something like "getter" (bug 16734). 185 this.valueElement.textContent = "\u2014"; // em dash 186 this.valueElement.addStyleClass("dimmed"); 187 } 171 this.valueElement.textContent = this.property.textContent; 172 if (this.property.isGetter) 173 this.valueElement.addStyleClass("dimmed"); 188 174 189 175 this.listItemElement.removeChildren(); … … 192 178 this.listItemElement.appendChild(document.createTextNode(": ")); 193 179 this.listItemElement.appendChild(this.valueElement); 194 195 var hasSubProperties = false; 196 var type = typeof childObject; 197 if (childObject && (type === "object" || type === "function")) { 198 for (var subPropertyName in childObject) { 199 if (subPropertyName === "__treeElementIdentifier") 200 continue; 201 hasSubProperties = true; 202 break; 203 } 204 } 205 206 this.hasChildren = hasSubProperties; 180 this.hasChildren = this.property.hasChildren; 207 181 }, 208 182 … … 254 228 }, 255 229 256 evaluateExpression: function(expression, callback)257 {258 // Evaluate in the currently selected call frame if the debugger is paused.259 // Otherwise evaluate in against the inspected window.260 if (WebInspector.panels.scripts && WebInspector.panels.scripts.paused && this.treeOutline.section.editInSelectedCallFrameWhenPaused)261 return WebInspector.panels.scripts.evaluateInSelectedCallFrame(expression, false, callback);262 try {263 var result = InspectorController.inspectedWindow().eval(expression);264 callback(result);265 } catch (e) {266 callback(e, true);267 }268 },269 270 230 applyExpression: function(expression, updateInterface) 271 231 { 272 var expressionLength = expression.trimWhitespace().length; 273 274 if (!expressionLength) { 275 // The user deleted everything, so try to delete the property. 276 delete this.parentObject[this.propertyName]; 277 278 if (updateInterface) { 279 if (this.propertyName in this.parentObject) { 280 // The property was not deleted, so update. 281 this.update(); 282 } else { 283 // The property was deleted, so remove this tree element. 284 this.parent.removeChild(this); 285 } 232 expression = expression.trimWhitespace(); 233 var expressionLength = expression.length; 234 var self = this; 235 var callback = function(success) { 236 if (!updateInterface) 237 return; 238 239 if (!success) 240 self.update(); 241 242 if (!expressionLength) { 243 // The property was deleted, so remove this tree element. 244 self.parent.removeChild(this); 245 } else { 246 // Call updateSiblings since their value might be based on the value that just changed. 247 self.updateSiblings(); 286 248 } 287 288 return; 289 } 290 291 try { 292 // Surround the expression in parenthesis so the result of the eval is the result 293 // of the whole expression not the last potential sub-expression. 294 var result = this.evaluateExpression("(" + expression + ")"); 295 296 // Store the result in the property. 297 this.parentObject[this.propertyName] = result; 298 } catch(e) { 299 try { 300 // Try to update as a string 301 var result = this.evaluateExpression("\"" + expression.escapeCharacters("\"") + "\""); 302 303 // Store the result in the property. 304 this.parentObject[this.propertyName] = result; 305 } catch(e) { 306 // The expression failed so don't change the value. So just update and return. 307 if (updateInterface) 308 this.update(); 309 return; 310 } 311 } 312 313 if (updateInterface) { 314 // Call updateSiblings since their value might be based on the value that just changed. 315 this.updateSiblings(); 316 } 249 }; 250 InspectorController.setPropertyValue(this.property.parentObjectProxy, this.property.name, expression.trimWhitespace(), callback); 317 251 } 318 252 } -
trunk/WebCore/inspector/front-end/PropertiesSidebarPane.js
r37289 r46972 44 44 return; 45 45 46 for (var prototype = object; prototype; prototype = prototype.__proto__) { 47 var section = new WebInspector.ObjectPropertiesSection(prototype); 48 this.sections.push(section); 49 body.appendChild(section.element); 50 } 46 var self = this; 47 var callback = function(prototypes) { 48 var body = self.bodyElement; 49 body.removeChildren(); 50 self.sections = []; 51 52 // Get array of prototype user-friendly names. 53 for (var i = 0; i < prototypes.length; ++i) { 54 var prototype = new WebInspector.ObjectProxy(object, [], i); 55 var section = new WebInspector.ObjectPropertiesSection(prototype, prototypes[i], WebInspector.UIString("Prototype")); 56 self.sections.push(section); 57 body.appendChild(section.element); 58 } 59 }; 60 InspectorController.getPrototypes(object, callback); 51 61 } 52 62 } -
trunk/WebCore/inspector/front-end/ScopeChainSidebarPane.js
r37289 r46972 86 86 subtitle = null; 87 87 88 var section = new WebInspector.ObjectPropertiesSection( scopeObject, title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);88 var section = new WebInspector.ObjectPropertiesSection(new WebInspector.ObjectProxy(scopeObject), title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement); 89 89 section.editInSelectedCallFrameWhenPaused = true; 90 90 section.pane = this; … … 101 101 WebInspector.ScopeChainSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype; 102 102 103 WebInspector.ScopeVariableTreeElement = function(p arentObject, propertyName)103 WebInspector.ScopeVariableTreeElement = function(property) 104 104 { 105 WebInspector.ObjectPropertyTreeElement.call(this, p arentObject, propertyName);105 WebInspector.ObjectPropertyTreeElement.call(this, property); 106 106 } 107 107 … … 143 143 do { 144 144 if (result) 145 result = current.property Name + "." + result;145 result = current.property.name + "." + result; 146 146 else 147 result = current.property Name;147 result = current.property.name; 148 148 current = current.parent; 149 149 } while (current && !current.root); -
trunk/WebCore/inspector/front-end/WebKit.qrc
r46841 r46972 30 30 <file>Object.js</file> 31 31 <file>ObjectPropertiesSection.js</file> 32 <file>ObjectProxy.js</file> 32 33 <file>Panel.js</file> 33 34 <file>PanelEnablerView.js</file> -
trunk/WebCore/inspector/front-end/inspector.html
r46841 r46972 56 56 <script type="text/javascript" src="SidebarTreeElement.js"></script> 57 57 <script type="text/javascript" src="PropertiesSection.js"></script> 58 <script type="text/javascript" src="ObjectProxy.js"></script> 58 59 <script type="text/javascript" src="ObjectPropertiesSection.js"></script> 59 60 <script type="text/javascript" src="BreakpointsSidebarPane.js"></script>
Note: See TracChangeset
for help on using the changeset viewer.