| Index: Source/devtools/front_end/ConsoleMessage.js
|
| diff --git a/Source/devtools/front_end/ConsoleMessage.js b/Source/devtools/front_end/ConsoleMessage.js
|
| index 2d3500a0b5cc4e0e3cf9dea2774bfc29c5d5e75b..530851f75674fe1266205471e9a6ac3558ef4508 100644
|
| --- a/Source/devtools/front_end/ConsoleMessage.js
|
| +++ b/Source/devtools/front_end/ConsoleMessage.js
|
| @@ -363,7 +363,9 @@ WebInspector.ConsoleMessageImpl.prototype = {
|
| titleElement.createTextChild(description);
|
| if (includePreview && obj.preview) {
|
| titleElement.classList.add("console-object-preview");
|
| - var lossless = this._appendObjectPreview(obj, description, titleElement);
|
| + if (description)
|
| + titleElement.createTextChild(" ");
|
| + var lossless = this._appendObjectPreview(obj, titleElement);
|
| if (lossless) {
|
| elem.appendChild(titleElement);
|
| return;
|
| @@ -379,37 +381,127 @@ WebInspector.ConsoleMessageImpl.prototype = {
|
|
|
| /**
|
| * @param {!WebInspector.RemoteObject} obj
|
| - * @param {string} description
|
| * @param {!Element} titleElement
|
| * @return {boolean} true iff preview captured all information.
|
| */
|
| - _appendObjectPreview: function(obj, description, titleElement)
|
| + _appendObjectPreview: function(obj, titleElement)
|
| {
|
| var preview = obj.preview;
|
| var isArray = obj.subtype === "array";
|
| + var arrayLength = isArray ? obj.arrayLength() : undefined;
|
| + var properties = preview.properties;
|
|
|
| - if (description)
|
| - titleElement.createTextChild(" ");
|
| - titleElement.createTextChild(isArray ? "[" : "{");
|
| - for (var i = 0; i < preview.properties.length; ++i) {
|
| - if (i > 0)
|
| - titleElement.createTextChild(", ");
|
| -
|
| - var property = preview.properties[i];
|
| + var elements = [];
|
| + for (var i = 0; i < properties.length; ++i) {
|
| + var property = properties[i];
|
| var name = property.name;
|
| - if (!isArray || name != i) {
|
| - if (/^\s|\s$|^$|\n/.test(name))
|
| - name = "\"" + name.replace(/\n/g, "\u21B5") + "\"";
|
| - titleElement.createChild("span", "name").textContent = name;
|
| - titleElement.createTextChild(": ");
|
| + elements.push({
|
| + name: name,
|
| + element: this._renderPropertyPreviewOrAccessor(obj, [property])
|
| + });
|
| + }
|
| +
|
| + this._appendArrayOrObjectPropertyElements(titleElement, elements, preview.overflow, arrayLength);
|
| + return preview.lossless;
|
| + },
|
| +
|
| + /**
|
| + * @param {!Element} parent
|
| + * @param {!Array.<{name: string, element: !Element}>} propertyElements
|
| + * @param {boolean} overflow
|
| + * @param {number=} arrayLength
|
| + */
|
| + _appendArrayOrObjectPropertyElements: function(parent, propertyElements, overflow, arrayLength)
|
| + {
|
| + const maxFlatArrayLength = 100;
|
| +
|
| + /**
|
| + * @param {{name: string, element: !Element}} a
|
| + * @param {{name: string, element: !Element}} b
|
| + * @return {number}
|
| + */
|
| + function comparator(a, b)
|
| + {
|
| + var isIndex1 = String.isArrayIndexPropertyName(a.name, arrayLength);
|
| + var isIndex2 = String.isArrayIndexPropertyName(b.name, arrayLength);
|
| + if (isIndex1 && isIndex2)
|
| + return Number(a.name) - Number(b.name);
|
| + if (isIndex1)
|
| + return -1;
|
| + if (isIndex2)
|
| + return 1;
|
| + return 0;
|
| + }
|
| +
|
| + var isArray = typeof arrayLength === "number";
|
| + if (isArray)
|
| + propertyElements.stableSort(comparator);
|
| + var isFlatArray = isArray && (arrayLength <= maxFlatArrayLength);
|
| +
|
| + parent.createTextChild(isArray ? "[" : "{");
|
| + var firstElement = true;
|
| + var lastNonEmptyArrayIndex = -1;
|
| +
|
| + function appendCommaIfNeeded()
|
| + {
|
| + if (firstElement)
|
| + firstElement = false;
|
| + else
|
| + parent.createTextChild(", ");
|
| + }
|
| +
|
| + /**
|
| + * @param {number=} index
|
| + */
|
| + function appendUndefinedArrayElements(index)
|
| + {
|
| + if (typeof index !== "number")
|
| + return;
|
| + var undefinedRange = index - lastNonEmptyArrayIndex - 1;
|
| + lastNonEmptyArrayIndex = index;
|
| + if (undefinedRange < 1)
|
| + return;
|
| + appendCommaIfNeeded();
|
| + var span = parent.createChild("span", "console-formatted-undefined");
|
| + span.textContent = WebInspector.UIString("undefined × %d", undefinedRange);
|
| + }
|
| +
|
| + /**
|
| + * @param {string} name
|
| + */
|
| + function appendPropertyName(name)
|
| + {
|
| + if (/^\s|\s$|^$|\n/.test(name))
|
| + name = "\"" + name.replace(/\n/g, "\u21B5") + "\"";
|
| + parent.createChild("span", "name").textContent = name;
|
| + parent.createTextChild(": ");
|
| + }
|
| +
|
| + for (var i = 0, n = propertyElements.length; i < n; ++i) {
|
| + var name = propertyElements[i].name;
|
| + var element = propertyElements[i].element;
|
| + var isIndex = String.isArrayIndexPropertyName(name, arrayLength);
|
| + var index = isIndex ? Number(name) : 0;
|
| +
|
| + if (isFlatArray) {
|
| + appendUndefinedArrayElements(isIndex ? index : arrayLength);
|
| + appendCommaIfNeeded();
|
| + if (!isIndex)
|
| + appendPropertyName(name);
|
| + } else {
|
| + appendCommaIfNeeded();
|
| + if (!isArray || !isIndex || index !== i)
|
| + appendPropertyName(name);
|
| }
|
|
|
| - titleElement.appendChild(this._renderPropertyPreviewOrAccessor(obj, [property]));
|
| + parent.appendChild(element);
|
| }
|
| - if (preview.overflow)
|
| - titleElement.createChild("span").textContent = "\u2026";
|
| - titleElement.createTextChild(isArray ? "]" : "}");
|
| - return preview.lossless;
|
| + if (isFlatArray)
|
| + appendUndefinedArrayElements(arrayLength);
|
| +
|
| + if (overflow)
|
| + parent.createChild("span").textContent = "\u2026";
|
| + parent.createTextChild(isArray ? "]" : "}");
|
| },
|
|
|
| /**
|
| @@ -510,7 +602,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
|
| if (this._isOutdated || array.arrayLength() > maxFlatArrayLength)
|
| this._formatParameterAsObject(array, elem, false);
|
| else
|
| - array.getOwnProperties(this._printArray.bind(this, array, elem));
|
| + array.getAllProperties(false, this._printArray.bind(this, array, elem));
|
| },
|
|
|
| /**
|
| @@ -593,51 +685,36 @@ WebInspector.ConsoleMessageImpl.prototype = {
|
| */
|
| _printArray: function(array, elem, properties)
|
| {
|
| - if (!properties)
|
| + if (!properties) {
|
| + // Fall back to object formatting.
|
| + this._formatParameterAsObject(array, elem, false);
|
| return;
|
| + }
|
| + const maxNonIndexElements = 5;
|
| + var arrayLength = array.arrayLength();
|
|
|
| var elements = [];
|
| + var nonIndexElements = 0;
|
| for (var i = 0; i < properties.length; ++i) {
|
| var property = properties[i];
|
| var name = property.name;
|
| - if (isNaN(name))
|
| - continue;
|
| + if (!String.isArrayIndexPropertyName(name, arrayLength)) {
|
| + if (name === "length" || !property.enumerable)
|
| + continue;
|
| + if (++nonIndexElements > maxNonIndexElements)
|
| + continue;
|
| + }
|
| + var element = null;
|
| if (property.getter)
|
| - elements[name] = this._formatAsAccessorProperty(array, [name], true);
|
| + element = this._formatAsAccessorProperty(array, [name], true);
|
| else if (property.value)
|
| - elements[name] = this._formatAsArrayEntry(property.value);
|
| - }
|
| -
|
| - elem.appendChild(document.createTextNode("["));
|
| - var lastNonEmptyIndex = -1;
|
| -
|
| - function appendUndefined(elem, index)
|
| - {
|
| - if (index - lastNonEmptyIndex <= 1)
|
| - return;
|
| - var span = elem.createChild("span", "console-formatted-undefined");
|
| - span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
|
| - }
|
| -
|
| - var length = array.arrayLength();
|
| - for (var i = 0; i < length; ++i) {
|
| - var element = elements[i];
|
| - if (!element)
|
| - continue;
|
| -
|
| - if (i - lastNonEmptyIndex > 1) {
|
| - appendUndefined(elem, i);
|
| - elem.appendChild(document.createTextNode(", "));
|
| - }
|
| -
|
| - elem.appendChild(element);
|
| - lastNonEmptyIndex = i;
|
| - if (i < length - 1)
|
| - elem.appendChild(document.createTextNode(", "));
|
| + element = this._formatAsArrayEntry(property.value);
|
| + if (element)
|
| + elements.push({ name: name, element: element });
|
| }
|
| - appendUndefined(elem, length);
|
|
|
| - elem.appendChild(document.createTextNode("]"));
|
| + var overflow = (nonIndexElements > maxNonIndexElements);
|
| + this._appendArrayOrObjectPropertyElements(elem, elements, overflow, arrayLength);
|
| },
|
|
|
| /**
|
|
|