Bug 843004 - Part 3: VariablesView ObjectActor pretty output; r=benvie,vporof
This commit is contained in:
@@ -27,6 +27,9 @@ Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
|
|||||||
XPCOMUtils.defineLazyModuleGetter(this, "devtools",
|
XPCOMUtils.defineLazyModuleGetter(this, "devtools",
|
||||||
"resource://gre/modules/devtools/Loader.jsm");
|
"resource://gre/modules/devtools/Loader.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
|
||||||
|
"resource://gre/modules/PluralForm.jsm");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
|
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
|
||||||
"@mozilla.org/widget/clipboardhelper;1",
|
"@mozilla.org/widget/clipboardhelper;1",
|
||||||
"nsIClipboardHelper");
|
"nsIClipboardHelper");
|
||||||
@@ -2346,7 +2349,10 @@ Variable.prototype = Heritage.extend(Scope.prototype, {
|
|||||||
this._valueLabel.classList.remove(VariablesView.getClass(prevGrip));
|
this._valueLabel.classList.remove(VariablesView.getClass(prevGrip));
|
||||||
}
|
}
|
||||||
this._valueGrip = aGrip;
|
this._valueGrip = aGrip;
|
||||||
this._valueString = VariablesView.getString(aGrip, true);
|
this._valueString = VariablesView.getString(aGrip, {
|
||||||
|
concise: true,
|
||||||
|
noEllipsis: true,
|
||||||
|
});
|
||||||
this._valueClassName = VariablesView.getClass(aGrip);
|
this._valueClassName = VariablesView.getClass(aGrip);
|
||||||
|
|
||||||
this._valueLabel.classList.add(this._valueClassName);
|
this._valueLabel.classList.add(this._valueClassName);
|
||||||
@@ -3118,12 +3124,16 @@ VariablesView.getGrip = function(aValue) {
|
|||||||
*
|
*
|
||||||
* @param any aGrip
|
* @param any aGrip
|
||||||
* @see Variable.setGrip
|
* @see Variable.setGrip
|
||||||
* @param boolean aConciseFlag
|
* @param object aOptions
|
||||||
* Return a concisely formatted property string.
|
* Options:
|
||||||
|
* - concise: boolean that tells you want a concisely formatted string.
|
||||||
|
* - noStringQuotes: boolean that tells to not quote strings.
|
||||||
|
* - noEllipsis: boolean that tells to not add an ellipsis after the
|
||||||
|
* initial text of a longString.
|
||||||
* @return string
|
* @return string
|
||||||
* The formatted property string.
|
* The formatted property string.
|
||||||
*/
|
*/
|
||||||
VariablesView.getString = function(aGrip, aConciseFlag) {
|
VariablesView.getString = function(aGrip, aOptions = {}) {
|
||||||
if (aGrip && typeof aGrip == "object") {
|
if (aGrip && typeof aGrip == "object") {
|
||||||
switch (aGrip.type) {
|
switch (aGrip.type) {
|
||||||
case "undefined":
|
case "undefined":
|
||||||
@@ -3133,18 +3143,30 @@ VariablesView.getString = function(aGrip, aConciseFlag) {
|
|||||||
case "-Infinity":
|
case "-Infinity":
|
||||||
case "-0":
|
case "-0":
|
||||||
return aGrip.type;
|
return aGrip.type;
|
||||||
case "longString":
|
|
||||||
return "\"" + aGrip.initial + "\"";
|
|
||||||
default:
|
default:
|
||||||
if (!aConciseFlag) {
|
let stringifier = VariablesView.stringifiers.byType[aGrip.type];
|
||||||
return "[" + aGrip.type + " " + aGrip.class + "]";
|
if (stringifier) {
|
||||||
|
let result = stringifier(aGrip, aOptions);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aGrip.displayString) {
|
||||||
|
return VariablesView.getString(aGrip.displayString, aOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aGrip.type == "object" && aOptions.concise) {
|
||||||
return aGrip.class;
|
return aGrip.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "[" + aGrip.type + " " + aGrip.class + "]";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (typeof aGrip) {
|
switch (typeof aGrip) {
|
||||||
case "string":
|
case "string":
|
||||||
return "\"" + aGrip + "\"";
|
return VariablesView.stringifiers.byType.string(aGrip, aOptions);
|
||||||
case "boolean":
|
case "boolean":
|
||||||
return aGrip ? "true" : "false";
|
return aGrip ? "true" : "false";
|
||||||
case "number":
|
case "number":
|
||||||
@@ -3156,6 +3178,367 @@ VariablesView.getString = function(aGrip, aConciseFlag) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The VariablesView stringifiers are used by VariablesView.getString(). These
|
||||||
|
* are organized by object type, object class and by object actor preview kind.
|
||||||
|
* Some objects share identical ways for previews, for example Arrays, Sets and
|
||||||
|
* NodeLists.
|
||||||
|
*
|
||||||
|
* Any stringifier function must return a string. If null is returned, * then
|
||||||
|
* the default stringifier will be used. When invoked, the stringifier is
|
||||||
|
* given the same two arguments as those given to VariablesView.getString().
|
||||||
|
*/
|
||||||
|
VariablesView.stringifiers = {};
|
||||||
|
|
||||||
|
VariablesView.stringifiers.byType = {
|
||||||
|
string: function(aGrip, {noStringQuotes}) {
|
||||||
|
if (noStringQuotes) {
|
||||||
|
return aGrip;
|
||||||
|
}
|
||||||
|
return uneval(aGrip);
|
||||||
|
},
|
||||||
|
|
||||||
|
longString: function({initial}, {noStringQuotes, noEllipsis}) {
|
||||||
|
let ellipsis = noEllipsis ? "" : Scope.ellipsis;
|
||||||
|
if (noStringQuotes) {
|
||||||
|
return initial + ellipsis;
|
||||||
|
}
|
||||||
|
let result = uneval(initial);
|
||||||
|
if (!ellipsis) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result.substr(0, result.length - 1) + ellipsis + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
object: function(aGrip, aOptions) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
let stringifier;
|
||||||
|
if (preview && preview.kind) {
|
||||||
|
stringifier = VariablesView.stringifiers.byObjectKind[preview.kind];
|
||||||
|
}
|
||||||
|
if (!stringifier && aGrip.class) {
|
||||||
|
stringifier = VariablesView.stringifiers.byObjectClass[aGrip.class];
|
||||||
|
}
|
||||||
|
if (stringifier) {
|
||||||
|
return stringifier(aGrip, aOptions);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
}; // VariablesView.stringifiers.byType
|
||||||
|
|
||||||
|
VariablesView.stringifiers.byObjectClass = {
|
||||||
|
Function: function(aGrip, {concise}) {
|
||||||
|
// TODO: Bug 948484 - support arrow functions and ES6 generators
|
||||||
|
|
||||||
|
let name = aGrip.userDisplayName || aGrip.displayName || aGrip.name || "";
|
||||||
|
name = VariablesView.getString(name, { noStringQuotes: true });
|
||||||
|
|
||||||
|
// TODO: Bug 948489 - Support functions with destructured parameters and
|
||||||
|
// rest parameters
|
||||||
|
let params = aGrip.parameterNames || "";
|
||||||
|
if (!concise) {
|
||||||
|
return "function " + name + "(" + params + ")";
|
||||||
|
}
|
||||||
|
return (name || "function ") + "(" + params + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
RegExp: function({displayString}) {
|
||||||
|
return VariablesView.getString(displayString, { noStringQuotes: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
Date: function({preview}) {
|
||||||
|
if (!preview || !("timestamp" in preview)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof preview.timestamp != "number") {
|
||||||
|
return new Date(preview.timestamp).toString(); // invalid date
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Date " + new Date(preview.timestamp).toISOString();
|
||||||
|
},
|
||||||
|
}; // VariablesView.stringifiers.byObjectClass
|
||||||
|
|
||||||
|
VariablesView.stringifiers.byObjectKind = {
|
||||||
|
ArrayLike: function(aGrip, {concise}) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
if (concise) {
|
||||||
|
return aGrip.class + "[" + preview.length + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preview.items) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let shown = 0, result = [], lastHole = null;
|
||||||
|
for (let item of preview.items) {
|
||||||
|
if (item === null) {
|
||||||
|
if (lastHole !== null) {
|
||||||
|
result[lastHole] += ",";
|
||||||
|
} else {
|
||||||
|
result.push("");
|
||||||
|
}
|
||||||
|
lastHole = result.length - 1;
|
||||||
|
} else {
|
||||||
|
lastHole = null;
|
||||||
|
result.push(VariablesView.getString(item, { concise: true }));
|
||||||
|
}
|
||||||
|
shown++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shown < preview.length) {
|
||||||
|
let n = preview.length - shown;
|
||||||
|
result.push(VariablesView.stringifiers._getNMoreString(n));
|
||||||
|
} else if (lastHole !== null) {
|
||||||
|
// make sure we have the right number of commas...
|
||||||
|
result[lastHole] += ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefix = aGrip.class == "Array" ? "" : aGrip.class + " ";
|
||||||
|
return prefix + "[" + result.join(", ") + "]";
|
||||||
|
},
|
||||||
|
|
||||||
|
MapLike: function(aGrip, {concise}) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
if (concise || !preview.entries) {
|
||||||
|
let size = typeof preview.size == "number" ?
|
||||||
|
"[" + preview.size + "]" : "";
|
||||||
|
return aGrip.class + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
let entries = [];
|
||||||
|
for (let [key, value] of preview.entries) {
|
||||||
|
let keyString = VariablesView.getString(key, {
|
||||||
|
concise: true,
|
||||||
|
noStringQuotes: true,
|
||||||
|
});
|
||||||
|
let valueString = VariablesView.getString(value, { concise: true });
|
||||||
|
entries.push(keyString + ": " + valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof preview.size == "number" && preview.size > entries.length) {
|
||||||
|
let n = preview.size - entries.length;
|
||||||
|
entries.push(VariablesView.stringifiers._getNMoreString(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
return aGrip.class + " {" + entries.join(", ") + "}";
|
||||||
|
},
|
||||||
|
|
||||||
|
ObjectWithText: function(aGrip, {concise}) {
|
||||||
|
if (concise) {
|
||||||
|
return aGrip.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aGrip.class + " " + VariablesView.getString(aGrip.preview.text);
|
||||||
|
},
|
||||||
|
|
||||||
|
ObjectWithURL: function(aGrip, {concise}) {
|
||||||
|
let result = aGrip.class;
|
||||||
|
let url = aGrip.preview.url;
|
||||||
|
if (!VariablesView.isFalsy({ value: url })) {
|
||||||
|
result += " \u2192 " + WebConsoleUtils.abbreviateSourceURL(url,
|
||||||
|
{ onlyCropQuery: !concise });
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Stringifier for any kind of object.
|
||||||
|
Object: function(aGrip, {concise}) {
|
||||||
|
if (concise) {
|
||||||
|
return aGrip.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {preview} = aGrip;
|
||||||
|
let props = [];
|
||||||
|
for (let key of Object.keys(preview.ownProperties || {})) {
|
||||||
|
let value = preview.ownProperties[key];
|
||||||
|
let valueString = "";
|
||||||
|
if (value.get) {
|
||||||
|
valueString = "Getter";
|
||||||
|
} else if (value.set) {
|
||||||
|
valueString = "Setter";
|
||||||
|
} else {
|
||||||
|
valueString = VariablesView.getString(value.value, { concise: true });
|
||||||
|
}
|
||||||
|
props.push(key + ": " + valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key of Object.keys(preview.safeGetterValues || {})) {
|
||||||
|
let value = preview.safeGetterValues[key];
|
||||||
|
let valueString = VariablesView.getString(value.getterValue,
|
||||||
|
{ concise: true });
|
||||||
|
props.push(key + ": " + valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preview.ownPropertiesLength) {
|
||||||
|
let previewLength = Object.keys(preview.ownProperties).length;
|
||||||
|
let diff = preview.ownPropertiesLength - previewLength;
|
||||||
|
if (diff > 0) {
|
||||||
|
props.push(VariablesView.stringifiers._getNMoreString(diff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefix = aGrip.class != "Object" ? aGrip.class + " " : "";
|
||||||
|
return prefix + "{" + props.join(", ") + "}";
|
||||||
|
}, // Object
|
||||||
|
|
||||||
|
Error: function(aGrip, {concise}) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
let name = VariablesView.getString(preview.name, { noStringQuotes: true });
|
||||||
|
if (concise) {
|
||||||
|
return name || aGrip.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = name + ": " +
|
||||||
|
VariablesView.getString(preview.message, { noStringQuotes: true });
|
||||||
|
|
||||||
|
if (!VariablesView.isFalsy({ value: preview.stack })) {
|
||||||
|
msg += "\n" + STR.GetStringFromName("variablesViewErrorStacktrace") +
|
||||||
|
"\n" + preview.stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
},
|
||||||
|
|
||||||
|
DOMException: function(aGrip, {concise}) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
if (concise) {
|
||||||
|
return preview.name || aGrip.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = aGrip.class + " [" + preview.name + ": " +
|
||||||
|
VariablesView.getString(preview.message) + "\n" +
|
||||||
|
"code: " + preview.code + "\n" +
|
||||||
|
"nsresult: 0x" + (+preview.result).toString(16);
|
||||||
|
|
||||||
|
if (preview.filename) {
|
||||||
|
msg += "\nlocation: " + preview.filename;
|
||||||
|
if (preview.lineNumber) {
|
||||||
|
msg += ":" + preview.lineNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg + "]";
|
||||||
|
},
|
||||||
|
|
||||||
|
DOMEvent: function(aGrip, {concise}) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
if (!preview.type) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (concise) {
|
||||||
|
return aGrip.class + " " + preview.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = preview.type;
|
||||||
|
|
||||||
|
if (preview.eventKind == "key" && preview.modifiers &&
|
||||||
|
preview.modifiers.length) {
|
||||||
|
result += " " + preview.modifiers.join("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
let props = [];
|
||||||
|
if (preview.target) {
|
||||||
|
let target = VariablesView.getString(preview.target, { concise: true });
|
||||||
|
props.push("target: " + target);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let prop in preview.properties) {
|
||||||
|
let value = preview.properties[prop];
|
||||||
|
props.push(prop + ": " + VariablesView.getString(value, { concise: true }));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result + " {" + props.join(", ") + "}";
|
||||||
|
}, // DOMEvent
|
||||||
|
|
||||||
|
DOMNode: function(aGrip, {concise}) {
|
||||||
|
let {preview} = aGrip;
|
||||||
|
|
||||||
|
switch (preview.nodeType) {
|
||||||
|
case Ci.nsIDOMNode.DOCUMENT_NODE: {
|
||||||
|
let location = WebConsoleUtils.abbreviateSourceURL(preview.location,
|
||||||
|
{ onlyCropQuery: !concise });
|
||||||
|
return aGrip.class + " \u2192 " + location;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Ci.nsIDOMNode.ATTRIBUTE_NODE: {
|
||||||
|
let value = VariablesView.getString(preview.value, { noStringQuotes: true });
|
||||||
|
return preview.nodeName + '="' + escapeHTML(value) + '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
case Ci.nsIDOMNode.TEXT_NODE:
|
||||||
|
return preview.nodeName + " " +
|
||||||
|
VariablesView.getString(preview.textContent);
|
||||||
|
|
||||||
|
case Ci.nsIDOMNode.COMMENT_NODE: {
|
||||||
|
let comment = VariablesView.getString(preview.textContent,
|
||||||
|
{ noStringQuotes: true });
|
||||||
|
return "<!--" + comment + "-->";
|
||||||
|
}
|
||||||
|
|
||||||
|
case Ci.nsIDOMNode.DOCUMENT_FRAGMENT_NODE: {
|
||||||
|
if (concise || !preview.childNodes) {
|
||||||
|
return aGrip.class + "[" + preview.childNodesLength + "]";
|
||||||
|
}
|
||||||
|
let nodes = [];
|
||||||
|
for (let node of preview.childNodes) {
|
||||||
|
nodes.push(VariablesView.getString(node));
|
||||||
|
}
|
||||||
|
if (nodes.length < preview.childNodesLength) {
|
||||||
|
let n = preview.childNodesLength - nodes.length;
|
||||||
|
nodes.push(VariablesView.stringifiers._getNMoreString(n));
|
||||||
|
}
|
||||||
|
return aGrip.class + " [" + nodes.join(", ") + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
case Ci.nsIDOMNode.ELEMENT_NODE: {
|
||||||
|
let attrs = preview.attributes;
|
||||||
|
if (!concise) {
|
||||||
|
let n = 0, result = "<" + preview.nodeName;
|
||||||
|
for (let name in attrs) {
|
||||||
|
let value = VariablesView.getString(attrs[name],
|
||||||
|
{ noStringQuotes: true });
|
||||||
|
result += " " + name + '="' + escapeHTML(value) + '"';
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if (preview.attributesLength > n) {
|
||||||
|
result += " " + Scope.ellipsis;
|
||||||
|
}
|
||||||
|
return result + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = "<" + preview.nodeName;
|
||||||
|
if (attrs.id) {
|
||||||
|
result += "#" + attrs.id;
|
||||||
|
}
|
||||||
|
return result + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, // DOMNode
|
||||||
|
}; // VariablesView.stringifiers.byObjectKind
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the "N more…" formatted string, given an N. This is used for displaying
|
||||||
|
* how many elements are not displayed in an object preview (eg. an array).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param number aNumber
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
VariablesView.stringifiers._getNMoreString = function(aNumber) {
|
||||||
|
let str = STR.GetStringFromName("variablesViewMoreObjects");
|
||||||
|
return PluralForm.get(aNumber, str).replace("#1", aNumber);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a custom class style for a grip.
|
* Returns a custom class style for a grip.
|
||||||
*
|
*
|
||||||
@@ -3208,6 +3591,22 @@ let generateId = (function() {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape some HTML special characters. We do not need full HTML serialization
|
||||||
|
* here, we just want to make strings safe to display in HTML attributes, for
|
||||||
|
* the stringifiers.
|
||||||
|
*
|
||||||
|
* @param string aString
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function escapeHTML(aString) {
|
||||||
|
return aString.replace(/&/g, "&")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Editable encapsulates the UI of an edit box that overlays a label,
|
* An Editable encapsulates the UI of an edit box that overlays a label,
|
||||||
* allowing the user to edit the value.
|
* allowing the user to edit the value.
|
||||||
|
|||||||
@@ -997,10 +997,12 @@ Messages.Extended.prototype = Heritage.extend(Messages.Simple.prototype,
|
|||||||
}
|
}
|
||||||
|
|
||||||
let result = this.document.createDocumentFragment();
|
let result = this.document.createDocumentFragment();
|
||||||
if (!isPrimitive || (!this._quoteStrings && typeof piece == "string")) {
|
if (isPrimitive) {
|
||||||
result.textContent = piece;
|
result.textContent = VariablesView.getString(piece, {
|
||||||
|
noStringQuotes: !this._quoteStrings,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
result.textContent = VariablesView.getString(piece);
|
result.textContent = piece;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1219,7 +1221,7 @@ Widgets.JSObject.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
|
|||||||
_onClick: function()
|
_onClick: function()
|
||||||
{
|
{
|
||||||
this.output.openVariablesView({
|
this.output.openVariablesView({
|
||||||
label: this.element.textContent,
|
label: VariablesView.getString(this.objectActor, { concise: true }),
|
||||||
objectActor: this.objectActor,
|
objectActor: this.objectActor,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
});
|
});
|
||||||
@@ -1273,11 +1275,10 @@ Widgets.LongString.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
|
|||||||
*/
|
*/
|
||||||
_renderString: function(str)
|
_renderString: function(str)
|
||||||
{
|
{
|
||||||
if (this.message._quoteStrings) {
|
this.element.textContent = VariablesView.getString(str, {
|
||||||
this.element.textContent = VariablesView.getString(str);
|
noStringQuotes: !this.message._quoteStrings,
|
||||||
} else {
|
noEllipsis: true,
|
||||||
this.element.textContent = str;
|
});
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1183,10 +1183,6 @@ WebConsoleFrame.prototype = {
|
|||||||
let clipboardArray = [];
|
let clipboardArray = [];
|
||||||
args.forEach((aValue) => {
|
args.forEach((aValue) => {
|
||||||
clipboardArray.push(VariablesView.getString(aValue));
|
clipboardArray.push(VariablesView.getString(aValue));
|
||||||
if (aValue && typeof aValue == "object" &&
|
|
||||||
aValue.type == "longString") {
|
|
||||||
clipboardArray.push(l10n.getStr("longStringEllipsis"));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
clipboardText = clipboardArray.join(" ");
|
clipboardText = clipboardArray.join(" ");
|
||||||
break;
|
break;
|
||||||
@@ -3103,7 +3099,7 @@ JSTerm.prototype = {
|
|||||||
aAfterMessage._objectActors.add(helperResult.object.actor);
|
aAfterMessage._objectActors.add(helperResult.object.actor);
|
||||||
}
|
}
|
||||||
this.openVariablesView({
|
this.openVariablesView({
|
||||||
label: VariablesView.getString(helperResult.object),
|
label: VariablesView.getString(helperResult.object, { concise: true }),
|
||||||
objectActor: helperResult.object,
|
objectActor: helperResult.object,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -202,8 +202,8 @@ loadingText=Loading\u2026
|
|||||||
# viewer when there is an error loading a file
|
# viewer when there is an error loading a file
|
||||||
errorLoadingText=Error loading source:\n
|
errorLoadingText=Error loading source:\n
|
||||||
|
|
||||||
# LOCALIZATION NOTE (emptyStackText): The text that is displayed in the watch
|
# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the
|
||||||
# expressions list to add a new item.
|
# watch expressions list to add a new item.
|
||||||
addWatchExpressionText=Add watch expression
|
addWatchExpressionText=Add watch expression
|
||||||
|
|
||||||
# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the
|
# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the
|
||||||
@@ -225,6 +225,19 @@ watchExpressionsScopeLabel=Watch expressions
|
|||||||
# the global scope.
|
# the global scope.
|
||||||
globalScopeLabel=Global
|
globalScopeLabel=Global
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is
|
||||||
|
# shown before the stack trace in an error.
|
||||||
|
variablesViewErrorStacktrace=Stack trace:
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed
|
||||||
|
# when you have an object preview that does not show all of the elements. At the end of the list
|
||||||
|
# you see "N more..." in the web console output.
|
||||||
|
# This is a semi-colon list of plural forms.
|
||||||
|
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||||
|
# #1 number of remaining items in the object
|
||||||
|
# example: 3 more…
|
||||||
|
variablesViewMoreObjects=#1 more…;#1 more…
|
||||||
|
|
||||||
# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed
|
# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed
|
||||||
# in the variables list on an item with an editable name.
|
# in the variables list on an item with an editable name.
|
||||||
variablesEditableNameTooltip=Double click to edit
|
variablesEditableNameTooltip=Double click to edit
|
||||||
|
|||||||
@@ -188,12 +188,18 @@ let WebConsoleUtils = {
|
|||||||
*
|
*
|
||||||
* @param string aSourceURL
|
* @param string aSourceURL
|
||||||
* The source URL to shorten.
|
* The source URL to shorten.
|
||||||
|
* @param object [aOptions]
|
||||||
|
* Options:
|
||||||
|
* - onlyCropQuery: boolean that tells if the URL abbreviation function
|
||||||
|
* should only remove the query parameters and the hash fragment from
|
||||||
|
* the given URL.
|
||||||
* @return string
|
* @return string
|
||||||
* The abbreviated form of the source URL.
|
* The abbreviated form of the source URL.
|
||||||
*/
|
*/
|
||||||
abbreviateSourceURL: function WCU_abbreviateSourceURL(aSourceURL)
|
abbreviateSourceURL:
|
||||||
|
function WCU_abbreviateSourceURL(aSourceURL, aOptions = {})
|
||||||
{
|
{
|
||||||
if (aSourceURL.substr(0, 5) == "data:") {
|
if (!aOptions.onlyCropQuery && aSourceURL.substr(0, 5) == "data:") {
|
||||||
let commaIndex = aSourceURL.indexOf(",");
|
let commaIndex = aSourceURL.indexOf(",");
|
||||||
if (commaIndex > -1) {
|
if (commaIndex > -1) {
|
||||||
aSourceURL = "data:" + aSourceURL.substring(commaIndex + 1);
|
aSourceURL = "data:" + aSourceURL.substring(commaIndex + 1);
|
||||||
@@ -214,14 +220,16 @@ let WebConsoleUtils = {
|
|||||||
|
|
||||||
// Remove a trailing "/".
|
// Remove a trailing "/".
|
||||||
if (aSourceURL[aSourceURL.length - 1] == "/") {
|
if (aSourceURL[aSourceURL.length - 1] == "/") {
|
||||||
aSourceURL = aSourceURL.substring(0, aSourceURL.length - 1);
|
aSourceURL = aSourceURL.replace(/\/+$/, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all but the last path component.
|
// Remove all but the last path component.
|
||||||
|
if (!aOptions.onlyCropQuery) {
|
||||||
let slashIndex = aSourceURL.lastIndexOf("/");
|
let slashIndex = aSourceURL.lastIndexOf("/");
|
||||||
if (slashIndex > -1) {
|
if (slashIndex > -1) {
|
||||||
aSourceURL = aSourceURL.substring(slashIndex + 1);
|
aSourceURL = aSourceURL.substring(slashIndex + 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return aSourceURL;
|
return aSourceURL;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user