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

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

Issue 2012033002: DevTools: more previews when formatting logged arrays/objects (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code cleanup Created 4 years, 6 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 11 matching lines...) Expand all
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 /** 27 /**
28 * @constructor 28 * @constructor
29 * @extends {TreeOutlineInShadow} 29 * @extends {TreeOutlineInShadow}
30 * @param {!WebInspector.RemoteObject} object 30 * @param {!WebInspector.RemoteObject} object
31 * @param {?string|!Element=} title 31 * @param {?string|!Element=} title
32 * @param {?string|!Element=} expandedTitle
32 * @param {?string=} emptyPlaceholder 33 * @param {?string=} emptyPlaceholder
33 * @param {boolean=} ignoreHasOwnProperty 34 * @param {boolean=} ignoreHasOwnProperty
34 * @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties 35 * @param {!Array.<!WebInspector.RemoteObjectProperty>=} extraProperties
35 */ 36 */
36 WebInspector.ObjectPropertiesSection = function(object, title, emptyPlaceholder, ignoreHasOwnProperty, extraProperties) 37 WebInspector.ObjectPropertiesSection = function(object, title, expandedTitle, em ptyPlaceholder, ignoreHasOwnProperty, extraProperties)
37 { 38 {
38 this._object = object; 39 this._object = object;
39 this._editable = true; 40 this._editable = true;
40 TreeOutlineInShadow.call(this); 41 TreeOutlineInShadow.call(this);
41 this.hideOverflow(); 42 this.hideOverflow();
42 this.setFocusable(false); 43 this.setFocusable(false);
43 this._objectTreeElement = new WebInspector.ObjectPropertiesSection.RootEleme nt(object, emptyPlaceholder, ignoreHasOwnProperty, extraProperties); 44 this._objectTreeElement = new WebInspector.ObjectPropertiesSection.RootEleme nt(object, emptyPlaceholder, ignoreHasOwnProperty, extraProperties);
44 this.appendChild(this._objectTreeElement); 45 this.appendChild(this._objectTreeElement);
45 if (typeof title === "string" || !title) 46 if (typeof title === "string" || !title) {
46 this.element.createChild("span").textContent = title || ""; 47 this.titleElement = this.element.createChild("span");
47 else 48 this.titleElement.textContent = title || "";
49 } else {
50 this.titleElement = title;
48 this.element.appendChild(title); 51 this.element.appendChild(title);
52 }
53
54 if (typeof expandedTitle === "string") {
55 this.expandedTitleElement = this.element.createChild("span");
56 this.expandedTitleElement.textContent = expandedTitle || "";
57 } else if (!!expandedTitle) {
58 this.expandedTitleElement = expandedTitle;
59 this.element.appendChild(expandedTitle);
60 }
61
62 if (!!expandedTitle)
63 this.expandedTitleElement.classList.add("hidden");
49 64
50 this.element._section = this; 65 this.element._section = this;
51 this.registerRequiredCSS("components/objectValue.css"); 66 this.registerRequiredCSS("components/objectValue.css");
52 this.registerRequiredCSS("components/objectPropertiesSection.css"); 67 this.registerRequiredCSS("components/objectPropertiesSection.css");
53 this.rootElement().childrenListElement.classList.add("source-code", "object- properties-section"); 68 this.rootElement().childrenListElement.classList.add("source-code", "object- properties-section");
54 } 69 }
55 70
56 /** @const */ 71 /** @const */
57 WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100; 72 WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;
58 73
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 this.setExpandable(true); 180 this.setExpandable(true);
166 this.selectable = false; 181 this.selectable = false;
167 this.toggleOnClick = true; 182 this.toggleOnClick = true;
168 this.listItemElement.classList.add("object-properties-section-root-element") ; 183 this.listItemElement.classList.add("object-properties-section-root-element") ;
169 } 184 }
170 185
171 WebInspector.ObjectPropertiesSection.RootElement.prototype = { 186 WebInspector.ObjectPropertiesSection.RootElement.prototype = {
172 187
173 onexpand: function() 188 onexpand: function()
174 { 189 {
175 if (this.treeOutline) 190 if (this.treeOutline) {
176 this.treeOutline.element.classList.add("expanded"); 191 this.treeOutline.element.classList.add("expanded");
192 if (this.treeOutline.expandedTitleElement) {
193 this.treeOutline.titleElement.classList.add("hidden");
194 this.treeOutline.expandedTitleElement.classList.remove("hidden") ;
195 }
196 }
177 }, 197 },
178 198
179 oncollapse: function() 199 oncollapse: function()
180 { 200 {
181 if (this.treeOutline) 201 if (this.treeOutline) {
182 this.treeOutline.element.classList.remove("expanded"); 202 this.treeOutline.element.classList.remove("expanded");
203 if (this.treeOutline.expandedTitleElement) {
204 this.treeOutline.titleElement.classList.remove("hidden");
205 this.treeOutline.expandedTitleElement.classList.add("hidden");
206 }
207 }
183 }, 208 },
184 209
185 /** 210 /**
186 * @override 211 * @override
187 * @param {!Event} e 212 * @param {!Event} e
188 * @return {boolean} 213 * @return {boolean}
189 */ 214 */
190 ondblclick: function(e) 215 ondblclick: function(e)
191 { 216 {
192 return true; 217 return true;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 var targetValue = this.property.name !== "__proto__" ? propertyValue : t his.property.parentObject; 295 var targetValue = this.property.name !== "__proto__" ? propertyValue : t his.property.parentObject;
271 WebInspector.ObjectPropertyTreeElement._populate(this, propertyValue, sk ipProto, undefined, undefined, undefined, targetValue); 296 WebInspector.ObjectPropertyTreeElement._populate(this, propertyValue, sk ipProto, undefined, undefined, undefined, targetValue);
272 }, 297 },
273 298
274 /** 299 /**
275 * @override 300 * @override
276 * @return {boolean} 301 * @return {boolean}
277 */ 302 */
278 ondblclick: function(event) 303 ondblclick: function(event)
279 { 304 {
280 var editableElement = this.valueElement; 305 var inEditableElement = event.target.isSelfOrDescendant(this.valueElemen t) || (this.expandedValueElement && event.target.isSelfOrDescendant(this.expande dValueElement));
281 if (!this.property.value.customPreview() && (this.property.writable || t his.property.setter) && event.target.isSelfOrDescendant(editableElement)) 306 if (!this.property.value.customPreview() && inEditableElement && (this.p roperty.writable || this.property.setter))
282 this._startEditing(); 307 this._startEditing();
283 return false; 308 return false;
284 }, 309 },
285 310
286 /** 311 /**
287 * @override 312 * @override
288 */ 313 */
289 onattach: function() 314 onattach: function()
290 { 315 {
291 this.update(); 316 this.update();
292 this._updateExpandable(); 317 this._updateExpandable();
293 }, 318 },
294 319
320 /**
321 * @override
322 */
323 onexpand: function()
324 {
325 this.valueElement.classList.add("hidden");
326 if (this.expandedValueElement)
327 this.expandedValueElement.classList.remove("hidden");
328 },
329
330 /**
331 * @override
332 */
333 oncollapse: function()
334 {
335 this.valueElement.classList.remove("hidden");
336 if (this.expandedValueElement)
337 this.expandedValueElement.classList.add("hidden");
338 },
339
295 update: function() 340 update: function()
296 { 341 {
297 this.nameElement = WebInspector.ObjectPropertiesSection.createNameElemen t(this.property.name); 342 this.nameElement = WebInspector.ObjectPropertiesSection.createNameElemen t(this.property.name);
298 if (!this.property.enumerable) 343 if (!this.property.enumerable)
299 this.nameElement.classList.add("object-properties-section-dimmed"); 344 this.nameElement.classList.add("object-properties-section-dimmed");
300 if (this.property.isAccessorProperty()) 345 if (this.property.isAccessorProperty())
301 this.nameElement.classList.add("properties-accessor-property-name"); 346 this.nameElement.classList.add("properties-accessor-property-name");
302 if (this.property.synthetic) 347 if (this.property.synthetic)
303 this.nameElement.classList.add("synthetic-property"); 348 this.nameElement.classList.add("synthetic-property");
304 349
305 this._updatePropertyPath(); 350 this._updatePropertyPath();
306 this.nameElement.addEventListener("contextmenu", this._contextMenuFired. bind(this, this.property), false); 351 this.nameElement.addEventListener("contextmenu", this._contextMenuFired. bind(this, this.property), false);
307 352
308 var separatorElement = createElementWithClass("span", "object-properties -section-separator"); 353 var separatorElement = createElementWithClass("span", "object-properties -section-separator");
309 separatorElement.textContent = ": "; 354 separatorElement.textContent = ": ";
310 355
311 if (this.property.value) { 356 if (this.property.value) {
312 this.valueElement = WebInspector.ObjectPropertiesSection.createValue ElementWithCustomSupport(this.property.value, this.property.wasThrown, this.list ItemElement); 357 this.valueElement = WebInspector.ObjectPropertiesSection.createValue ElementWithCustomSupport(this.property.value, this.property.wasThrown, this.list ItemElement);
313 this.valueElement.addEventListener("contextmenu", this._contextMenuF ired.bind(this, this.property), false); 358 this.valueElement.addEventListener("contextmenu", this._contextMenuF ired.bind(this, this.property), false);
314 } else if (this.property.getter) { 359 } else if (this.property.getter) {
315 this.valueElement = WebInspector.ObjectPropertyTreeElement.createRem oteObjectAccessorPropertySpan(this.property.parentObject, [this.property.name], this._onInvokeGetterClick.bind(this)); 360 this.valueElement = WebInspector.ObjectPropertyTreeElement.createRem oteObjectAccessorPropertySpan(this.property.parentObject, [this.property.name], this._onInvokeGetterClick.bind(this));
316 } else { 361 } else {
317 this.valueElement = createElementWithClass("span", "object-value-und efined"); 362 this.valueElement = createElementWithClass("span", "object-value-und efined");
318 this.valueElement.textContent = WebInspector.UIString("<unreadable>" ); 363 this.valueElement.textContent = WebInspector.UIString("<unreadable>" );
319 this.valueElement.title = WebInspector.UIString("No property getter" ); 364 this.valueElement.title = WebInspector.UIString("No property getter" );
320 } 365 }
321 366
367 this.expandedValueElement = WebInspector.ObjectPropertiesSection.createD escriptionValueElement(this.property.value);
368
322 this.listItemElement.removeChildren(); 369 this.listItemElement.removeChildren();
323 this.listItemElement.appendChildren(this.nameElement, separatorElement, this.valueElement); 370 this.listItemElement.appendChildren(this.nameElement, separatorElement, this.valueElement);
371 if (this.expandedValueElement)
372 this.listItemElement.appendChild(this.expandedValueElement);
324 }, 373 },
325 374
326 _updatePropertyPath: function() 375 _updatePropertyPath: function()
327 { 376 {
328 if (this.nameElement.title) 377 if (this.nameElement.title)
329 return; 378 return;
330 379
331 var useDotNotation = /^(_|\$|[A-Z])(_|\$|[A-Z]|\d)*$/i; 380 var useDotNotation = /^(_|\$|[A-Z])(_|\$|[A-Z]|\d)*$/i;
332 var isInteger = /^[1-9]\d*$/; 381 var isInteger = /^[1-9]\d*$/;
333 var name = this.property.name; 382 var name = this.property.name;
(...skipping 22 matching lines...) Expand all
356 contextMenu.show(); 405 contextMenu.show();
357 }, 406 },
358 407
359 _startEditing: function() 408 _startEditing: function()
360 { 409 {
361 if (this._prompt || !this.treeOutline._editable || this._readOnly) 410 if (this._prompt || !this.treeOutline._editable || this._readOnly)
362 return; 411 return;
363 412
364 this._editableDiv = this.listItemElement.createChild("span"); 413 this._editableDiv = this.listItemElement.createChild("span");
365 414
366 var text = this.property.value.description; 415 var text = this.valueElement.textContent || this.property.value.descript ion;
367 if (this.property.value.type === "string" && typeof text === "string") 416 if (this.property.value.type === "object" && this.property.value.subtype === "array") {
368 text = "\"" + text + "\""; 417 var childNodes = Array.prototype.slice.call(this.valueElement.childN odes);
418 var hasLengthLabel = childNodes.length && childNodes[childNodes.leng th - 1].classList.contains("object-value-array-length");
419 if (hasLengthLabel)
420 text = childNodes.slice(0, childNodes.length - 1).map((el) => el .textContent).join("");
421 }
369 422
370 this._editableDiv.setTextContentTruncatedIfNeeded(text, WebInspector.UIS tring("<string is too large to edit>")); 423 this._editableDiv.setTextContentTruncatedIfNeeded(text, WebInspector.UIS tring("<string is too large to edit>"));
371 var originalContent = this._editableDiv.textContent; 424 var originalContent = this._editableDiv.textContent;
372 425
373 this.valueElement.classList.add("hidden");
374
375 // Lie about our children to prevent expanding on double click and to co llapse subproperties. 426 // Lie about our children to prevent expanding on double click and to co llapse subproperties.
376 this.setExpandable(false); 427 this.setExpandable(false);
377 this.listItemElement.classList.add("editing-sub-part"); 428 this.listItemElement.classList.add("editing-sub-part");
429 this.valueElement.classList.add("hidden");
430 if (this.expandedValueElement)
431 this.expandedValueElement.classList.add("hidden");
378 432
379 this._prompt = new WebInspector.ObjectPropertyPrompt(); 433 this._prompt = new WebInspector.ObjectPropertyPrompt();
380 434
381 var proxyElement = this._prompt.attachAndStartEditing(this._editableDiv, this._editingCommitted.bind(this, originalContent)); 435 var proxyElement = this._prompt.attachAndStartEditing(this._editableDiv, this._editingCommitted.bind(this, originalContent));
382 this.listItemElement.getComponentSelection().setBaseAndExtent(this._edit ableDiv, 0, this._editableDiv, 1); 436 this.listItemElement.getComponentSelection().setBaseAndExtent(this._edit ableDiv, 0, this._editableDiv, 1);
383 proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, originalContent), false); 437 proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, originalContent), false);
384 }, 438 },
385 439
386 _editingEnded: function() 440 _editingEnded: function()
387 { 441 {
388 this._prompt.detach(); 442 this._prompt.detach();
389 delete this._prompt; 443 delete this._prompt;
390 this._editableDiv.remove(); 444 this._editableDiv.remove();
391 this._updateExpandable(); 445 this._updateExpandable();
392 this.listItemElement.scrollLeft = 0; 446 this.listItemElement.scrollLeft = 0;
393 this.listItemElement.classList.remove("editing-sub-part"); 447 this.listItemElement.classList.remove("editing-sub-part");
394 }, 448 },
395 449
396 _editingCancelled: function() 450 _editingCancelled: function()
397 { 451 {
398 this.valueElement.classList.remove("hidden"); 452 if (this.expanded && this.expandedValueElement)
453 this.expandedValueElement.classList.remove("hidden");
454 else
455 this.valueElement.classList.remove("hidden");
399 this._editingEnded(); 456 this._editingEnded();
400 }, 457 },
401 458
402 /** 459 /**
403 * @param {string} originalContent 460 * @param {string} originalContent
404 */ 461 */
405 _editingCommitted: function(originalContent) 462 _editingCommitted: function(originalContent)
406 { 463 {
407 var userInput = this._prompt.text(); 464 var userInput = this._prompt.text();
408 if (userInput === originalContent) { 465 if (userInput === originalContent) {
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 } else if (type === "string" && typeof description === "string") { 1241 } else if (type === "string" && typeof description === "string") {
1185 // Render \n as a nice unicode cr symbol. 1242 // Render \n as a nice unicode cr symbol.
1186 prefix = "\""; 1243 prefix = "\"";
1187 valueText = description.replace(/\n/g, "\u21B5"); 1244 valueText = description.replace(/\n/g, "\u21B5");
1188 suffix = "\""; 1245 suffix = "\"";
1189 } else if (type === "function") { 1246 } else if (type === "function") {
1190 valueText = WebInspector.ObjectPropertiesSection.valueTextForFunctionDes cription(description); 1247 valueText = WebInspector.ObjectPropertiesSection.valueTextForFunctionDes cription(description);
1191 } else if (type !== "object" || subtype !== "node") { 1248 } else if (type !== "object" || subtype !== "node") {
1192 valueText = description; 1249 valueText = description;
1193 } 1250 }
1194 if (type !== "number" || valueText.indexOf("e") === -1) { 1251
1252 var previewFormatter = new WebInspector.RemoteObjectPreviewFormatter();
1253 if (type === "object" && !subtype && value.preview) {
1254 previewFormatter.appendObjectPreview(valueElement, value.preview, true);
1255 } else if (value.arrayLength && value.preview) {
1256 previewFormatter.appendObjectPreview(valueElement, value.preview, true);
1257 valueElement.createChild("span", "object-value-array-length").textConten t = "(" + value.arrayLength() + ")";
1258 } else if (type !== "number" || valueText.indexOf("e") === -1) {
1195 valueElement.setTextContentTruncatedIfNeeded(valueText || ""); 1259 valueElement.setTextContentTruncatedIfNeeded(valueText || "");
1196 if (prefix) 1260 if (prefix)
1197 valueElement.insertBefore(createTextNode(prefix), valueElement.first Child); 1261 valueElement.insertBefore(createTextNode(prefix), valueElement.first Child);
1198 if (suffix) 1262 if (suffix)
1199 valueElement.createTextChild(suffix); 1263 valueElement.createTextChild(suffix);
1200 } else { 1264 } else {
1201 var numberParts = valueText.split("e"); 1265 var numberParts = valueText.split("e");
1202 var mantissa = valueElement.createChild("span", "object-value-scientific -notation-mantissa"); 1266 var mantissa = valueElement.createChild("span", "object-value-scientific -notation-mantissa");
1203 mantissa.textContent = numberParts[0]; 1267 mantissa.textContent = numberParts[0];
1204 var exponent = valueElement.createChild("span", "object-value-scientific -notation-exponent"); 1268 var exponent = valueElement.createChild("span", "object-value-scientific -notation-exponent");
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 function mouseClick(event) 1302 function mouseClick(event)
1239 { 1303 {
1240 WebInspector.Revealer.reveal(value); 1304 WebInspector.Revealer.reveal(value);
1241 event.consume(true); 1305 event.consume(true);
1242 } 1306 }
1243 1307
1244 return valueElement; 1308 return valueElement;
1245 } 1309 }
1246 1310
1247 /** 1311 /**
1312 * @param {!WebInspector.RemoteObject} value
1313 * @return {?Element}
1314 */
1315 WebInspector.ObjectPropertiesSection.createDescriptionValueElement = function(va lue)
1316 {
1317 if (!value || (value.type === "object" && value.subtype === "node"))
1318 return null;
1319 var valueElement = createElementWithClass("span", "value");
1320 var type = value.type;
1321 var subtype = value.subtype;
1322 var description = value.description;
1323
1324 valueElement.setTextContentTruncatedIfNeeded(description || "");
1325 valueElement.classList.add("object-value-" + (subtype || type));
1326 valueElement.classList.add("hidden");
1327 valueElement.title = description || "";
1328
1329 return valueElement;
1330 }
1331
1332 /**
1248 * @param {!WebInspector.RemoteObject} func 1333 * @param {!WebInspector.RemoteObject} func
1249 * @param {!Element} element 1334 * @param {!Element} element
1250 * @param {boolean} linkify 1335 * @param {boolean} linkify
1251 * @param {boolean=} includePreview 1336 * @param {boolean=} includePreview
1252 */ 1337 */
1253 WebInspector.ObjectPropertiesSection.formatObjectAsFunction = function(func, ele ment, linkify, includePreview) 1338 WebInspector.ObjectPropertiesSection.formatObjectAsFunction = function(func, ele ment, linkify, includePreview)
1254 { 1339 {
1255 func.functionDetails(didGetDetails); 1340 func.functionDetails(didGetDetails);
1256 1341
1257 /** 1342 /**
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 1496
1412 result = currentName + (result ? "." + result : ""); 1497 result = currentName + (result ? "." + result : "");
1413 current = current.parent; 1498 current = current.parent;
1414 } 1499 }
1415 var treeOutlineId = treeElement.treeOutline[WebInspector.ObjectPropertie sSectionExpandController._treeOutlineId]; 1500 var treeOutlineId = treeElement.treeOutline[WebInspector.ObjectPropertie sSectionExpandController._treeOutlineId];
1416 result = treeOutlineId + (result ? ":" + result : ""); 1501 result = treeOutlineId + (result ? ":" + result : "");
1417 treeElement[WebInspector.ObjectPropertiesSectionExpandController._cached PathSymbol] = result; 1502 treeElement[WebInspector.ObjectPropertiesSectionExpandController._cached PathSymbol] = result;
1418 return result; 1503 return result;
1419 } 1504 }
1420 } 1505 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698