Files
react-native-devtools-frontend/front_end/object_ui/RemoteObjectPreviewFormatter.js
T
Blink Reformat 4c46d0969f The Great Blink mv for source files, part 2.
Move and rename files.

NOAUTOREVERT=true
NOPRESUBMIT=true
NOTREECHECKS=true
Bug: 768828
TBR=darin@chromium.org
NOTRY=true

Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28
Reviewed-on: https://chromium-review.googlesource.com/1001153
Reviewed-by: Blink Reformat <blink-reformat@chromium.org>
Commit-Queue: Blink Reformat <blink-reformat@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#549061}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
2018-04-07 15:32:37 +00:00

310 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @unrestricted
*/
ObjectUI.RemoteObjectPreviewFormatter = class {
/**
* @param {!Protocol.Runtime.PropertyPreview} a
* @param {!Protocol.Runtime.PropertyPreview} b
* @return {number}
*/
static _objectPropertyComparator(a, b) {
return sortValue(a) - sortValue(b);
/**
* @param {!Protocol.Runtime.PropertyPreview} property
* @return {number}
*/
function sortValue(property) {
const internalName = ObjectUI.RemoteObjectPreviewFormatter._internalName;
if (property.name === internalName.PromiseStatus)
return 1;
else if (property.name === internalName.PromiseValue)
return 2;
else if (property.name === internalName.GeneratorStatus || internalName.PrimitiveValue)
return 3;
else if (property.type !== 'function')
return 4;
return 5;
}
}
/**
* @param {!Element} parentElement
* @param {!Protocol.Runtime.ObjectPreview} preview
* @param {boolean} isEntry
*/
appendObjectPreview(parentElement, preview, isEntry) {
const description = preview.description;
const subTypesWithoutValuePreview = new Set(['null', 'regexp', 'error', 'internal#entry']);
if (preview.type !== 'object' || subTypesWithoutValuePreview.has(preview.subtype) || isEntry) {
parentElement.appendChild(this.renderPropertyPreview(preview.type, preview.subtype, description));
return;
}
const isArrayOrTypedArray = preview.subtype === 'array' || preview.subtype === 'typedarray';
if (description) {
let text;
if (isArrayOrTypedArray) {
const arrayLength = SDK.RemoteObject.arrayLength(preview);
const arrayLengthText = arrayLength > 1 ? ('(' + arrayLength + ')') : '';
const arrayName = SDK.RemoteObject.arrayNameFromDescription(description);
text = arrayName === 'Array' ? arrayLengthText : (arrayName + arrayLengthText);
} else {
const hideDescription = description === 'Object';
text = hideDescription ? '' : description;
}
if (text.length > 0)
parentElement.createChild('span', 'object-description').textContent = text + '\u00a0';
}
const propertiesElement = parentElement.createChild('span', 'object-properties-preview');
propertiesElement.createTextChild(isArrayOrTypedArray ? '[' : '{');
if (preview.entries)
this._appendEntriesPreview(propertiesElement, preview);
else if (isArrayOrTypedArray)
this._appendArrayPropertiesPreview(propertiesElement, preview);
else
this._appendObjectPropertiesPreview(propertiesElement, preview);
if (preview.overflow) {
const ellipsisText = propertiesElement.textContent.length > 1 ? ',\u00a0\u2026' : '\u2026';
propertiesElement.createChild('span').textContent = ellipsisText;
}
propertiesElement.createTextChild(isArrayOrTypedArray ? ']' : '}');
}
/**
* @param {string} description
* @return {string}
*/
_abbreviateFullQualifiedClassName(description) {
const abbreviatedDescription = description.split('.');
for (let i = 0; i < abbreviatedDescription.length - 1; ++i)
abbreviatedDescription[i] = abbreviatedDescription[i].trimMiddle(3);
return abbreviatedDescription.join('.');
}
/**
* @param {!Element} parentElement
* @param {!Protocol.Runtime.ObjectPreview} preview
*/
_appendObjectPropertiesPreview(parentElement, preview) {
const internalName = ObjectUI.RemoteObjectPreviewFormatter._internalName;
const properties = preview.properties.filter(p => p.type !== 'accessor')
.stableSort(ObjectUI.RemoteObjectPreviewFormatter._objectPropertyComparator);
for (let i = 0; i < properties.length; ++i) {
if (i > 0)
parentElement.createTextChild(', ');
const property = properties[i];
const name = property.name;
// Internal properties are given special formatting, e.g. Promises `<rejected>: 123`.
if (preview.subtype === 'promise' && name === internalName.PromiseStatus) {
parentElement.appendChild(this._renderDisplayName('<' + property.value + '>'));
const nextProperty = i + 1 < properties.length ? properties[i + 1] : null;
if (nextProperty && nextProperty.name === internalName.PromiseValue) {
if (property.value !== 'pending') {
parentElement.createTextChild(': ');
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([nextProperty]));
}
i++;
}
} else if (preview.subtype === 'generator' && name === internalName.GeneratorStatus) {
parentElement.appendChild(this._renderDisplayName('<' + property.value + '>'));
} else if (name === internalName.PrimitiveValue) {
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
} else {
parentElement.appendChild(this._renderDisplayName(name));
parentElement.createTextChild(': ');
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
}
}
}
/**
* @param {!Element} parentElement
* @param {!Protocol.Runtime.ObjectPreview} preview
*/
_appendArrayPropertiesPreview(parentElement, preview) {
const arrayLength = SDK.RemoteObject.arrayLength(preview);
const indexProperties =
preview.properties.filter(p => toArrayIndex(p.name) !== -1).stableSort(arrayEntryComparator);
const otherProperties = preview.properties.filter(p => toArrayIndex(p.name) === -1)
.stableSort(ObjectUI.RemoteObjectPreviewFormatter._objectPropertyComparator);
/**
* @param {!Protocol.Runtime.PropertyPreview} a
* @param {!Protocol.Runtime.PropertyPreview} b
* @return {number}
*/
function arrayEntryComparator(a, b) {
return toArrayIndex(a.name) - toArrayIndex(b.name);
}
/**
* @param {string} name
* @return {number}
*/
function toArrayIndex(name) {
const index = name >>> 0;
if (String(index) === name && index < arrayLength)
return index;
return -1;
}
// Gaps can be shown when all properties are guaranteed to be in the preview.
const canShowGaps = !preview.overflow;
let lastNonEmptyArrayIndex = -1;
let elementsAdded = false;
for (let i = 0; i < indexProperties.length; ++i) {
if (elementsAdded)
parentElement.createTextChild(', ');
const property = indexProperties[i];
const index = toArrayIndex(property.name);
if (canShowGaps && index - lastNonEmptyArrayIndex > 1) {
appendUndefined(index);
parentElement.createTextChild(', ');
}
if (!canShowGaps && i !== index) {
parentElement.appendChild(this._renderDisplayName(property.name));
parentElement.createTextChild(': ');
}
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
lastNonEmptyArrayIndex = index;
elementsAdded = true;
}
if (canShowGaps && arrayLength - lastNonEmptyArrayIndex > 1) {
if (elementsAdded)
parentElement.createTextChild(', ');
appendUndefined(arrayLength);
}
for (let i = 0; i < otherProperties.length; ++i) {
if (elementsAdded)
parentElement.createTextChild(', ');
const property = otherProperties[i];
parentElement.appendChild(this._renderDisplayName(property.name));
parentElement.createTextChild(': ');
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));
elementsAdded = true;
}
/**
* @param {number} index
*/
function appendUndefined(index) {
const span = parentElement.createChild('span', 'object-value-undefined');
const count = index - lastNonEmptyArrayIndex - 1;
span.textContent = count !== 1 ? Common.UIString('empty × %d', count) : Common.UIString('empty');
elementsAdded = true;
}
}
/**
* @param {!Element} parentElement
* @param {!Protocol.Runtime.ObjectPreview} preview
*/
_appendEntriesPreview(parentElement, preview) {
for (let i = 0; i < preview.entries.length; ++i) {
if (i > 0)
parentElement.createTextChild(', ');
const entry = preview.entries[i];
if (entry.key) {
this.appendObjectPreview(parentElement, entry.key, true /* isEntry */);
parentElement.createTextChild(' => ');
}
this.appendObjectPreview(parentElement, entry.value, true /* isEntry */);
}
}
/**
* @param {string} name
* @return {!Element}
*/
_renderDisplayName(name) {
const result = createElementWithClass('span', 'name');
const needsQuotes = /^\s|\s$|^$|\n/.test(name);
result.textContent = needsQuotes ? '"' + name.replace(/\n/g, '\u21B5') + '"' : name;
return result;
}
/**
* @param {!Array.<!Protocol.Runtime.PropertyPreview>} propertyPath
* @return {!Element}
*/
_renderPropertyPreviewOrAccessor(propertyPath) {
const property = propertyPath.peekLast();
return this.renderPropertyPreview(property.type, /** @type {string} */ (property.subtype), property.value);
}
/**
* @param {string} type
* @param {string=} subtype
* @param {string=} description
* @return {!Element}
*/
renderPropertyPreview(type, subtype, description) {
const span = createElementWithClass('span', 'object-value-' + (subtype || type));
description = description || '';
if (type === 'accessor') {
span.textContent = '(...)';
span.title = Common.UIString('The property is computed with a getter');
return span;
}
if (type === 'function') {
span.textContent = '\u0192';
return span;
}
if (type === 'object' && subtype === 'node' && description) {
ObjectUI.RemoteObjectPreviewFormatter.createSpansForNodeTitle(span, description);
return span;
}
if (type === 'string') {
span.createTextChildren('"', description.replace(/\n/g, '\u21B5'), '"');
return span;
}
if (type === 'object' && !subtype) {
let preview = this._abbreviateFullQualifiedClassName(description);
if (preview === 'Object')
preview = '{\u2026}';
span.textContent = preview;
span.title = description;
return span;
}
span.textContent = description;
return span;
}
};
/** @enum {string} */
ObjectUI.RemoteObjectPreviewFormatter._internalName = {
GeneratorStatus: '[[GeneratorStatus]]',
PrimitiveValue: '[[PrimitiveValue]]',
PromiseStatus: '[[PromiseStatus]]',
PromiseValue: '[[PromiseValue]]'
};
/**
* @param {!Element} container
* @param {string} nodeTitle
*/
ObjectUI.RemoteObjectPreviewFormatter.createSpansForNodeTitle = function(container, nodeTitle) {
const match = nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);
container.createChild('span', 'webkit-html-tag-name').textContent = match[1];
if (match[2])
container.createChild('span', 'webkit-html-attribute-value').textContent = match[2];
if (match[3])
container.createChild('span', 'webkit-html-attribute-name').textContent = match[3];
};