| 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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 * @param {!Element} elem | 359 * @param {!Element} elem |
| 360 * @param {boolean} includePreview | 360 * @param {boolean} includePreview |
| 361 */ | 361 */ |
| 362 _formatParameterAsArrayOrObject: function(obj, description, elem, includePre
view) | 362 _formatParameterAsArrayOrObject: function(obj, description, elem, includePre
view) |
| 363 { | 363 { |
| 364 var titleElement = document.createElement("span"); | 364 var titleElement = document.createElement("span"); |
| 365 if (description) | 365 if (description) |
| 366 titleElement.createTextChild(description); | 366 titleElement.createTextChild(description); |
| 367 if (includePreview && obj.preview) { | 367 if (includePreview && obj.preview) { |
| 368 titleElement.classList.add("console-object-preview"); | 368 titleElement.classList.add("console-object-preview"); |
| 369 if (description) | 369 var lossless = this._appendObjectPreview(obj, description, titleElem
ent); |
| 370 titleElement.createTextChild(" "); | |
| 371 var lossless = this._appendObjectPreview(obj, titleElement); | |
| 372 if (lossless) { | 370 if (lossless) { |
| 373 elem.appendChild(titleElement); | 371 elem.appendChild(titleElement); |
| 374 return; | 372 return; |
| 375 } | 373 } |
| 376 } | 374 } |
| 377 var section = new WebInspector.ObjectPropertiesSection(obj, titleElement
); | 375 var section = new WebInspector.ObjectPropertiesSection(obj, titleElement
); |
| 378 section.enableContextMenu(); | 376 section.enableContextMenu(); |
| 379 elem.appendChild(section.element); | 377 elem.appendChild(section.element); |
| 380 | 378 |
| 381 var note = section.titleElement.createChild("span", "object-info-state-n
ote"); | 379 var note = section.titleElement.createChild("span", "object-info-state-n
ote"); |
| 382 note.title = WebInspector.UIString("Object state below is captured upon
first expansion"); | 380 note.title = WebInspector.UIString("Object state below is captured upon
first expansion"); |
| 383 }, | 381 }, |
| 384 | 382 |
| 385 /** | 383 /** |
| 386 * @param {!WebInspector.RemoteObject} obj | 384 * @param {!WebInspector.RemoteObject} obj |
| 385 * @param {string} description |
| 387 * @param {!Element} titleElement | 386 * @param {!Element} titleElement |
| 388 * @return {boolean} true iff preview captured all information. | 387 * @return {boolean} true iff preview captured all information. |
| 389 */ | 388 */ |
| 390 _appendObjectPreview: function(obj, titleElement) | 389 _appendObjectPreview: function(obj, description, titleElement) |
| 391 { | 390 { |
| 392 var preview = obj.preview; | 391 var preview = obj.preview; |
| 393 var isArray = obj.subtype === "array"; | 392 var isArray = obj.subtype === "array"; |
| 394 var arrayLength = isArray ? obj.arrayLength() : undefined; | |
| 395 var properties = preview.properties; | |
| 396 | 393 |
| 397 var elements = []; | 394 if (description) |
| 398 for (var i = 0; i < properties.length; ++i) { | 395 titleElement.createTextChild(" "); |
| 399 var property = properties[i]; | 396 titleElement.createTextChild(isArray ? "[" : "{"); |
| 397 for (var i = 0; i < preview.properties.length; ++i) { |
| 398 if (i > 0) |
| 399 titleElement.createTextChild(", "); |
| 400 |
| 401 var property = preview.properties[i]; |
| 400 var name = property.name; | 402 var name = property.name; |
| 401 elements.push({ | 403 if (!isArray || name != i) { |
| 402 name: name, | 404 if (/^\s|\s$|^$|\n/.test(name)) |
| 403 element: this._renderPropertyPreviewOrAccessor(obj, [property]) | 405 name = "\"" + name.replace(/\n/g, "\u21B5") + "\""; |
| 404 }); | 406 titleElement.createChild("span", "name").textContent = name; |
| 407 titleElement.createTextChild(": "); |
| 408 } |
| 409 |
| 410 titleElement.appendChild(this._renderPropertyPreviewOrAccessor(obj,
[property])); |
| 405 } | 411 } |
| 406 | 412 if (preview.overflow) |
| 407 this._appendArrayOrObjectPropertyElements(titleElement, elements, previe
w.overflow, arrayLength); | 413 titleElement.createChild("span").textContent = "\u2026"; |
| 414 titleElement.createTextChild(isArray ? "]" : "}"); |
| 408 return preview.lossless; | 415 return preview.lossless; |
| 409 }, | 416 }, |
| 410 | 417 |
| 411 /** | 418 /** |
| 412 * @param {!Element} parent | |
| 413 * @param {!Array.<{name: string, element: !Element}>} propertyElements | |
| 414 * @param {boolean} overflow | |
| 415 * @param {number=} arrayLength | |
| 416 */ | |
| 417 _appendArrayOrObjectPropertyElements: function(parent, propertyElements, ove
rflow, arrayLength) | |
| 418 { | |
| 419 const maxFlatArrayLength = 100; | |
| 420 | |
| 421 /** | |
| 422 * @param {{name: string, element: !Element}} a | |
| 423 * @param {{name: string, element: !Element}} b | |
| 424 * @return {number} | |
| 425 */ | |
| 426 function comparator(a, b) | |
| 427 { | |
| 428 var isIndex1 = String.isArrayIndexPropertyName(a.name, arrayLength); | |
| 429 var isIndex2 = String.isArrayIndexPropertyName(b.name, arrayLength); | |
| 430 if (isIndex1 && isIndex2) | |
| 431 return Number(a.name) - Number(b.name); | |
| 432 if (isIndex1) | |
| 433 return -1; | |
| 434 if (isIndex2) | |
| 435 return 1; | |
| 436 return 0; | |
| 437 } | |
| 438 | |
| 439 var isArray = typeof arrayLength === "number"; | |
| 440 if (isArray) | |
| 441 propertyElements.stableSort(comparator); | |
| 442 var isFlatArray = isArray && (arrayLength <= maxFlatArrayLength); | |
| 443 | |
| 444 parent.createTextChild(isArray ? "[" : "{"); | |
| 445 var firstElement = true; | |
| 446 var lastNonEmptyArrayIndex = -1; | |
| 447 | |
| 448 function appendCommaIfNeeded() | |
| 449 { | |
| 450 if (firstElement) | |
| 451 firstElement = false; | |
| 452 else | |
| 453 parent.createTextChild(", "); | |
| 454 } | |
| 455 | |
| 456 /** | |
| 457 * @param {number=} index | |
| 458 */ | |
| 459 function appendUndefinedArrayElements(index) | |
| 460 { | |
| 461 if (typeof index !== "number") | |
| 462 return; | |
| 463 var undefinedRange = index - lastNonEmptyArrayIndex - 1; | |
| 464 lastNonEmptyArrayIndex = index; | |
| 465 if (undefinedRange < 1) | |
| 466 return; | |
| 467 appendCommaIfNeeded(); | |
| 468 var span = parent.createChild("span", "console-formatted-undefined")
; | |
| 469 span.textContent = WebInspector.UIString("undefined × %d", undefined
Range); | |
| 470 } | |
| 471 | |
| 472 /** | |
| 473 * @param {string} name | |
| 474 */ | |
| 475 function appendPropertyName(name) | |
| 476 { | |
| 477 if (/^\s|\s$|^$|\n/.test(name)) | |
| 478 name = "\"" + name.replace(/\n/g, "\u21B5") + "\""; | |
| 479 parent.createChild("span", "name").textContent = name; | |
| 480 parent.createTextChild(": "); | |
| 481 } | |
| 482 | |
| 483 for (var i = 0, n = propertyElements.length; i < n; ++i) { | |
| 484 var name = propertyElements[i].name; | |
| 485 var element = propertyElements[i].element; | |
| 486 var isIndex = String.isArrayIndexPropertyName(name, arrayLength); | |
| 487 var index = isIndex ? Number(name) : 0; | |
| 488 | |
| 489 if (isFlatArray) { | |
| 490 appendUndefinedArrayElements(isIndex ? index : arrayLength); | |
| 491 appendCommaIfNeeded(); | |
| 492 if (!isIndex) | |
| 493 appendPropertyName(name); | |
| 494 } else { | |
| 495 appendCommaIfNeeded(); | |
| 496 if (!isArray || !isIndex || index !== i) | |
| 497 appendPropertyName(name); | |
| 498 } | |
| 499 | |
| 500 parent.appendChild(element); | |
| 501 } | |
| 502 if (isFlatArray) | |
| 503 appendUndefinedArrayElements(arrayLength); | |
| 504 | |
| 505 if (overflow) | |
| 506 parent.createChild("span").textContent = "\u2026"; | |
| 507 parent.createTextChild(isArray ? "]" : "}"); | |
| 508 }, | |
| 509 | |
| 510 /** | |
| 511 * @param {!WebInspector.RemoteObject} object | 419 * @param {!WebInspector.RemoteObject} object |
| 512 * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath | 420 * @param {!Array.<!RuntimeAgent.PropertyPreview>} propertyPath |
| 513 * @return {!Element} | 421 * @return {!Element} |
| 514 */ | 422 */ |
| 515 _renderPropertyPreviewOrAccessor: function(object, propertyPath) | 423 _renderPropertyPreviewOrAccessor: function(object, propertyPath) |
| 516 { | 424 { |
| 517 var property = propertyPath.peekLast(); | 425 var property = propertyPath.peekLast(); |
| 518 if (property.type === "accessor") | 426 if (property.type === "accessor") |
| 519 return this._formatAsAccessorProperty(object, propertyPath.select("n
ame"), false); | 427 return this._formatAsAccessorProperty(object, propertyPath.select("n
ame"), false); |
| 520 return this._renderPropertyPreview(property.type, /** @type {string} */
(property.subtype), property.value); | 428 return this._renderPropertyPreview(property.type, /** @type {string} */
(property.subtype), property.value); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 { | 506 { |
| 599 if (this.useArrayPreviewInFormatter(array)) { | 507 if (this.useArrayPreviewInFormatter(array)) { |
| 600 this._formatParameterAsArrayOrObject(array, "", elem, true); | 508 this._formatParameterAsArrayOrObject(array, "", elem, true); |
| 601 return; | 509 return; |
| 602 } | 510 } |
| 603 | 511 |
| 604 const maxFlatArrayLength = 100; | 512 const maxFlatArrayLength = 100; |
| 605 if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) | 513 if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) |
| 606 this._formatParameterAsObject(array, elem, false); | 514 this._formatParameterAsObject(array, elem, false); |
| 607 else | 515 else |
| 608 array.getAllProperties(false, this._printArray.bind(this, array, ele
m)); | 516 array.getOwnProperties(this._printArray.bind(this, array, elem)); |
| 609 }, | 517 }, |
| 610 | 518 |
| 611 /** | 519 /** |
| 612 * @param {!Array.<!WebInspector.RemoteObject>} parameters | 520 * @param {!Array.<!WebInspector.RemoteObject>} parameters |
| 613 * @return {!Element} | 521 * @return {!Element} |
| 614 */ | 522 */ |
| 615 _formatParameterAsTable: function(parameters) | 523 _formatParameterAsTable: function(parameters) |
| 616 { | 524 { |
| 617 var element = document.createElement("span"); | 525 var element = document.createElement("span"); |
| 618 var table = parameters[0]; | 526 var table = parameters[0]; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 elem.appendChild(document.createTextNode("\"")); | 589 elem.appendChild(document.createTextNode("\"")); |
| 682 }, | 590 }, |
| 683 | 591 |
| 684 /** | 592 /** |
| 685 * @param {!WebInspector.RemoteObject} array | 593 * @param {!WebInspector.RemoteObject} array |
| 686 * @param {!Element} elem | 594 * @param {!Element} elem |
| 687 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | 595 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 688 */ | 596 */ |
| 689 _printArray: function(array, elem, properties) | 597 _printArray: function(array, elem, properties) |
| 690 { | 598 { |
| 691 if (!properties) { | 599 if (!properties) |
| 692 // Fall back to object formatting. | |
| 693 this._formatParameterAsObject(array, elem, false); | |
| 694 return; | 600 return; |
| 695 } | |
| 696 const maxNonIndexElements = 5; | |
| 697 var arrayLength = array.arrayLength(); | |
| 698 | 601 |
| 699 var elements = []; | 602 var elements = []; |
| 700 var nonIndexElements = 0; | |
| 701 for (var i = 0; i < properties.length; ++i) { | 603 for (var i = 0; i < properties.length; ++i) { |
| 702 var property = properties[i]; | 604 var property = properties[i]; |
| 703 var name = property.name; | 605 var name = property.name; |
| 704 if (!String.isArrayIndexPropertyName(name, arrayLength)) { | 606 if (isNaN(name)) |
| 705 if (name === "length" || !property.enumerable) | 607 continue; |
| 706 continue; | |
| 707 if (++nonIndexElements > maxNonIndexElements) | |
| 708 continue; | |
| 709 } | |
| 710 var element = null; | |
| 711 if (property.getter) | 608 if (property.getter) |
| 712 element = this._formatAsAccessorProperty(array, [name], true); | 609 elements[name] = this._formatAsAccessorProperty(array, [name], t
rue); |
| 713 else if (property.value) | 610 else if (property.value) |
| 714 element = this._formatAsArrayEntry(property.value); | 611 elements[name] = this._formatAsArrayEntry(property.value); |
| 715 if (element) | |
| 716 elements.push({ name: name, element: element }); | |
| 717 } | 612 } |
| 718 | 613 |
| 719 var overflow = (nonIndexElements > maxNonIndexElements); | 614 elem.appendChild(document.createTextNode("[")); |
| 720 this._appendArrayOrObjectPropertyElements(elem, elements, overflow, arra
yLength); | 615 var lastNonEmptyIndex = -1; |
| 616 |
| 617 function appendUndefined(elem, index) |
| 618 { |
| 619 if (index - lastNonEmptyIndex <= 1) |
| 620 return; |
| 621 var span = elem.createChild("span", "console-formatted-undefined"); |
| 622 span.textContent = WebInspector.UIString("undefined × %d", index - l
astNonEmptyIndex - 1); |
| 623 } |
| 624 |
| 625 var length = array.arrayLength(); |
| 626 for (var i = 0; i < length; ++i) { |
| 627 var element = elements[i]; |
| 628 if (!element) |
| 629 continue; |
| 630 |
| 631 if (i - lastNonEmptyIndex > 1) { |
| 632 appendUndefined(elem, i); |
| 633 elem.appendChild(document.createTextNode(", ")); |
| 634 } |
| 635 |
| 636 elem.appendChild(element); |
| 637 lastNonEmptyIndex = i; |
| 638 if (i < length - 1) |
| 639 elem.appendChild(document.createTextNode(", ")); |
| 640 } |
| 641 appendUndefined(elem, length); |
| 642 |
| 643 elem.appendChild(document.createTextNode("]")); |
| 721 }, | 644 }, |
| 722 | 645 |
| 723 /** | 646 /** |
| 724 * @param {!WebInspector.RemoteObject} output | 647 * @param {!WebInspector.RemoteObject} output |
| 725 * @return {!Element} | 648 * @return {!Element} |
| 726 */ | 649 */ |
| 727 _formatAsArrayEntry: function(output) | 650 _formatAsArrayEntry: function(output) |
| 728 { | 651 { |
| 729 // Prevent infinite expansion of cross-referencing arrays. | 652 // Prevent infinite expansion of cross-referencing arrays. |
| 730 return this._formatParameter(output, output.subtype === "array", false); | 653 return this._formatParameter(output, output.subtype === "array", false); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 /** | 1085 /** |
| 1163 * @return {!WebInspector.ConsoleMessage} | 1086 * @return {!WebInspector.ConsoleMessage} |
| 1164 */ | 1087 */ |
| 1165 clone: function() | 1088 clone: function() |
| 1166 { | 1089 { |
| 1167 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 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); |
| 1168 }, | 1091 }, |
| 1169 | 1092 |
| 1170 __proto__: WebInspector.ConsoleMessage.prototype | 1093 __proto__: WebInspector.ConsoleMessage.prototype |
| 1171 } | 1094 } |
| OLD | NEW |