--- a/devtools/client/storage/test/browser_storage_basic.js
+++ b/devtools/client/storage/test/browser_storage_basic.js
@@ -43,23 +43,23 @@ const testCases = [
getCookieId("c4", ".example.org", "/"),
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/client/storage/test/"),
getCookieId("sc2", "sectest1.example.org",
"/browser/devtools/client/storage/test/")
]
],
[["localStorage", "http://test1.example.org"],
- ["ls1", "ls2"]],
+ ["key", "ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
["iframe-s-ls1"]],
[["sessionStorage", "http://test1.example.org"],
- ["ss1"]],
+ ["key", "ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org"],
["idb1 (default)", "idb2 (default)"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)"],
["obj1", "obj2"]],
--- a/devtools/client/storage/test/browser_storage_basic_usercontextid_1.js
+++ b/devtools/client/storage/test/browser_storage_basic_usercontextid_1.js
@@ -28,23 +28,23 @@ const testCases = [
getCookieId("c4", ".example.org", "/"),
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/client/storage/test/"),
getCookieId("sc2", "sectest1.example.org",
"/browser/devtools/client/storage/test/")
]
],
[["localStorage", "http://test1.example.org"],
- ["ls1", "ls2"]],
+ ["key", "ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
["iframe-s-ls1"]],
[["sessionStorage", "http://test1.example.org"],
- ["ss1"]],
+ ["key", "ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org"],
["idb1 (default)", "idb2 (default)"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)"],
["obj1", "obj2"]],
--- a/devtools/client/storage/test/browser_storage_delete_all.js
+++ b/devtools/client/storage/test/browser_storage_delete_all.js
@@ -13,23 +13,23 @@ add_task(async function() {
let contextMenu = gPanelWindow.document.getElementById("storage-table-popup");
let menuDeleteAllItem = contextMenu.querySelector(
"#storage-table-popup-delete-all");
info("test state before delete");
const beforeState = [
[["localStorage", "http://test1.example.org"],
- ["ls1", "ls2"]],
+ ["key", "ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
["iframe-s-ls1"]],
[["sessionStorage", "http://test1.example.org"],
- ["ss1"]],
+ ["key", "ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
[1, 2, 3]],
[["Cache", "http://test1.example.org", "plop"],
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
@@ -62,23 +62,23 @@ add_task(async function() {
await eventWait;
}
info("test state after delete");
const afterState = [
// iframes from the same host, one secure, one unsecure, are independent
// from each other. Delete all in one doesn't touch the other one.
[["localStorage", "http://test1.example.org"],
- ["ls1", "ls2"]],
+ ["key", "ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
[]],
[["sessionStorage", "http://test1.example.org"],
- ["ss1"]],
+ ["key", "ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
[]],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
[]],
[["Cache", "http://test1.example.org", "plop"],
[]],
--- a/devtools/client/storage/test/browser_storage_delete_tree.js
+++ b/devtools/client/storage/test/browser_storage_delete_tree.js
@@ -23,18 +23,18 @@ add_task(async function() {
getCookieId("c1", "test1.example.org", "/browser"),
getCookieId("cs2", ".example.org", "/"),
getCookieId("c3", "test1.example.org", "/"),
getCookieId("c4", ".example.org", "/"),
getCookieId("uc1", ".example.org", "/"),
getCookieId("uc2", ".example.org", "/")
]
],
- [["localStorage", "http://test1.example.org"], ["ls1", "ls2"]],
- [["sessionStorage", "http://test1.example.org"], ["ss1"]],
+ [["localStorage", "http://test1.example.org"], ["key", "ls1", "ls2"]],
+ [["sessionStorage", "http://test1.example.org"], ["key", "ss1"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], [1, 2, 3]],
[["Cache", "http://test1.example.org", "plop"],
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
]);
info("do the delete");
const deleteHosts = [
["cookies", "http://test1.example.org"],
--- a/devtools/client/storage/test/browser_storage_delete_usercontextid.js
+++ b/devtools/client/storage/test/browser_storage_delete_usercontextid.js
@@ -46,23 +46,23 @@ const storageItemsForDefault = [
getCookieId("c4", ".example.org", "/"),
getCookieId("sc1", "sectest1.example.org",
"/browser/devtools/client/storage/test/"),
getCookieId("sc2", "sectest1.example.org",
"/browser/devtools/client/storage/test/")
]
],
[["localStorage", "http://test1.example.org"],
- ["ls1", "ls2"]],
+ ["key", "ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
["iframe-s-ls1"]],
[["sessionStorage", "http://test1.example.org"],
- ["ss1"]],
+ ["key", "ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org"],
["idb1 (default)", "idb2 (default)"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)"],
["obj1", "obj2"]],
--- a/devtools/client/storage/test/browser_storage_dom_cache_disabled.js
+++ b/devtools/client/storage/test/browser_storage_dom_cache_disabled.js
@@ -11,23 +11,23 @@
add_task(async function() {
// Disable the DOM cache
Services.prefs.setBoolPref(DOM_CACHE, false);
await openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html");
const state = [
[["localStorage", "http://test1.example.org"],
- ["ls1", "ls2"]],
+ ["key", "ls1", "ls2"]],
[["localStorage", "http://sectest1.example.org"],
["iframe-u-ls1"]],
[["localStorage", "https://sectest1.example.org"],
["iframe-s-ls1"]],
[["sessionStorage", "http://test1.example.org"],
- ["ss1"]],
+ ["key", "ss1"]],
[["sessionStorage", "http://sectest1.example.org"],
["iframe-u-ss1", "iframe-u-ss2"]],
[["sessionStorage", "https://sectest1.example.org"],
["iframe-s-ss1"]],
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
[1, 2, 3]],
];
--- a/devtools/client/storage/test/storage-listings.html
+++ b/devtools/client/storage/test/storage-listings.html
@@ -22,18 +22,30 @@ document.cookie = "cs2=sessionCookie; pa
document.cookie = "c3=foobar-2; expires=" +
new Date(cookieExpiresTime1).toGMTString() + "; path=/";
document.cookie = "c4=foobar-3; expires=" +
new Date(cookieExpiresTime2).toGMTString() + "; path=/; domain=" +
partialHostname;
// ... and some local storage items ..
localStorage.setItem("ls1", "foobar");
localStorage.setItem("ls2", "foobar-2");
+
+// Because localStorage contains key() on the prototype and it can't be iterated
+// using object.keys() we check the the value "key" exists.
+// See bug 1451991 for details.
+localStorage.setItem("key", "value1");
+
// ... and finally some session storage items too
sessionStorage.setItem("ss1", "foobar-3");
+
+// Because sessionStorage contains key() on the prototype and it can't be
+// iterated using object.keys() we check the the value "key" exists.
+// See bug 1451991 for details.
+sessionStorage.setItem("key", "value2");
+
dump("added cookies and storage from main page\n");
let idbGenerator = async function () {
let request = indexedDB.open("idb1", 1);
request.onerror = function() {
throw new Error("error opening db connection");
};
let db = await new Promise(done => {
--- a/devtools/server/actors/storage.js
+++ b/devtools/server/actors/storage.js
@@ -1163,20 +1163,30 @@ function getObjectForLocalOrSessionStora
}
if (name) {
let value = storage ? storage.getItem(name) : null;
return [{ name, value }];
}
if (!storage) {
return [];
}
- return Object.keys(storage).map(key => ({
- name: key,
- value: storage.getItem(key)
- }));
+
+ // local and session storage cannot be iterated over using Object.keys()
+ // because it skips keys that are duplicated on the prototype
+ // e.g. "key", "getKeys" so we need to gather the real keys using the
+ // storage.key() function.
+ const storageArray = [];
+ for (let i = 0; i < storage.length; i++) {
+ const key = storage.key(i);
+ storageArray.push({
+ name: key,
+ value: storage.getItem(key)
+ });
+ }
+ return storageArray;
},
populateStoresForHost(host, window) {
try {
this.hostVsStores.set(host, window[type]);
} catch (ex) {
console.warn(`Failed to enumerate ${type} for host ${host}: ${ex}`);
}