Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 3 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
| 4 * Copyright (C) 2009 Joseph Pecoraro | 4 * Copyright (C) 2009 Joseph Pecoraro |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * | 9 * |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 * @param {!Element} elem | 356 * @param {!Element} elem |
| 357 * @param {boolean} includePreview | 357 * @param {boolean} includePreview |
| 358 */ | 358 */ |
| 359 _formatParameterAsArrayOrObject: function(obj, description, elem, includePre view) | 359 _formatParameterAsArrayOrObject: function(obj, description, elem, includePre view) |
| 360 { | 360 { |
| 361 var titleElement = document.createElement("span"); | 361 var titleElement = document.createElement("span"); |
| 362 if (description) | 362 if (description) |
| 363 titleElement.createTextChild(description); | 363 titleElement.createTextChild(description); |
| 364 if (includePreview && obj.preview) { | 364 if (includePreview && obj.preview) { |
| 365 titleElement.classList.add("console-object-preview"); | 365 titleElement.classList.add("console-object-preview"); |
| 366 var lossless = this._appendObjectPreview(obj, description, titleElem ent); | 366 if (description) |
| 367 titleElement.createTextChild(" "); | |
| 368 var lossless = this._appendObjectPreview(obj, titleElement); | |
| 367 if (lossless) { | 369 if (lossless) { |
| 368 elem.appendChild(titleElement); | 370 elem.appendChild(titleElement); |
| 369 return; | 371 return; |
| 370 } | 372 } |
| 371 } | 373 } |
| 372 var section = new WebInspector.ObjectPropertiesSection(obj, titleElement ); | 374 var section = new WebInspector.ObjectPropertiesSection(obj, titleElement ); |
| 373 section.enableContextMenu(); | 375 section.enableContextMenu(); |
| 374 elem.appendChild(section.element); | 376 elem.appendChild(section.element); |
| 375 | 377 |
| 376 var note = section.titleElement.createChild("span", "object-info-state-n ote"); | 378 var note = section.titleElement.createChild("span", "object-info-state-n ote"); |
| 377 note.title = WebInspector.UIString("Object state below is captured upon first expansion"); | 379 note.title = WebInspector.UIString("Object state below is captured upon first expansion"); |
| 378 }, | 380 }, |
| 379 | 381 |
| 380 /** | 382 /** |
| 381 * @param {!WebInspector.RemoteObject} obj | 383 * @param {!WebInspector.RemoteObject} obj |
| 382 * @param {string} description | |
| 383 * @param {!Element} titleElement | 384 * @param {!Element} titleElement |
| 384 * @return {boolean} true iff preview captured all information. | 385 * @return {boolean} true iff preview captured all information. |
| 385 */ | 386 */ |
| 386 _appendObjectPreview: function(obj, description, titleElement) | 387 _appendObjectPreview: function(obj, titleElement) |
| 387 { | 388 { |
| 388 var preview = obj.preview; | 389 var preview = obj.preview; |
| 389 var isArray = obj.subtype === "array"; | 390 var isArray = obj.subtype === "array"; |
| 391 var arrayLength = isArray ? obj.arrayLength() : undefined; | |
| 392 var properties = preview.properties; | |
| 390 | 393 |
| 391 if (description) | 394 var elements = []; |
| 392 titleElement.createTextChild(" "); | 395 for (var i = 0; i < properties.length; ++i) { |
| 393 titleElement.createTextChild(isArray ? "[" : "{"); | 396 var property = properties[i]; |
| 394 for (var i = 0; i < preview.properties.length; ++i) { | 397 var name = property.name; |
| 395 if (i > 0) | 398 elements.push({ |
| 396 titleElement.createTextChild(", "); | 399 name: name, |
| 400 element: this._renderPropertyPreviewOrAccessor(obj, [property]) | |
| 401 }); | |
| 402 } | |
| 397 | 403 |
| 398 var property = preview.properties[i]; | 404 this._appendArrayOrObjectPropertyElements(titleElement, elements, previe w.overflow, arrayLength); |
| 399 var name = property.name; | |
| 400 if (!isArray || name != i) { | |
| 401 if (/^\s|\s$|^$|\n/.test(name)) | |
| 402 name = "\"" + name.replace(/\n/g, "\u21B5") + "\""; | |
| 403 titleElement.createChild("span", "name").textContent = name; | |
| 404 titleElement.createTextChild(": "); | |
| 405 } | |
| 406 | |
| 407 titleElement.appendChild(this._renderPropertyPreviewOrAccessor(obj, [property])); | |
| 408 } | |
| 409 if (preview.overflow) | |
| 410 titleElement.createChild("span").textContent = "\u2026"; | |
| 411 titleElement.createTextChild(isArray ? "]" : "}"); | |
| 412 return preview.lossless; | 405 return preview.lossless; |
| 413 }, | 406 }, |
| 414 | 407 |
| 415 /** | 408 /** |
| 409 * @param {!Element} parent | |
| 410 * @param {!Array.<{name: string, element: !Element}>} propertyElements | |
| 411 * @param {boolean} overflow | |
| 412 * @param {number=} arrayLength | |
| 413 */ | |
| 414 _appendArrayOrObjectPropertyElements: function(parent, propertyElements, ove rflow, arrayLength) | |
|
pfeldman
2014/01/23 16:19:02
This only runs for preview, right? Could you name
aandrey
2014/01/24 06:22:04
not only for preview: from _printArray also.
| |
| 415 { | |
| 416 const maxFlatArrayLength = 100; | |
| 417 | |
| 418 /** | |
| 419 * @param {{name: string, element: !Element}} a | |
| 420 * @param {{name: string, element: !Element}} b | |
| 421 * @return {number} | |
| 422 */ | |
| 423 function comparator(a, b) | |
| 424 { | |
| 425 var isIndex1 = String.isArrayIndexPropertyName(a.name, arrayLength); | |
| 426 var isIndex2 = String.isArrayIndexPropertyName(b.name, arrayLength); | |
| 427 if (isIndex1 && isIndex2) | |
| 428 return Number(a.name) - Number(b.name); | |
| 429 if (isIndex1) | |
| 430 return -1; | |
| 431 if (isIndex2) | |
| 432 return 1; | |
| 433 return 0; | |
| 434 } | |
| 435 | |
| 436 var isArray = typeof arrayLength === "number"; | |
| 437 if (isArray) | |
| 438 propertyElements.stableSort(comparator); | |
|
pfeldman
2014/01/23 16:19:02
Why sorting properties? They should come in sorted
aandrey
2014/01/24 06:22:04
They are sorted according to the index in the prot
| |
| 439 var isFlatArray = isArray && (arrayLength <= maxFlatArrayLength); | |
|
pfeldman
2014/01/23 16:19:02
So we only render as flat when < 100 actual values
aandrey
2014/01/24 06:22:04
Yes. This has been the case up to now - I didn't c
| |
| 440 | |
| 441 parent.createTextChild(isArray ? "[" : "{"); | |
| 442 var firstElement = true; | |
| 443 var lastNonEmptyArrayIndex = -1; | |
| 444 | |
| 445 function appendCommaIfNeeded() | |
| 446 { | |
| 447 if (firstElement) | |
| 448 firstElement = false; | |
| 449 else | |
| 450 parent.createTextChild(", "); | |
| 451 } | |
| 452 | |
| 453 /** | |
| 454 * @param {number=} index | |
| 455 */ | |
| 456 function appendUndefinedArrayElements(index) | |
| 457 { | |
| 458 if (typeof index !== "number") | |
| 459 return; | |
| 460 var undefinedRange = index - lastNonEmptyArrayIndex - 1; | |
| 461 lastNonEmptyArrayIndex = index; | |
| 462 if (undefinedRange < 1) | |
| 463 return; | |
| 464 appendCommaIfNeeded(); | |
| 465 var span = parent.createChild("span", "console-formatted-undefined") ; | |
| 466 span.textContent = WebInspector.UIString("undefined × %d", undefined Range); | |
| 467 } | |
| 468 | |
| 469 /** | |
| 470 * @param {string} name | |
| 471 */ | |
| 472 function appendPropertyName(name) | |
| 473 { | |
| 474 if (/^\s|\s$|^$|\n/.test(name)) | |
| 475 name = "\"" + name.replace(/\n/g, "\u21B5") + "\""; | |
| 476 parent.createChild("span", "name").textContent = name; | |
| 477 parent.createTextChild(": "); | |
| 478 } | |
| 479 | |
| 480 for (var i = 0, n = propertyElements.length; i < n; ++i) { | |
| 481 var name = propertyElements[i].name; | |
| 482 var element = propertyElements[i].element; | |
| 483 var isIndex = String.isArrayIndexPropertyName(name, arrayLength); | |
| 484 var index = isIndex ? Number(name) : 0; | |
| 485 | |
| 486 if (isFlatArray) { | |
| 487 appendUndefinedArrayElements(isIndex ? index : arrayLength); | |
| 488 appendCommaIfNeeded(); | |
| 489 if (!isIndex) | |
| 490 appendPropertyName(name); | |
| 491 } else { | |
| 492 appendCommaIfNeeded(); | |
| 493 if (!isArray || !isIndex || index !== i) | |
| 494 appendPropertyName(name); | |
| 495 } | |
| 496 | |
| 497 parent.appendChild(element); | |
| 498 } | |
| 499 if (isFlatArray) | |
| 500 appendUndefinedArrayElements(arrayLength); | |
| 501 | |
| 502 if (overflow) | |
| 503 parent.createChild("span").textContent = "\u2026"; | |
| 504 parent.createTextChild(isArray ? "]" : "}"); | |
| 505 }, | |
| 506 | |
| 507 /** | |
| 416 * @param {!WebInspector.RemoteObject} object | 508 * @param {!WebInspector.RemoteObject} object |
| 417 * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath | 509 * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath |
| 418 * @return {!Element} | 510 * @return {!Element} |
| 419 */ | 511 */ |
| 420 _renderPropertyPreviewOrAccessor: function(object, propertyPath) | 512 _renderPropertyPreviewOrAccessor: function(object, propertyPath) |
| 421 { | 513 { |
| 422 var property = propertyPath.peekLast(); | 514 var property = propertyPath.peekLast(); |
| 423 if (property.type === "accessor") | 515 if (property.type === "accessor") |
| 424 return this._formatAsAccessorProperty(object, propertyPath.select("n ame"), false); | 516 return this._formatAsAccessorProperty(object, propertyPath.select("n ame"), false); |
| 425 return this._renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value); | 517 return this._renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 { | 597 { |
| 506 if (this.useArrayPreviewInFormatter(array)) { | 598 if (this.useArrayPreviewInFormatter(array)) { |
| 507 this._formatParameterAsArrayOrObject(array, "", elem, true); | 599 this._formatParameterAsArrayOrObject(array, "", elem, true); |
| 508 return; | 600 return; |
| 509 } | 601 } |
| 510 | 602 |
| 511 const maxFlatArrayLength = 100; | 603 const maxFlatArrayLength = 100; |
| 512 if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) | 604 if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) |
| 513 this._formatParameterAsObject(array, elem, false); | 605 this._formatParameterAsObject(array, elem, false); |
| 514 else | 606 else |
| 515 array.getOwnProperties(this._printArray.bind(this, array, elem)); | 607 array.getAllProperties(false, this._printArray.bind(this, array, ele m)); |
| 516 }, | 608 }, |
| 517 | 609 |
| 518 /** | 610 /** |
| 519 * @param {!Array.<!WebInspector.RemoteObject>} parameters | 611 * @param {!Array.<!WebInspector.RemoteObject>} parameters |
| 520 * @return {!Element} | 612 * @return {!Element} |
| 521 */ | 613 */ |
| 522 _formatParameterAsTable: function(parameters) | 614 _formatParameterAsTable: function(parameters) |
| 523 { | 615 { |
| 524 var element = document.createElement("span"); | 616 var element = document.createElement("span"); |
| 525 var table = parameters[0]; | 617 var table = parameters[0]; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 elem.appendChild(document.createTextNode("\"")); | 680 elem.appendChild(document.createTextNode("\"")); |
| 589 }, | 681 }, |
| 590 | 682 |
| 591 /** | 683 /** |
| 592 * @param {!WebInspector.RemoteObject} array | 684 * @param {!WebInspector.RemoteObject} array |
| 593 * @param {!Element} elem | 685 * @param {!Element} elem |
| 594 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | 686 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 595 */ | 687 */ |
| 596 _printArray: function(array, elem, properties) | 688 _printArray: function(array, elem, properties) |
| 597 { | 689 { |
| 598 if (!properties) | 690 if (!properties) { |
| 691 // Fall back to object formatting. | |
| 692 this._formatParameterAsObject(array, elem, false); | |
| 599 return; | 693 return; |
| 694 } | |
| 695 const maxNonIndexElements = 5; | |
| 696 var arrayLength = array.arrayLength(); | |
| 600 | 697 |
| 601 var elements = []; | 698 var elements = []; |
| 699 var nonIndexElements = 0; | |
| 602 for (var i = 0; i < properties.length; ++i) { | 700 for (var i = 0; i < properties.length; ++i) { |
| 603 var property = properties[i]; | 701 var property = properties[i]; |
| 604 var name = property.name; | 702 var name = property.name; |
| 605 if (isNaN(name)) | 703 if (!String.isArrayIndexPropertyName(name, arrayLength)) { |
| 606 continue; | 704 if (name === "length" || !property.enumerable) |
| 705 continue; | |
| 706 if (++nonIndexElements > maxNonIndexElements) | |
| 707 continue; | |
| 708 } | |
| 709 var element = null; | |
| 607 if (property.getter) | 710 if (property.getter) |
| 608 elements[name] = this._formatAsAccessorProperty(array, [name], t rue); | 711 element = this._formatAsAccessorProperty(array, [name], true); |
| 609 else if (property.value) | 712 else if (property.value) |
| 610 elements[name] = this._formatAsArrayEntry(property.value); | 713 element = this._formatAsArrayEntry(property.value); |
| 714 if (element) | |
| 715 elements.push({ name: name, element: element }); | |
| 611 } | 716 } |
| 612 | 717 |
| 613 elem.appendChild(document.createTextNode("[")); | 718 var overflow = (nonIndexElements > maxNonIndexElements); |
| 614 var lastNonEmptyIndex = -1; | 719 this._appendArrayOrObjectPropertyElements(elem, elements, overflow, arra yLength); |
| 615 | |
| 616 function appendUndefined(elem, index) | |
| 617 { | |
| 618 if (index - lastNonEmptyIndex <= 1) | |
| 619 return; | |
| 620 var span = elem.createChild("span", "console-formatted-undefined"); | |
| 621 span.textContent = WebInspector.UIString("undefined × %d", index - l astNonEmptyIndex - 1); | |
| 622 } | |
| 623 | |
| 624 var length = array.arrayLength(); | |
| 625 for (var i = 0; i < length; ++i) { | |
| 626 var element = elements[i]; | |
| 627 if (!element) | |
| 628 continue; | |
| 629 | |
| 630 if (i - lastNonEmptyIndex > 1) { | |
| 631 appendUndefined(elem, i); | |
| 632 elem.appendChild(document.createTextNode(", ")); | |
| 633 } | |
| 634 | |
| 635 elem.appendChild(element); | |
| 636 lastNonEmptyIndex = i; | |
| 637 if (i < length - 1) | |
| 638 elem.appendChild(document.createTextNode(", ")); | |
| 639 } | |
| 640 appendUndefined(elem, length); | |
| 641 | |
| 642 elem.appendChild(document.createTextNode("]")); | |
| 643 }, | 720 }, |
| 644 | 721 |
| 645 /** | 722 /** |
| 646 * @param {!WebInspector.RemoteObject} output | 723 * @param {!WebInspector.RemoteObject} output |
| 647 * @return {!Element} | 724 * @return {!Element} |
| 648 */ | 725 */ |
| 649 _formatAsArrayEntry: function(output) | 726 _formatAsArrayEntry: function(output) |
| 650 { | 727 { |
| 651 // Prevent infinite expansion of cross-referencing arrays. | 728 // Prevent infinite expansion of cross-referencing arrays. |
| 652 return this._formatParameter(output, output.subtype === "array", false); | 729 return this._formatParameter(output, output.subtype === "array", false); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1084 /** | 1161 /** |
| 1085 * @return {!WebInspector.ConsoleMessage} | 1162 * @return {!WebInspector.ConsoleMessage} |
| 1086 */ | 1163 */ |
| 1087 clone: function() | 1164 clone: function() |
| 1088 { | 1165 { |
| 1089 return WebInspector.ConsoleMessage.create(this.source, this.level, this. _messageText, this.type, this.url, this.line, this.column, this.repeatCount, thi s._parameters, this._stackTrace, this._request ? this._request.requestId : undef ined, this._isOutdated); | 1166 return WebInspector.ConsoleMessage.create(this.source, this.level, this. _messageText, this.type, this.url, this.line, this.column, this.repeatCount, thi s._parameters, this._stackTrace, this._request ? this._request.requestId : undef ined, this._isOutdated); |
| 1090 }, | 1167 }, |
| 1091 | 1168 |
| 1092 __proto__: WebInspector.ConsoleMessage.prototype | 1169 __proto__: WebInspector.ConsoleMessage.prototype |
| 1093 } | 1170 } |
| OLD | NEW |