Index: Source/devtools/front_end/components/ObjectPropertiesSection.js |
diff --git a/Source/devtools/front_end/components/ObjectPropertiesSection.js b/Source/devtools/front_end/components/ObjectPropertiesSection.js |
index 5ad51126a336150be71066f4e919f937dbc281c7..2acc1a96cdf313f752f6e30503be767e08b01329 100644 |
--- a/Source/devtools/front_end/components/ObjectPropertiesSection.js |
+++ b/Source/devtools/front_end/components/ObjectPropertiesSection.js |
@@ -34,8 +34,9 @@ |
* @param {boolean=} ignoreHasOwnProperty |
* @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties |
* @param {function(new:TreeElement, !WebInspector.RemoteObjectProperty)=} treeElementConstructor |
+ * @param {?WebInspector.ObjectPropertiesMemento=} memento |
*/ |
-WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor) |
+WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor, memento) |
{ |
this._emptyPlaceholder = emptyPlaceholder; |
this.object = object; |
@@ -44,6 +45,10 @@ WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPl |
this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement; |
this.editable = true; |
this.skipProto = false; |
+ /** |
+ * @private |
+ */ |
+ this.memento = memento; |
WebInspector.PropertiesSection.call(this, title || "", subtitle); |
} |
@@ -94,6 +99,9 @@ WebInspector.ObjectPropertiesSection.prototype = { |
updateProperties: function(properties, internalProperties, rootTreeElementConstructor, rootPropertyComparer) |
{ |
+ if (this.memento) |
+ this.memento.forgetProperties(); |
+ |
if (!rootTreeElementConstructor) |
rootTreeElementConstructor = this.treeElementConstructor; |
@@ -140,6 +148,66 @@ WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, pro |
/** |
* @constructor |
+ */ |
+WebInspector.ObjectPropertiesMemento = function() |
+{ |
+ this._expandedProperties = new Set(); |
+ this._lastDescriptions = {}; |
+ this._propertyIdentifiers = {}; |
+} |
+ |
+WebInspector.ObjectPropertiesMemento.prototype = { |
+ /** |
+ * @return {boolean} |
+ */ |
+ isPropertyPathExpanded: function(propertyPath) |
+ { |
+ return this._expandedProperties.has(propertyPath); |
+ }, |
+ addExpandedPropertyPath: function(propertyPath) |
+ { |
+ this._expandedProperties.add(propertyPath); |
+ }, |
+ deleteExpandedPropertyPath: function(propertyPath) |
+ { |
+ this._expandedProperties['delete'](propertyPath); |
+ }, |
+ forgetProperties: function() |
+ { |
+ for (var pi in this._lastDescriptions) |
+ { |
+ if (!(pi in this._propertyIdentifiers)) |
+ delete this._lastDescriptions[pi]; |
+ } |
+ this._propertyIdentifiers = {}; |
+ }, |
+ /** |
+ * @param {!WebInspector.ObjectPropertyTreeElement} objectPropertyTreeElement |
+ */ |
+ recordAndDecorate: function(objectPropertyTreeElement) |
+ { |
+ var propertyPath = objectPropertyTreeElement.propertyPath(); |
+ if (Runtime.experiments.isEnabled("highlightChangedProperties") && propertyPath) { |
+ this._propertyIdentifiers[propertyPath] = 1; |
+ var lastDesription = this._lastDescriptions[propertyPath]; |
+ var hadProperty = (lastDesription != undefined); |
+ var description = (objectPropertyTreeElement.property.value.type + ":" + |
+ (objectPropertyTreeElement.property.value.subtype? objectPropertyTreeElement.property.value.subtype : "") + ":" + |
+ /* (objectPropertyTreeElement.property.value.objectId ? objectPropertyTreeElement.property.value.objectId : "") + ":" + */ |
+ objectPropertyTreeElement.property.value.description); |
+ var descriptionChanged = (!hadProperty) || (description != lastDesription); |
+ this._lastDescriptions[propertyPath] = description; |
+ |
+ if (descriptionChanged) |
+ objectPropertyTreeElement.valueElement.classList.add("highlighted-search-result"); |
+ if (!hadProperty) |
+ objectPropertyTreeElement.nameElement.classList.add("highlighted-search-result"); |
+ } |
+ } |
+} |
+ |
+/** |
+ * @constructor |
* @extends {TreeElement} |
* @param {!WebInspector.RemoteObjectProperty} property |
*/ |
@@ -540,6 +608,17 @@ WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value, e |
WebInspector.ObjectPropertyTreeElement.populateWithProperties = function(treeNode, properties, internalProperties, treeElementConstructor, comparator, skipProto, value, emptyPlaceholder) { |
properties.sort(comparator); |
+ function appendChild(treeElement) { |
+ treeNode.appendChild(treeElement); |
+ if (treeElement instanceof WebInspector.ObjectPropertyTreeElement) { |
+ var treeElementPropertyPath = treeElement.propertyPath(); |
+ if (Runtime.experiments.isEnabled("highlightChangedProperties") && |
+ treeElementPropertyPath && |
+ treeNode.treeOutline.section.memento) |
+ treeNode.treeOutline.section.memento.recordAndDecorate(treeElement); |
+ } |
+ } |
+ |
for (var i = 0; i < properties.length; ++i) { |
var property = properties[i]; |
if (skipProto && property.name === "__proto__") |
@@ -547,29 +626,29 @@ WebInspector.ObjectPropertyTreeElement.populateWithProperties = function(treeNod |
if (property.isAccessorProperty()) { |
if (property.name !== "__proto__" && property.getter) { |
property.parentObject = value; |
- treeNode.appendChild(new treeElementConstructor(property)); |
+ appendChild(new treeElementConstructor(property)); |
} |
if (property.isOwn) { |
if (property.getter) { |
var getterProperty = new WebInspector.RemoteObjectProperty("get " + property.name, property.getter); |
getterProperty.parentObject = value; |
- treeNode.appendChild(new treeElementConstructor(getterProperty)); |
+ appendChild(new treeElementConstructor(getterProperty)); |
} |
if (property.setter) { |
var setterProperty = new WebInspector.RemoteObjectProperty("set " + property.name, property.setter); |
setterProperty.parentObject = value; |
- treeNode.appendChild(new treeElementConstructor(setterProperty)); |
+ appendChild(new treeElementConstructor(setterProperty)); |
} |
} |
} else { |
property.parentObject = value; |
- treeNode.appendChild(new treeElementConstructor(property)); |
+ appendChild(new treeElementConstructor(property)); |
} |
} |
if (internalProperties) { |
for (var i = 0; i < internalProperties.length; i++) { |
internalProperties[i].parentObject = value; |
- treeNode.appendChild(new treeElementConstructor(internalProperties[i])); |
+ appendChild(new treeElementConstructor(internalProperties[i])); |
} |
} |
if (value && value.type === "function") { |
@@ -587,10 +666,10 @@ WebInspector.ObjectPropertyTreeElement.populateWithProperties = function(treeNod |
} |
} |
if (!hasTargetFunction) |
- treeNode.appendChild(new WebInspector.FunctionScopeMainTreeElement(value)); |
+ appendChild(new WebInspector.FunctionScopeMainTreeElement(value)); |
} |
if (value && value.type === "object" && (value.subtype === "map" || value.subtype === "set" || value.subtype === "iterator")) |
- treeNode.appendChild(new WebInspector.CollectionEntriesMainTreeElement(value)); |
+ appendChild(new WebInspector.CollectionEntriesMainTreeElement(value)); |
WebInspector.ObjectPropertyTreeElement._appendEmptyPlaceholderIfNeeded(treeNode, emptyPlaceholder); |
} |