Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: Source/devtools/front_end/components/ObjectPropertiesSection.js

Issue 826713005: DevTools: Highlight changed scope variables as they change (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: addressing feedback. settings label. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2009 Joseph Pecoraro 3 * Copyright (C) 2009 Joseph Pecoraro
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 16 matching lines...) Expand all
27 /** 27 /**
28 * @constructor 28 * @constructor
29 * @extends {WebInspector.PropertiesSection} 29 * @extends {WebInspector.PropertiesSection}
30 * @param {!WebInspector.RemoteObject} object 30 * @param {!WebInspector.RemoteObject} object
31 * @param {?string|!Element=} title 31 * @param {?string|!Element=} title
32 * @param {string=} subtitle 32 * @param {string=} subtitle
33 * @param {?string=} emptyPlaceholder 33 * @param {?string=} emptyPlaceholder
34 * @param {boolean=} ignoreHasOwnProperty 34 * @param {boolean=} ignoreHasOwnProperty
35 * @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties 35 * @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties
36 * @param {function(new:TreeElement, !WebInspector.RemoteObjectProperty)=} treeE lementConstructor 36 * @param {function(new:TreeElement, !WebInspector.RemoteObjectProperty)=} treeE lementConstructor
37 * @param {?WebInspector.ObjectPropertiesMemento=} memento
37 */ 38 */
38 WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPl aceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor) 39 WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPl aceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor, mement o)
39 { 40 {
40 this._emptyPlaceholder = emptyPlaceholder; 41 this._emptyPlaceholder = emptyPlaceholder;
41 this.object = object; 42 this.object = object;
42 this.ignoreHasOwnProperty = ignoreHasOwnProperty; 43 this.ignoreHasOwnProperty = ignoreHasOwnProperty;
43 this.extraProperties = extraProperties; 44 this.extraProperties = extraProperties;
44 this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectP ropertyTreeElement; 45 this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectP ropertyTreeElement;
45 this.editable = true; 46 this.editable = true;
46 this.skipProto = false; 47 this.skipProto = false;
48 this.memento = memento;
pfeldman 2015/01/21 10:41:25 Should be private.
sandipchitale 2015/01/22 07:46:33 Acknowledged.
47 49
48 WebInspector.PropertiesSection.call(this, title || "", subtitle); 50 WebInspector.PropertiesSection.call(this, title || "", subtitle);
49 } 51 }
50 52
51 /** @const */ 53 /** @const */
52 WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100; 54 WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;
53 55
54 WebInspector.ObjectPropertiesSection.prototype = { 56 WebInspector.ObjectPropertiesSection.prototype = {
55 enableContextMenu: function() 57 enableContextMenu: function()
56 { 58 {
(...skipping 30 matching lines...) Expand all
87 if (!properties) 89 if (!properties)
88 return; 90 return;
89 this.updateProperties(properties, internalProperties); 91 this.updateProperties(properties, internalProperties);
90 } 92 }
91 93
92 WebInspector.RemoteObject.loadFromObject(this.object, !!this.ignoreHasOw nProperty, callback.bind(this)); 94 WebInspector.RemoteObject.loadFromObject(this.object, !!this.ignoreHasOw nProperty, callback.bind(this));
93 }, 95 },
94 96
95 updateProperties: function(properties, internalProperties, rootTreeElementCo nstructor, rootPropertyComparer) 97 updateProperties: function(properties, internalProperties, rootTreeElementCo nstructor, rootPropertyComparer)
96 { 98 {
99 if (this.memento) {
100 // Delete the cached last descriptions of all propertyIdentifiers
pfeldman 2015/01/21 10:41:25 No need for comments.
sandipchitale 2015/01/22 07:46:33 Acknowledged.
101 // did were not preset when the debugee was suspended last time
102 this.memento.forgetProperties();
103
104 // start with empty propertyIdentifiers cache
105 // this will get populated as the tree elemnts are
106 // shown
107 this.memento.initPropertyIdentifiers();
108 }
109
97 if (!rootTreeElementConstructor) 110 if (!rootTreeElementConstructor)
98 rootTreeElementConstructor = this.treeElementConstructor; 111 rootTreeElementConstructor = this.treeElementConstructor;
99 112
100 if (!rootPropertyComparer) 113 if (!rootPropertyComparer)
101 rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareP roperties; 114 rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareP roperties;
102 115
103 if (this.extraProperties) { 116 if (this.extraProperties) {
104 for (var i = 0; i < this.extraProperties.length; ++i) 117 for (var i = 0; i < this.extraProperties.length; ++i)
105 properties.push(this.extraProperties[i]); 118 properties.push(this.extraProperties[i]);
106 } 119 }
(...skipping 26 matching lines...) Expand all
133 return -1; 146 return -1;
134 if (propertyA.symbol && !propertyB.symbol) 147 if (propertyA.symbol && !propertyB.symbol)
135 return 1; 148 return 1;
136 if (propertyB.symbol && !propertyA.symbol) 149 if (propertyB.symbol && !propertyA.symbol)
137 return -1; 150 return -1;
138 return String.naturalOrderComparator(a, b); 151 return String.naturalOrderComparator(a, b);
139 } 152 }
140 153
141 /** 154 /**
142 * @constructor 155 * @constructor
156 */
157 WebInspector.ObjectPropertiesMemento = function() {
pfeldman 2015/01/21 10:41:25 Here and below, { on the next line.
sandipchitale 2015/01/22 07:46:34 Acknowledged.
158 this._expandedProperties = new Set();
159 this._lastDescriptions = {};
160 this._propertyIdentifiers = {};
161 }
162
163 WebInspector.ObjectPropertiesMemento.prototype = {
164 forgetProperties: function() {
165 for (var pi in this._lastDescriptions) {
166 if (!(pi in this._propertyIdentifiers))
167 // Delete the properties that no longer exist
168 delete this._lastDescriptions[pi];
169 }
170 },
171
172 /**
173 * @return {boolean}
174 */
175 isPropertyPathExpanded: function(propertyPath) {
176 return this._expandedProperties.has(propertyPath);
177 },
178 addExpandedPropertyPath: function(propertyPath) {
179 this._expandedProperties.add(propertyPath);
180 },
181 deleteExpandedPropertyPath: function(propertyPath) {
182 this._expandedProperties['delete'](propertyPath);
183 },
184 initPropertyIdentifiers: function() {
185 this._propertyIdentifiers = {};
186 },
187 recordPropertyPath: function(propertyPath) {
188 this._propertyIdentifiers[propertyPath] = 1;
189 },
190 /**
191 * @return {string}
192 */
193 getLastDescriptionForPropertyPath: function(propertyPath) {
pfeldman 2015/01/21 10:41:25 no get prefixes in Blink
sandipchitale 2015/01/22 07:46:33 Acknowledged.
194 return this._lastDescriptions[propertyPath];
195 },
196 setLastDescriptionForPropertyPath: function(propertyPath, description) {
197 this._lastDescriptions[propertyPath] = description;
198 }
199 }
200
201 /**
202 * @constructor
143 * @extends {TreeElement} 203 * @extends {TreeElement}
144 * @param {!WebInspector.RemoteObjectProperty} property 204 * @param {!WebInspector.RemoteObjectProperty} property
145 */ 205 */
146 WebInspector.ObjectPropertyTreeElement = function(property) 206 WebInspector.ObjectPropertyTreeElement = function(property)
147 { 207 {
148 this.property = property; 208 this.property = property;
149 209
150 // Pass an empty title, the title gets made later in onattach. 210 // Pass an empty title, the title gets made later in onattach.
151 TreeElement.call(this, "", null, false); 211 TreeElement.call(this, "", null, false);
152 this.toggleOnClick = true; 212 this.toggleOnClick = true;
(...skipping 18 matching lines...) Expand all
171 if ((this.property.writable || this.property.setter) && event.target.isS elfOrDescendant(editableElement)) 231 if ((this.property.writable || this.property.setter) && event.target.isS elfOrDescendant(editableElement))
172 this.startEditing(event); 232 this.startEditing(event);
173 return false; 233 return false;
174 }, 234 },
175 235
176 /** 236 /**
177 * @override 237 * @override
178 */ 238 */
179 onattach: function() 239 onattach: function()
180 { 240 {
241 // record the propertyIdentifier
242 if (WebInspector.settings.highlightChangedProperties.get() && this.prope rtyPath() && this.treeOutline.section.memento && this.treeOutline.section.mement o._propertyIdentifiers)
243 this.treeOutline.section.memento.recordPropertyPath(this.propertyPat h());
244
181 this.update(); 245 this.update();
182 }, 246 },
183 247
184 update: function() 248 update: function()
185 { 249 {
186 this.nameElement = createElementWithClass("span", "name"); 250 this.nameElement = createElementWithClass("span", "name");
187 var name = this.property.name; 251 var name = this.property.name;
188 if (/^\s|\s$|^$|\n/.test(name)) 252 if (/^\s|\s$|^$|\n/.test(name))
189 this.nameElement.createTextChildren("\"", name.replace(/\n/g, "\u21B 5"), "\""); 253 this.nameElement.createTextChildren("\"", name.replace(/\n/g, "\u21B 5"), "\"");
190 else 254 else
191 this.nameElement.textContent = name; 255 this.nameElement.textContent = name;
192 if (!this.property.enumerable) 256 if (!this.property.enumerable)
193 this.nameElement.classList.add("dimmed"); 257 this.nameElement.classList.add("dimmed");
194 if (this.property.isAccessorProperty()) 258 if (this.property.isAccessorProperty())
195 this.nameElement.classList.add("properties-accessor-property-name"); 259 this.nameElement.classList.add("properties-accessor-property-name");
196 if (this.property.symbol) 260 if (this.property.symbol)
197 this.nameElement.addEventListener("contextmenu", this._contextMenuFi red.bind(this, this.property.symbol), false); 261 this.nameElement.addEventListener("contextmenu", this._contextMenuFi red.bind(this, this.property.symbol), false);
198 262
199 var separatorElement = createElementWithClass("span", "separator"); 263 var separatorElement = createElementWithClass("span", "separator");
200 separatorElement.textContent = ": "; 264 separatorElement.textContent = ": ";
201 265
202 if (this.property.value) { 266 if (this.property.value) {
203 this.valueElement = createElementWithClass("span", "value"); 267 this.valueElement = createElementWithClass("span", "value");
204 var type = this.property.value.type; 268 var type = this.property.value.type;
205 var subtype = this.property.value.subtype; 269 var subtype = this.property.value.subtype;
270
271 var oldDescription;
272
273 if (WebInspector.settings.highlightChangedProperties.get() && this.t reeOutline.section && this.treeOutline.section.memento) {
274 // detect if the propertyIdentifier was shown when the debugee w as suspended last time
275 var hadProperty = false;
276 var lastDesription = this.treeOutline.section.memento.getLastDes criptionForPropertyPath(this.propertyPath())
pfeldman 2015/01/21 10:41:25 This code can't be a part of the ObjectPropertyTre
sandipchitale 2015/01/22 07:46:33 Will work on this.
277 if (this.propertyPath()) {
278 hadProperty = (lastDesription != undefined);
279 // retrieve the description from last suspension
280 oldDescription = lastDesription;
281 }
282 }
283
206 var description = this.property.value.description; 284 var description = this.property.value.description;
285
286 if (WebInspector.settings.highlightChangedProperties.get() && this.t reeOutline.section && this.treeOutline.section.memento) {
287 var descriptionToCompare = (type + ":" +
288 (subtype? subtype : "") + ":" + /* (this.property.value.obje ctId ? this.property.value.objectId : "") + ":" + */ description);
289 // determine if it has it changed only if description is initial ized
290 // this handles the case when the variable came into scope but
291 // was not initialized
292 var descriptionChanged = false;
293 if (hadProperty)
294 descriptionChanged = (descriptionToCompare != oldDescription );
295 else
296 descriptionChanged = true;
297
298 if (this.propertyPath() && this.treeOutline.section.memento._las tDescriptions)
299 this.treeOutline.section.memento.setLastDescriptionForProper tyPath(this.propertyPath(), descriptionToCompare);
300 }
301
207 var prefix; 302 var prefix;
208 var valueText; 303 var valueText;
209 var suffix; 304 var suffix;
210 if (this.property.wasThrown) { 305 if (this.property.wasThrown) {
211 prefix = "[Exception: "; 306 prefix = "[Exception: ";
212 valueText = description; 307 valueText = description;
213 suffix = "]"; 308 suffix = "]";
214 } else if (type === "string" && typeof description === "string") { 309 } else if (type === "string" && typeof description === "string") {
215 // Render \n as a nice unicode cr symbol. 310 // Render \n as a nice unicode cr symbol.
216 prefix = "\""; 311 prefix = "\"";
(...skipping 16 matching lines...) Expand all
233 } else { 328 } else {
234 var numberParts = valueText.split("e"); 329 var numberParts = valueText.split("e");
235 var mantissa = this.valueElement.createChild("span", "scientific -notation-mantissa"); 330 var mantissa = this.valueElement.createChild("span", "scientific -notation-mantissa");
236 mantissa.textContent = numberParts[0]; 331 mantissa.textContent = numberParts[0];
237 var exponent = this.valueElement.createChild("span", "scientific -notation-exponent"); 332 var exponent = this.valueElement.createChild("span", "scientific -notation-exponent");
238 exponent.textContent = "e" + numberParts[1]; 333 exponent.textContent = "e" + numberParts[1];
239 this.valueElement.classList.add("scientific-notation-number"); 334 this.valueElement.classList.add("scientific-notation-number");
240 this.listItemElement.classList.add("hbox"); 335 this.listItemElement.classList.add("hbox");
241 } 336 }
242 337
338 if (WebInspector.settings.highlightChangedProperties.get() && this.t reeOutline.section && this.treeOutline.section.memento) {
339 if (descriptionChanged) {
340 this.valueElement.classList.add("highlighted-search-result") ;
341 if (!hadProperty)
342 // new - highlight name also
343 this.nameElement.classList.add("highlighted-search-resul t");
344 }
345 }
346
243 if (this.property.wasThrown) 347 if (this.property.wasThrown)
244 this.valueElement.classList.add("error"); 348 this.valueElement.classList.add("error");
245 if (subtype || type) 349 if (subtype || type)
246 this.valueElement.classList.add("console-formatted-" + (subtype || type)); 350 this.valueElement.classList.add("console-formatted-" + (subtype || type));
247 351
248 this.valueElement.addEventListener("contextmenu", this._contextMenuF ired.bind(this, this.property.value), false); 352 this.valueElement.addEventListener("contextmenu", this._contextMenuF ired.bind(this, this.property.value), false);
249 if (type === "object" && subtype === "node" && description) { 353 if (type === "object" && subtype === "node" && description) {
250 WebInspector.DOMPresentationUtils.createSpansForNodeTitle(this.v alueElement, description); 354 WebInspector.DOMPresentationUtils.createSpansForNodeTitle(this.v alueElement, description);
251 this.valueElement.addEventListener("mousemove", this._mouseMove. bind(this), false); 355 this.valueElement.addEventListener("mousemove", this._mouseMove. bind(this), false);
252 this.valueElement.addEventListener("mouseleave", this._mouseLeav e.bind(this), false); 356 this.valueElement.addEventListener("mouseleave", this._mouseLeav e.bind(this), false);
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 { 1224 {
1121 WebInspector.TextPrompt.call(this, WebInspector.ExecutionContextSelector.com pletionsForTextPromptInCurrentContext); 1225 WebInspector.TextPrompt.call(this, WebInspector.ExecutionContextSelector.com pletionsForTextPromptInCurrentContext);
1122 this.setSuggestBoxEnabled(true); 1226 this.setSuggestBoxEnabled(true);
1123 if (renderAsBlock) 1227 if (renderAsBlock)
1124 this.renderAsBlock(); 1228 this.renderAsBlock();
1125 } 1229 }
1126 1230
1127 WebInspector.ObjectPropertyPrompt.prototype = { 1231 WebInspector.ObjectPropertyPrompt.prototype = {
1128 __proto__: WebInspector.TextPrompt.prototype 1232 __proto__: WebInspector.TextPrompt.prototype
1129 } 1233 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698