Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
90 lines (86 sloc) 3.53 KB
# HG changeset patch
# Parent 3281298476f0806b3d316075c30330414f2b0861
# User Thaddee Tyl <thaddee.tyl@gmail.com>
Bug 776106 — Autocompletion on arrays include numbers
diff --git a/browser/devtools/webconsole/WebConsoleUtils.jsm b/browser/devtools/webconsole/WebConsoleUtils.jsm
--- a/browser/devtools/webconsole/WebConsoleUtils.jsm
+++ b/browser/devtools/webconsole/WebConsoleUtils.jsm
@@ -953,7 +953,7 @@ function JSPropertyProvider(aScope, aInp
return null;
}
- let matches = Object.keys(getMatchedProps(obj, matchProp));
+ let matches = Object.keys(getMatchedProps(obj, {matchProp:matchProp}));
return {
matchProp: matchProp,
@@ -969,15 +969,25 @@ function JSPropertyProvider(aScope, aInp
* @param mixed aObj
* JS value whose properties we want to collect.
*
- * @param string aMatchProp
- * Filter for properties that match this one.
- * Defaults to the empty string (which always matches).
+ * @param object aOptions
+ * Options that the algorithm takes.
+ * - matchProp (string): Filter for properties that match this one.
+ * Defaults to the empty string (which always matches).
+ * - completeAfter (string): Character after which we are getting the
+ * properties. Should be either "." or "[". Chooses how the properties
+ * should look: "." gives the string directly, and doesn't give number
+ * indices, whereas "[" surrounds the properties with '"' and gives
+ * number indices.
*
* @return object
* Object whose keys are all accessible properties on the object.
*/
-function getMatchedProps(aObj, aMatchProp = "")
+function getMatchedProps(aObj, aOptions = {matchProp: "", completeAfter: "."})
{
+ // Argument defaults.
+ aOptions.matchProp = aOptions.matchProp || "";
+ aOptions.completeAfter = aOptions.completeAfter || ".";
+
if (aObj == null) { return {}; }
try {
Object.getPrototypeOf(aObj);
@@ -988,13 +998,30 @@ function getMatchedProps(aObj, aMatchPro
let names = {}; // Using an Object to avoid duplicates.
let ownNames = Object.getOwnPropertyNames(aObj);
for (let i = 0; i < ownNames.length; i++) {
- if (ownNames[i].indexOf(aMatchProp) == 0) {
+ // Filtering happens here.
+ if (ownNames[i].indexOf(aOptions.matchProp) == 0) {
+ // If we already have it in, no need to append it.
if (names[ownNames[i]] != true) {
c--;
if (c < 0) {
return names;
}
- names[ownNames[i]] = true;
+ if (aOptions.completeAfter[0] == ".") {
+ // If it is an array index, we can't take it.
+ // This uses a trick: converting a string to a number yields NaN if
+ // the operation failed, and NaN is not equal to itself.
+ if (+ownNames[i] != +ownNames[i]) {
+ names[ownNames[i]] = true;
+ }
+ } else if (aOptions.completeAfter[0] == "[") {
+ // See above for the following trick.
+ if (+ownNames[i] != +ownNames[i]) {
+ names['"' + ownNames[i] + '"'] = true;
+ } else {
+ // The property is a number index.
+ names[ownNames[i]] = true;
+ }
+ }
}
}
}
@@ -1002,7 +1029,7 @@ function getMatchedProps(aObj, aMatchPro
// We need to recursively go up the prototype chain.
aObj = Object.getPrototypeOf(aObj);
if (aObj !== null) {
- let parentScope = getMatchedProps(aObj, aMatchProp);
+ let parentScope = getMatchedProps(aObj, aOptions);
for (let name in parentScope) {
if (names[name] != true) {
c--;