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 |