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) |
| 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); |
| 439 var isFlatArray = isArray && (arrayLength <= maxFlatArrayLength); |
| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 { | 595 { |
504 if (this.useArrayPreviewInFormatter(array)) { | 596 if (this.useArrayPreviewInFormatter(array)) { |
505 this._formatParameterAsArrayOrObject(array, "", elem, true); | 597 this._formatParameterAsArrayOrObject(array, "", elem, true); |
506 return; | 598 return; |
507 } | 599 } |
508 | 600 |
509 const maxFlatArrayLength = 100; | 601 const maxFlatArrayLength = 100; |
510 if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) | 602 if (this._isOutdated || array.arrayLength() > maxFlatArrayLength) |
511 this._formatParameterAsObject(array, elem, false); | 603 this._formatParameterAsObject(array, elem, false); |
512 else | 604 else |
513 array.getOwnProperties(this._printArray.bind(this, array, elem)); | 605 array.getAllProperties(false, this._printArray.bind(this, array, ele
m)); |
514 }, | 606 }, |
515 | 607 |
516 /** | 608 /** |
517 * @param {!Array.<!WebInspector.RemoteObject>} parameters | 609 * @param {!Array.<!WebInspector.RemoteObject>} parameters |
518 * @return {!Element} | 610 * @return {!Element} |
519 */ | 611 */ |
520 _formatParameterAsTable: function(parameters) | 612 _formatParameterAsTable: function(parameters) |
521 { | 613 { |
522 var element = document.createElement("span"); | 614 var element = document.createElement("span"); |
523 var table = parameters[0]; | 615 var table = parameters[0]; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 elem.appendChild(document.createTextNode("\"")); | 678 elem.appendChild(document.createTextNode("\"")); |
587 }, | 679 }, |
588 | 680 |
589 /** | 681 /** |
590 * @param {!WebInspector.RemoteObject} array | 682 * @param {!WebInspector.RemoteObject} array |
591 * @param {!Element} elem | 683 * @param {!Element} elem |
592 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | 684 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
593 */ | 685 */ |
594 _printArray: function(array, elem, properties) | 686 _printArray: function(array, elem, properties) |
595 { | 687 { |
596 if (!properties) | 688 if (!properties) { |
| 689 // Fall back to object formatting. |
| 690 this._formatParameterAsObject(array, elem, false); |
597 return; | 691 return; |
| 692 } |
| 693 const maxNonIndexElements = 5; |
| 694 var arrayLength = array.arrayLength(); |
598 | 695 |
599 var elements = []; | 696 var elements = []; |
| 697 var nonIndexElements = 0; |
600 for (var i = 0; i < properties.length; ++i) { | 698 for (var i = 0; i < properties.length; ++i) { |
601 var property = properties[i]; | 699 var property = properties[i]; |
602 var name = property.name; | 700 var name = property.name; |
603 if (isNaN(name)) | 701 if (!String.isArrayIndexPropertyName(name, arrayLength)) { |
604 continue; | 702 if (name === "length" || !property.enumerable) |
| 703 continue; |
| 704 if (++nonIndexElements > maxNonIndexElements) |
| 705 continue; |
| 706 } |
| 707 var element = null; |
605 if (property.getter) | 708 if (property.getter) |
606 elements[name] = this._formatAsAccessorProperty(array, [name], t
rue); | 709 element = this._formatAsAccessorProperty(array, [name], true); |
607 else if (property.value) | 710 else if (property.value) |
608 elements[name] = this._formatAsArrayEntry(property.value); | 711 element = this._formatAsArrayEntry(property.value); |
| 712 if (element) |
| 713 elements.push({ name: name, element: element }); |
609 } | 714 } |
610 | 715 |
611 elem.appendChild(document.createTextNode("[")); | 716 var overflow = (nonIndexElements > maxNonIndexElements); |
612 var lastNonEmptyIndex = -1; | 717 this._appendArrayOrObjectPropertyElements(elem, elements, overflow, arra
yLength); |
613 | |
614 function appendUndefined(elem, index) | |
615 { | |
616 if (index - lastNonEmptyIndex <= 1) | |
617 return; | |
618 var span = elem.createChild("span", "console-formatted-undefined"); | |
619 span.textContent = WebInspector.UIString("undefined × %d", index - l
astNonEmptyIndex - 1); | |
620 } | |
621 | |
622 var length = array.arrayLength(); | |
623 for (var i = 0; i < length; ++i) { | |
624 var element = elements[i]; | |
625 if (!element) | |
626 continue; | |
627 | |
628 if (i - lastNonEmptyIndex > 1) { | |
629 appendUndefined(elem, i); | |
630 elem.appendChild(document.createTextNode(", ")); | |
631 } | |
632 | |
633 elem.appendChild(element); | |
634 lastNonEmptyIndex = i; | |
635 if (i < length - 1) | |
636 elem.appendChild(document.createTextNode(", ")); | |
637 } | |
638 appendUndefined(elem, length); | |
639 | |
640 elem.appendChild(document.createTextNode("]")); | |
641 }, | 718 }, |
642 | 719 |
643 /** | 720 /** |
644 * @param {!WebInspector.RemoteObject} output | 721 * @param {!WebInspector.RemoteObject} output |
645 * @return {!Element} | 722 * @return {!Element} |
646 */ | 723 */ |
647 _formatAsArrayEntry: function(output) | 724 _formatAsArrayEntry: function(output) |
648 { | 725 { |
649 // Prevent infinite expansion of cross-referencing arrays. | 726 // Prevent infinite expansion of cross-referencing arrays. |
650 return this._formatParameter(output, output.subtype === "array", false); | 727 return this._formatParameter(output, output.subtype === "array", false); |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 /** | 1159 /** |
1083 * @return {!WebInspector.ConsoleMessage} | 1160 * @return {!WebInspector.ConsoleMessage} |
1084 */ | 1161 */ |
1085 clone: function() | 1162 clone: function() |
1086 { | 1163 { |
1087 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); | 1164 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); |
1088 }, | 1165 }, |
1089 | 1166 |
1090 __proto__: WebInspector.ConsoleMessage.prototype | 1167 __proto__: WebInspector.ConsoleMessage.prototype |
1091 } | 1168 } |
OLD | NEW |