mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-31 11:37:30 +09:00
Bug 1276339: Storage inspector doesn't work on chrome:// pages and web extensions
Issue #31
This commit is contained in:
parent
a5b4f6e003
commit
d0ef0781ff
18 changed files with 361 additions and 129 deletions
|
|
@ -60,7 +60,7 @@ table.headers.indexedDB.value=Value
|
||||||
table.headers.indexedDB.origin=Origin
|
table.headers.indexedDB.origin=Origin
|
||||||
table.headers.indexedDB.version=Version
|
table.headers.indexedDB.version=Version
|
||||||
table.headers.indexedDB.objectStores=Object Stores
|
table.headers.indexedDB.objectStores=Object Stores
|
||||||
table.headers.indexedDB.keyPath=Key
|
table.headers.indexedDB.keyPath2=Key Path
|
||||||
table.headers.indexedDB.autoIncrement=Auto Increment
|
table.headers.indexedDB.autoIncrement=Auto Increment
|
||||||
table.headers.indexedDB.indexes=Indexes
|
table.headers.indexedDB.indexes=Indexes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ support-files =
|
||||||
storage-cookies.html
|
storage-cookies.html
|
||||||
storage-empty-objectstores.html
|
storage-empty-objectstores.html
|
||||||
storage-idb-delete-blocked.html
|
storage-idb-delete-blocked.html
|
||||||
|
storage-indexeddb-duplicate-names.html
|
||||||
storage-listings.html
|
storage-listings.html
|
||||||
storage-localstorage.html
|
storage-localstorage.html
|
||||||
storage-overflow.html
|
storage-overflow.html
|
||||||
|
|
@ -35,6 +36,7 @@ support-files =
|
||||||
[browser_storage_empty_objectstores.js]
|
[browser_storage_empty_objectstores.js]
|
||||||
[browser_storage_indexeddb_delete.js]
|
[browser_storage_indexeddb_delete.js]
|
||||||
[browser_storage_indexeddb_delete_blocked.js]
|
[browser_storage_indexeddb_delete_blocked.js]
|
||||||
|
[browser_storage_indexeddb_duplicate_names.js]
|
||||||
[browser_storage_localstorage_edit.js]
|
[browser_storage_localstorage_edit.js]
|
||||||
[browser_storage_localstorage_error.js]
|
[browser_storage_localstorage_error.js]
|
||||||
[browser_storage_overflow.js]
|
[browser_storage_overflow.js]
|
||||||
|
|
|
||||||
|
|
@ -53,28 +53,28 @@ const testCases = [
|
||||||
[["sessionStorage", "https://sectest1.example.org"],
|
[["sessionStorage", "https://sectest1.example.org"],
|
||||||
["iframe-s-ss1"]],
|
["iframe-s-ss1"]],
|
||||||
[["indexedDB", "http://test1.example.org"],
|
[["indexedDB", "http://test1.example.org"],
|
||||||
["idb1", "idb2"]],
|
["idb1 (default)", "idb2 (default)"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)"],
|
||||||
["obj1", "obj2"]],
|
["obj1", "obj2"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb2"],
|
[["indexedDB", "http://test1.example.org", "idb2 (default)"],
|
||||||
["obj3"]],
|
["obj3"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
|
||||||
[1, 2, 3]],
|
[1, 2, 3]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj2"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj2"],
|
||||||
[1]],
|
[1]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb2", "obj3"],
|
[["indexedDB", "http://test1.example.org", "idb2 (default)", "obj3"],
|
||||||
[]],
|
[]],
|
||||||
[["indexedDB", "http://sectest1.example.org"],
|
[["indexedDB", "http://sectest1.example.org"],
|
||||||
[]],
|
[]],
|
||||||
[["indexedDB", "https://sectest1.example.org"],
|
[["indexedDB", "https://sectest1.example.org"],
|
||||||
["idb-s1", "idb-s2"]],
|
["idb-s1 (default)", "idb-s2 (default)"]],
|
||||||
[["indexedDB", "https://sectest1.example.org", "idb-s1"],
|
[["indexedDB", "https://sectest1.example.org", "idb-s1 (default)"],
|
||||||
["obj-s1"]],
|
["obj-s1"]],
|
||||||
[["indexedDB", "https://sectest1.example.org", "idb-s2"],
|
[["indexedDB", "https://sectest1.example.org", "idb-s2 (default)"],
|
||||||
["obj-s2"]],
|
["obj-s2"]],
|
||||||
[["indexedDB", "https://sectest1.example.org", "idb-s1", "obj-s1"],
|
[["indexedDB", "https://sectest1.example.org", "idb-s1 (default)", "obj-s1"],
|
||||||
[6, 7]],
|
[6, 7]],
|
||||||
[["indexedDB", "https://sectest1.example.org", "idb-s2", "obj-s2"],
|
[["indexedDB", "https://sectest1.example.org", "idb-s2 (default)", "obj-s2"],
|
||||||
[16]],
|
[16]],
|
||||||
[["Cache", "http://test1.example.org", "plop"],
|
[["Cache", "http://test1.example.org", "plop"],
|
||||||
[MAIN_DOMAIN + "404_cached_file.js",
|
[MAIN_DOMAIN + "404_cached_file.js",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ const TEST_CASES = [
|
||||||
["cookies", "test1.example.org"],
|
["cookies", "test1.example.org"],
|
||||||
getCookieId("c1", "test1.example.org", "/browser"), "name"
|
getCookieId("c1", "test1.example.org", "/browser"), "name"
|
||||||
],
|
],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
|
||||||
1, "name"],
|
1, "name"],
|
||||||
[["Cache", "http://test1.example.org", "plop"],
|
[["Cache", "http://test1.example.org", "plop"],
|
||||||
MAIN_DOMAIN + "404_cached_file.js", "url"],
|
MAIN_DOMAIN + "404_cached_file.js", "url"],
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ add_task(function* () {
|
||||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||||
[["sessionStorage", "https://sectest1.example.org"],
|
[["sessionStorage", "https://sectest1.example.org"],
|
||||||
["iframe-s-ss1"]],
|
["iframe-s-ss1"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
|
||||||
[1, 2, 3]],
|
[1, 2, 3]],
|
||||||
[["Cache", "http://test1.example.org", "plop"],
|
[["Cache", "http://test1.example.org", "plop"],
|
||||||
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
|
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
|
||||||
|
|
@ -41,7 +41,7 @@ add_task(function* () {
|
||||||
const deleteHosts = [
|
const deleteHosts = [
|
||||||
[["localStorage", "https://sectest1.example.org"], "iframe-s-ls1", "name"],
|
[["localStorage", "https://sectest1.example.org"], "iframe-s-ls1", "name"],
|
||||||
[["sessionStorage", "https://sectest1.example.org"], "iframe-s-ss1", "name"],
|
[["sessionStorage", "https://sectest1.example.org"], "iframe-s-ss1", "name"],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"], 1, "name"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], 1, "name"],
|
||||||
[["Cache", "http://test1.example.org", "plop"],
|
[["Cache", "http://test1.example.org", "plop"],
|
||||||
MAIN_DOMAIN + "404_cached_file.js", "url"],
|
MAIN_DOMAIN + "404_cached_file.js", "url"],
|
||||||
];
|
];
|
||||||
|
|
@ -78,7 +78,7 @@ add_task(function* () {
|
||||||
["iframe-u-ss1", "iframe-u-ss2"]],
|
["iframe-u-ss1", "iframe-u-ss2"]],
|
||||||
[["sessionStorage", "https://sectest1.example.org"],
|
[["sessionStorage", "https://sectest1.example.org"],
|
||||||
[]],
|
[]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
|
||||||
[]],
|
[]],
|
||||||
[["Cache", "http://test1.example.org", "plop"],
|
[["Cache", "http://test1.example.org", "plop"],
|
||||||
[]],
|
[]],
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ add_task(function* () {
|
||||||
],
|
],
|
||||||
[["localStorage", "http://test1.example.org"], ["ls1", "ls2"]],
|
[["localStorage", "http://test1.example.org"], ["ls1", "ls2"]],
|
||||||
[["sessionStorage", "http://test1.example.org"], ["ss1"]],
|
[["sessionStorage", "http://test1.example.org"], ["ss1"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"], [1, 2, 3]],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], [1, 2, 3]],
|
||||||
[["Cache", "http://test1.example.org", "plop"],
|
[["Cache", "http://test1.example.org", "plop"],
|
||||||
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
|
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
|
||||||
]);
|
]);
|
||||||
|
|
@ -38,7 +38,7 @@ add_task(function* () {
|
||||||
["cookies", "test1.example.org"],
|
["cookies", "test1.example.org"],
|
||||||
["localStorage", "http://test1.example.org"],
|
["localStorage", "http://test1.example.org"],
|
||||||
["sessionStorage", "http://test1.example.org"],
|
["sessionStorage", "http://test1.example.org"],
|
||||||
["indexedDB", "http://test1.example.org", "idb1", "obj1"],
|
["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
|
||||||
["Cache", "http://test1.example.org", "plop"],
|
["Cache", "http://test1.example.org", "plop"],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ add_task(function* () {
|
||||||
[["cookies", "test1.example.org"], []],
|
[["cookies", "test1.example.org"], []],
|
||||||
[["localStorage", "http://test1.example.org"], []],
|
[["localStorage", "http://test1.example.org"], []],
|
||||||
[["sessionStorage", "http://test1.example.org"], []],
|
[["sessionStorage", "http://test1.example.org"], []],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"], []],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], []],
|
||||||
[["Cache", "http://test1.example.org", "plop"], []],
|
[["Cache", "http://test1.example.org", "plop"], []],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,14 @@
|
||||||
// storage-secured-iframe.html and storage-unsecured-iframe.html
|
// storage-secured-iframe.html and storage-unsecured-iframe.html
|
||||||
const storeItems = [
|
const storeItems = [
|
||||||
[["indexedDB", "http://test1.example.org"],
|
[["indexedDB", "http://test1.example.org"],
|
||||||
["idb1", "idb2"]],
|
["idb1 (default)", "idb2 (default)"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)"],
|
||||||
["obj1", "obj2"]],
|
["obj1", "obj2"]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb2"],
|
[["indexedDB", "http://test1.example.org", "idb2 (default)"],
|
||||||
[]],
|
[]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"],
|
||||||
[1, 2, 3]],
|
[1, 2, 3]],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj2"],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj2"],
|
||||||
[1]]
|
[1]]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@ add_task(function* () {
|
||||||
|
|
||||||
info("test state before delete");
|
info("test state before delete");
|
||||||
yield checkState([
|
yield checkState([
|
||||||
[["indexedDB", "http://test1.example.org"], ["idb1", "idb2"]],
|
[["indexedDB", "http://test1.example.org"], ["idb1 (default)", "idb2 (default)"]],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
info("do the delete");
|
info("do the delete");
|
||||||
const deletedDb = ["indexedDB", "http://test1.example.org", "idb1"];
|
const deletedDb = ["indexedDB", "http://test1.example.org", "idb1 (default)"];
|
||||||
|
|
||||||
yield selectTreeItem(deletedDb);
|
yield selectTreeItem(deletedDb);
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ add_task(function* () {
|
||||||
|
|
||||||
info("test state after delete");
|
info("test state after delete");
|
||||||
yield checkState([
|
yield checkState([
|
||||||
[["indexedDB", "http://test1.example.org"], ["idb2"]],
|
[["indexedDB", "http://test1.example.org"], ["idb2 (default)"]],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
yield finishTests();
|
yield finishTests();
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ add_task(function* () {
|
||||||
|
|
||||||
info("test state before delete");
|
info("test state before delete");
|
||||||
yield checkState([
|
yield checkState([
|
||||||
[["indexedDB", "http://test1.example.org"], ["idb"]]
|
[["indexedDB", "http://test1.example.org"], ["idb (default)"]]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
info("do the delete");
|
info("do the delete");
|
||||||
yield selectTreeItem(["indexedDB", "http://test1.example.org"]);
|
yield selectTreeItem(["indexedDB", "http://test1.example.org"]);
|
||||||
let actor = gUI.getCurrentActor();
|
let actor = gUI.getCurrentActor();
|
||||||
let result = yield actor.removeDatabase("http://test1.example.org", "idb");
|
let result = yield actor.removeDatabase("http://test1.example.org", "idb (default)");
|
||||||
|
|
||||||
ok(result.blocked, "removeDatabase attempt is blocked");
|
ok(result.blocked, "removeDatabase attempt is blocked");
|
||||||
|
|
||||||
info("test state after blocked delete");
|
info("test state after blocked delete");
|
||||||
yield checkState([
|
yield checkState([
|
||||||
[["indexedDB", "http://test1.example.org"], ["idb"]]
|
[["indexedDB", "http://test1.example.org"], ["idb (default)"]]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let eventWait = gUI.once("store-objects-updated");
|
let eventWait = gUI.once("store-objects-updated");
|
||||||
|
|
@ -47,7 +47,7 @@ add_task(function* () {
|
||||||
info("try to delete database from nonexistent host");
|
info("try to delete database from nonexistent host");
|
||||||
let errorThrown = false;
|
let errorThrown = false;
|
||||||
try {
|
try {
|
||||||
result = yield actor.removeDatabase("http://test2.example.org", "idb");
|
result = yield actor.removeDatabase("http://test2.example.org", "idb (default)");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
errorThrown = true;
|
errorThrown = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
// Test to verify that indexedDBs with duplicate names (different types / paths)
|
||||||
|
// work as expected.
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
add_task(function* () {
|
||||||
|
const TESTPAGE = MAIN_DOMAIN + "storage-indexeddb-duplicate-names.html";
|
||||||
|
|
||||||
|
setPermission(TESTPAGE, "indexedDB");
|
||||||
|
|
||||||
|
yield openTabAndSetupStorage(TESTPAGE);
|
||||||
|
|
||||||
|
yield checkState([
|
||||||
|
[
|
||||||
|
["indexedDB", "http://test1.example.org"], [
|
||||||
|
"idb1 (default)",
|
||||||
|
"idb1 (temporary)",
|
||||||
|
"idb1 (persistent)",
|
||||||
|
"idb2 (default)",
|
||||||
|
"idb2 (temporary)",
|
||||||
|
"idb2 (persistent)"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
yield finishTests();
|
||||||
|
});
|
||||||
|
|
@ -72,17 +72,17 @@ const testCases = [
|
||||||
sidebarHidden: true
|
sidebarHidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
location: "idb2",
|
location: "idb2 (default)",
|
||||||
sidebarHidden: false
|
sidebarHidden: false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
location: ["indexedDB", "http://test1.example.org", "idb2", "obj3"],
|
location: ["indexedDB", "http://test1.example.org", "idb2 (default)", "obj3"],
|
||||||
sidebarHidden: true
|
sidebarHidden: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
location: ["indexedDB", "https://sectest1.example.org", "idb-s2"],
|
location: ["indexedDB", "https://sectest1.example.org", "idb-s2 (default)"],
|
||||||
sidebarHidden: true
|
sidebarHidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ const testCases = [
|
||||||
{name: "ss5.3", value: `${LONG_WORD}&${LONG_WORD}`},
|
{name: "ss5.3", value: `${LONG_WORD}&${LONG_WORD}`},
|
||||||
{name: "ss5.4", value: `${LONG_WORD}&${LONG_WORD}`},
|
{name: "ss5.4", value: `${LONG_WORD}&${LONG_WORD}`},
|
||||||
], true],
|
], true],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj1"]],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"]],
|
||||||
[1, [
|
[1, [
|
||||||
{name: 1, value: JSON.stringify({id: 1, name: "foo", email: "foo@bar.com"})}
|
{name: 1, value: JSON.stringify({id: 1, name: "foo", email: "foo@bar.com"})}
|
||||||
]],
|
]],
|
||||||
|
|
@ -133,7 +133,7 @@ const testCases = [
|
||||||
{name: "1.name", value: "foo"},
|
{name: "1.name", value: "foo"},
|
||||||
{name: "1.email", value: "foo@bar.com"},
|
{name: "1.email", value: "foo@bar.com"},
|
||||||
], true],
|
], true],
|
||||||
[["indexedDB", "http://test1.example.org", "idb1", "obj2"]],
|
[["indexedDB", "http://test1.example.org", "idb1 (default)", "obj2"]],
|
||||||
[1, [
|
[1, [
|
||||||
{name: 1, value: JSON.stringify({
|
{name: 1, value: JSON.stringify({
|
||||||
id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"
|
id2: 1, name: "foo", email: "foo@bar.com", extra: "baz"
|
||||||
|
|
|
||||||
|
|
@ -879,3 +879,19 @@ var focusSearchBoxUsingShortcut = Task.async(function* (panelWin, callback) {
|
||||||
function getCookieId(name, domain, path) {
|
function getCookieId(name, domain, path) {
|
||||||
return `${name}${SEPARATOR_GUID}${domain}${SEPARATOR_GUID}${path}`;
|
return `${name}${SEPARATOR_GUID}${domain}${SEPARATOR_GUID}${path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPermission(url, permission) {
|
||||||
|
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
|
||||||
|
|
||||||
|
let uri = Components.classes["@mozilla.org/network/io-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIIOService)
|
||||||
|
.newURI(url, null, null);
|
||||||
|
let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||||
|
.getService(Ci.nsIScriptSecurityManager);
|
||||||
|
let principal = ssm.createCodebasePrincipal(uri, {});
|
||||||
|
|
||||||
|
Components.classes["@mozilla.org/permissionmanager;1"]
|
||||||
|
.getService(nsIPermissionManager)
|
||||||
|
.addFromPrincipal(principal, permission,
|
||||||
|
nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html><head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Storage inspector IndexedDBs with duplicate names</title>
|
||||||
|
|
||||||
|
<script type="application/javascript;version=1.7">
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function createIndexedDBs() {
|
||||||
|
createIndexedDB("idb1", "temporary");
|
||||||
|
createIndexedDB("idb1", "default");
|
||||||
|
createIndexedDB("idb1", "persistent");
|
||||||
|
createIndexedDB("idb2", "temporary");
|
||||||
|
createIndexedDB("idb2", "default");
|
||||||
|
createIndexedDB("idb2", "persistent");
|
||||||
|
}
|
||||||
|
|
||||||
|
function createIndexedDB(name, storage) {
|
||||||
|
let open = indexedDB.open(name, {storage: storage});
|
||||||
|
|
||||||
|
open.onsuccess = function () {
|
||||||
|
let db = open.result;
|
||||||
|
db.close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDB(dbName, storage) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
dump(`removing database ${dbName} (${storage}) from ${document.location}\n`);
|
||||||
|
indexedDB.deleteDatabase(dbName, { storage: storage }).onsuccess = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.clear = function* () {
|
||||||
|
yield deleteDB("idb1", "temporary");
|
||||||
|
yield deleteDB("idb1", "default");
|
||||||
|
yield deleteDB("idb1", "persistent");
|
||||||
|
yield deleteDB("idb2", "temporary");
|
||||||
|
yield deleteDB("idb2", "default");
|
||||||
|
yield deleteDB("idb2", "persistent");
|
||||||
|
|
||||||
|
dump(`removed indexedDB data from ${document.location}\n`);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="createIndexedDBs()">
|
||||||
|
<h1>storage-indexeddb-duplicate-names.html</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -809,7 +809,10 @@ StorageUI.prototype = {
|
||||||
columns[f.name] = f.name;
|
columns[f.name] = f.name;
|
||||||
let columnName;
|
let columnName;
|
||||||
try {
|
try {
|
||||||
columnName = L10N.getStr("table.headers." + type + "." + f.name);
|
// Path key names for l10n in the case of a string change.
|
||||||
|
let name = f.name === "keyPath" ? "keyPath2" : f.name;
|
||||||
|
|
||||||
|
columnName = L10N.getStr("table.headers." + type + "." + name);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
columnName = COOKIE_KEY_MAP[f.name];
|
columnName = COOKIE_KEY_MAP[f.name];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/* globals StopIteration */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const {Cc, Ci, Cu, CC} = require("chrome");
|
const {Cc, Ci, Cu, CC} = require("chrome");
|
||||||
|
|
@ -93,7 +95,7 @@ var StorageActors = {};
|
||||||
* - observe : Method which gets triggered on the notificaiton of the watched
|
* - observe : Method which gets triggered on the notificaiton of the watched
|
||||||
* topic.
|
* topic.
|
||||||
* - getNamesForHost : Given a host, get list of all known store names.
|
* - getNamesForHost : Given a host, get list of all known store names.
|
||||||
* - getValuesForHost : Given a host (and optianally a name) get all known
|
* - getValuesForHost : Given a host (and optionally a name) get all known
|
||||||
* store objects.
|
* store objects.
|
||||||
* - toStoreObject : Given a store object, convert it to the required format
|
* - toStoreObject : Given a store object, convert it to the required format
|
||||||
* so that it can be transferred over wire.
|
* so that it can be transferred over wire.
|
||||||
|
|
@ -141,6 +143,9 @@ StorageActors.defaults = function (typeName, observationTopic) {
|
||||||
* Converts the window.location object into host.
|
* Converts the window.location object into host.
|
||||||
*/
|
*/
|
||||||
getHostName(location) {
|
getHostName(location) {
|
||||||
|
if (location.protocol === "chrome:") {
|
||||||
|
return location.href;
|
||||||
|
}
|
||||||
return location.hostname || location.href;
|
return location.hostname || location.href;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -744,6 +749,7 @@ var cookieHelpers = {
|
||||||
|
|
||||||
let enumerator =
|
let enumerator =
|
||||||
Services.cookies.getCookiesFromHost(origHost, data.originAttributes || {});
|
Services.cookies.getCookiesFromHost(origHost, data.originAttributes || {});
|
||||||
|
|
||||||
while (enumerator.hasMoreElements()) {
|
while (enumerator.hasMoreElements()) {
|
||||||
let nsiCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
let nsiCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
||||||
if (nsiCookie.name === origName &&
|
if (nsiCookie.name === origName &&
|
||||||
|
|
@ -1041,6 +1047,9 @@ function getObjectForLocalOrSessionStorage(type) {
|
||||||
if (!location.host) {
|
if (!location.host) {
|
||||||
return location.href;
|
return location.href;
|
||||||
}
|
}
|
||||||
|
if (location.protocol === "chrome:") {
|
||||||
|
return location.href;
|
||||||
|
}
|
||||||
return location.protocol + "//" + location.host;
|
return location.protocol + "//" + location.host;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1251,6 +1260,9 @@ StorageActors.createActor({
|
||||||
if (!location.host) {
|
if (!location.host) {
|
||||||
return location.href;
|
return location.href;
|
||||||
}
|
}
|
||||||
|
if (location.protocol === "chrome:") {
|
||||||
|
return location.href;
|
||||||
|
}
|
||||||
return location.protocol + "//" + location.host;
|
return location.protocol + "//" + location.host;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1423,12 +1435,15 @@ ObjectStoreMetadata.prototype = {
|
||||||
* The host associated with this indexed db.
|
* The host associated with this indexed db.
|
||||||
* @param {IDBDatabase} db
|
* @param {IDBDatabase} db
|
||||||
* The particular indexed db.
|
* The particular indexed db.
|
||||||
|
* @param {String} storage
|
||||||
|
* Storage type, either "temporary", "default" or "persistent".
|
||||||
*/
|
*/
|
||||||
function DatabaseMetadata(origin, db) {
|
function DatabaseMetadata(origin, db, storage) {
|
||||||
this._origin = origin;
|
this._origin = origin;
|
||||||
this._name = db.name;
|
this._name = db.name;
|
||||||
this._version = db.version;
|
this._version = db.version;
|
||||||
this._objectStores = [];
|
this._objectStores = [];
|
||||||
|
this.storage = storage;
|
||||||
|
|
||||||
if (db.objectStoreNames.length) {
|
if (db.objectStoreNames.length) {
|
||||||
let transaction = db.transaction(db.objectStoreNames, "readonly");
|
let transaction = db.transaction(db.objectStoreNames, "readonly");
|
||||||
|
|
@ -1448,7 +1463,7 @@ DatabaseMetadata.prototype = {
|
||||||
|
|
||||||
toObject() {
|
toObject() {
|
||||||
return {
|
return {
|
||||||
name: this._name,
|
name: `${this._name} (${this.storage})`,
|
||||||
origin: this._origin,
|
origin: this._origin,
|
||||||
version: this._version,
|
version: this._version,
|
||||||
objectStores: this._objectStores.size
|
objectStores: this._objectStores.size
|
||||||
|
|
@ -1524,6 +1539,9 @@ StorageActors.createActor({
|
||||||
if (!location.host) {
|
if (!location.host) {
|
||||||
return location.href;
|
return location.href;
|
||||||
}
|
}
|
||||||
|
if (location.protocol === "chrome:") {
|
||||||
|
return location.href;
|
||||||
|
}
|
||||||
return location.protocol + "//" + location.host;
|
return location.protocol + "//" + location.host;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1616,15 +1634,17 @@ StorageActors.createActor({
|
||||||
populateStoresForHost: Task.async(function* (host) {
|
populateStoresForHost: Task.async(function* (host) {
|
||||||
let storeMap = new Map();
|
let storeMap = new Map();
|
||||||
let {names} = yield this.getDBNamesForHost(host);
|
let {names} = yield this.getDBNamesForHost(host);
|
||||||
|
|
||||||
let win = this.storageActor.getWindowFromHost(host);
|
let win = this.storageActor.getWindowFromHost(host);
|
||||||
if (win) {
|
if (win) {
|
||||||
let principal = win.document.nodePrincipal;
|
let principal = win.document.nodePrincipal;
|
||||||
|
|
||||||
for (let name of names) {
|
for (let {name, storage} of names) {
|
||||||
let metadata = yield this.getDBMetaData(host, principal, name);
|
let metadata = yield this.getDBMetaData(host, principal, name, storage);
|
||||||
|
|
||||||
metadata = indexedDBHelpers.patchMetadataMapsAndProtos(metadata);
|
metadata = indexedDBHelpers.patchMetadataMapsAndProtos(metadata);
|
||||||
storeMap.set(name, metadata);
|
|
||||||
|
storeMap.set(`${name} (${storage})`, metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1657,10 +1677,22 @@ StorageActors.createActor({
|
||||||
objectStores: item.objectStores
|
objectStores: item.objectStores
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let value = JSON.stringify(item.value);
|
||||||
|
|
||||||
|
// FIXME: Bug 1318029 - Due to a bug that is thrown whenever a
|
||||||
|
// LongStringActor string reaches DebuggerServer.LONG_STRING_LENGTH we need
|
||||||
|
// to trim the value. When the bug is fixed we should stop trimming the
|
||||||
|
// string here.
|
||||||
|
let maxLength = DebuggerServer.LONG_STRING_LENGTH - 1;
|
||||||
|
if (value.length > maxLength) {
|
||||||
|
value = value.substr(0, maxLength);
|
||||||
|
}
|
||||||
|
|
||||||
// Indexed db entry
|
// Indexed db entry
|
||||||
return {
|
return {
|
||||||
name: item.name,
|
name: item.name,
|
||||||
value: new LongStringActor(this.conn, JSON.stringify(item.value))
|
value: new LongStringActor(this.conn, value)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1696,16 +1728,18 @@ StorageActors.createActor({
|
||||||
maybeSetupChildProcess() {
|
maybeSetupChildProcess() {
|
||||||
if (!DebuggerServer.isInChildProcess) {
|
if (!DebuggerServer.isInChildProcess) {
|
||||||
this.backToChild = (func, rv) => rv;
|
this.backToChild = (func, rv) => rv;
|
||||||
|
this.clearDBStore = indexedDBHelpers.clearDBStore;
|
||||||
|
this.gatherFilesOrFolders = indexedDBHelpers.gatherFilesOrFolders;
|
||||||
this.getDBMetaData = indexedDBHelpers.getDBMetaData;
|
this.getDBMetaData = indexedDBHelpers.getDBMetaData;
|
||||||
this.openWithPrincipal = indexedDBHelpers.openWithPrincipal;
|
|
||||||
this.getDBNamesForHost = indexedDBHelpers.getDBNamesForHost;
|
this.getDBNamesForHost = indexedDBHelpers.getDBNamesForHost;
|
||||||
this.getSanitizedHost = indexedDBHelpers.getSanitizedHost;
|
|
||||||
this.getNameFromDatabaseFile = indexedDBHelpers.getNameFromDatabaseFile;
|
this.getNameFromDatabaseFile = indexedDBHelpers.getNameFromDatabaseFile;
|
||||||
this.getValuesForHost = indexedDBHelpers.getValuesForHost;
|
|
||||||
this.getObjectStoreData = indexedDBHelpers.getObjectStoreData;
|
this.getObjectStoreData = indexedDBHelpers.getObjectStoreData;
|
||||||
|
this.getSanitizedHost = indexedDBHelpers.getSanitizedHost;
|
||||||
|
this.getValuesForHost = indexedDBHelpers.getValuesForHost;
|
||||||
|
this.openWithPrincipal = indexedDBHelpers.openWithPrincipal;
|
||||||
this.removeDB = indexedDBHelpers.removeDB;
|
this.removeDB = indexedDBHelpers.removeDB;
|
||||||
this.removeDBRecord = indexedDBHelpers.removeDBRecord;
|
this.removeDBRecord = indexedDBHelpers.removeDBRecord;
|
||||||
this.clearDBStore = indexedDBHelpers.clearDBStore;
|
this.splitNameAndStorage = indexedDBHelpers.splitNameAndStorage;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1718,6 +1752,7 @@ StorageActors.createActor({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getDBMetaData = callParentProcessAsync.bind(null, "getDBMetaData");
|
this.getDBMetaData = callParentProcessAsync.bind(null, "getDBMetaData");
|
||||||
|
this.splitNameAndStorage = callParentProcessAsync.bind(null, "splitNameAndStorage");
|
||||||
this.getDBNamesForHost = callParentProcessAsync.bind(null, "getDBNamesForHost");
|
this.getDBNamesForHost = callParentProcessAsync.bind(null, "getDBNamesForHost");
|
||||||
this.getValuesForHost = callParentProcessAsync.bind(null, "getValuesForHost");
|
this.getValuesForHost = callParentProcessAsync.bind(null, "getValuesForHost");
|
||||||
this.removeDB = callParentProcessAsync.bind(null, "removeDB");
|
this.removeDB = callParentProcessAsync.bind(null, "removeDB");
|
||||||
|
|
@ -1813,14 +1848,14 @@ var indexedDBHelpers = {
|
||||||
* `name` for the given `host` with its `principal`. The stored metadata
|
* `name` for the given `host` with its `principal`. The stored metadata
|
||||||
* information is of `DatabaseMetadata` type.
|
* information is of `DatabaseMetadata` type.
|
||||||
*/
|
*/
|
||||||
getDBMetaData: Task.async(function* (host, principal, name) {
|
getDBMetaData: Task.async(function* (host, principal, name, storage) {
|
||||||
let request = this.openWithPrincipal(principal, name);
|
let request = this.openWithPrincipal(principal, name, storage);
|
||||||
let success = promise.defer();
|
let success = promise.defer();
|
||||||
|
|
||||||
request.onsuccess = event => {
|
request.onsuccess = event => {
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
let dbData = new DatabaseMetadata(host, db);
|
let dbData = new DatabaseMetadata(host, db, storage);
|
||||||
db.close();
|
db.close();
|
||||||
|
|
||||||
success.resolve(this.backToChild("getDBMetaData", dbData));
|
success.resolve(this.backToChild("getDBMetaData", dbData));
|
||||||
|
|
@ -1833,21 +1868,37 @@ var indexedDBHelpers = {
|
||||||
return success.promise;
|
return success.promise;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
splitNameAndStorage: function (name) {
|
||||||
|
let lastOpenBracketIndex = name.lastIndexOf("(");
|
||||||
|
let lastCloseBracketIndex = name.lastIndexOf(")");
|
||||||
|
let delta = lastCloseBracketIndex - lastOpenBracketIndex - 1;
|
||||||
|
|
||||||
|
let storage = name.substr(lastOpenBracketIndex + 1, delta);
|
||||||
|
|
||||||
|
name = name.substr(0, lastOpenBracketIndex - 1);
|
||||||
|
|
||||||
|
return { storage, name };
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens an indexed db connection for the given `principal` and
|
* Opens an indexed db connection for the given `principal` and
|
||||||
* database `name`.
|
* database `name`.
|
||||||
*/
|
*/
|
||||||
openWithPrincipal(principal, name) {
|
openWithPrincipal: function (principal, name, storage) {
|
||||||
return indexedDBForStorage.openForPrincipal(principal, name);
|
return indexedDBForStorage.openForPrincipal(principal, name,
|
||||||
|
{ storage: storage });
|
||||||
},
|
},
|
||||||
|
|
||||||
removeDB: Task.async(function* (host, principal, name) {
|
removeDB: Task.async(function* (host, principal, dbName) {
|
||||||
let result = new promise(resolve => {
|
let result = new promise(resolve => {
|
||||||
let request = indexedDBForStorage.deleteForPrincipal(principal, name);
|
let {name, storage} = this.splitNameAndStorage(dbName);
|
||||||
|
let request =
|
||||||
|
indexedDBForStorage.deleteForPrincipal(principal, name,
|
||||||
|
{ storage: storage });
|
||||||
|
|
||||||
request.onsuccess = () => {
|
request.onsuccess = () => {
|
||||||
resolve({});
|
resolve({});
|
||||||
this.onItemUpdated("deleted", host, [name]);
|
this.onItemUpdated("deleted", host, [dbName]);
|
||||||
};
|
};
|
||||||
|
|
||||||
request.onblocked = () => {
|
request.onblocked = () => {
|
||||||
|
|
@ -1873,10 +1924,11 @@ var indexedDBHelpers = {
|
||||||
|
|
||||||
removeDBRecord: Task.async(function* (host, principal, dbName, storeName, id) {
|
removeDBRecord: Task.async(function* (host, principal, dbName, storeName, id) {
|
||||||
let db;
|
let db;
|
||||||
|
let {name, storage} = this.splitNameAndStorage(dbName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db = yield new promise((resolve, reject) => {
|
db = yield new promise((resolve, reject) => {
|
||||||
let request = this.openWithPrincipal(principal, dbName);
|
let request = this.openWithPrincipal(principal, name, storage);
|
||||||
request.onsuccess = ev => resolve(ev.target.result);
|
request.onsuccess = ev => resolve(ev.target.result);
|
||||||
request.onerror = ev => reject(ev.target.error);
|
request.onerror = ev => reject(ev.target.error);
|
||||||
});
|
});
|
||||||
|
|
@ -1905,10 +1957,11 @@ var indexedDBHelpers = {
|
||||||
|
|
||||||
clearDBStore: Task.async(function* (host, principal, dbName, storeName) {
|
clearDBStore: Task.async(function* (host, principal, dbName, storeName) {
|
||||||
let db;
|
let db;
|
||||||
|
let {name, storage} = this.splitNameAndStorage(dbName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db = yield new promise((resolve, reject) => {
|
db = yield new promise((resolve, reject) => {
|
||||||
let request = this.openWithPrincipal(principal, dbName);
|
let request = this.openWithPrincipal(principal, name, storage);
|
||||||
request.onsuccess = ev => resolve(ev.target.result);
|
request.onsuccess = ev => resolve(ev.target.result);
|
||||||
request.onerror = ev => reject(ev.target.error);
|
request.onerror = ev => reject(ev.target.error);
|
||||||
});
|
});
|
||||||
|
|
@ -1940,46 +1993,106 @@ var indexedDBHelpers = {
|
||||||
*/
|
*/
|
||||||
getDBNamesForHost: Task.async(function* (host) {
|
getDBNamesForHost: Task.async(function* (host) {
|
||||||
let sanitizedHost = this.getSanitizedHost(host);
|
let sanitizedHost = this.getSanitizedHost(host);
|
||||||
let directory = OS.Path.join(OS.Constants.Path.profileDir, "storage",
|
let profileDir = OS.Constants.Path.profileDir;
|
||||||
"default", sanitizedHost, "idb");
|
let files = [];
|
||||||
|
|
||||||
let exists = yield OS.File.exists(directory);
|
|
||||||
if (!exists && host.startsWith("about:")) {
|
|
||||||
// try for moz-safe-about directory
|
|
||||||
sanitizedHost = this.getSanitizedHost("moz-safe-" + host);
|
|
||||||
directory = OS.Path.join(OS.Constants.Path.profileDir, "storage",
|
|
||||||
"permanent", sanitizedHost, "idb");
|
|
||||||
exists = yield OS.File.exists(directory);
|
|
||||||
}
|
|
||||||
if (!exists) {
|
|
||||||
return this.backToChild("getDBNamesForHost", {names: []});
|
|
||||||
}
|
|
||||||
|
|
||||||
let names = [];
|
let names = [];
|
||||||
let dirIterator = new OS.File.DirectoryIterator(directory);
|
let storagePath = OS.Path.join(profileDir, "storage");
|
||||||
try {
|
|
||||||
yield dirIterator.forEach(file => {
|
|
||||||
// Skip directories.
|
|
||||||
if (file.isDir) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip any non-sqlite files.
|
// We expect sqlite DB paths to look something like this:
|
||||||
if (!file.name.endsWith(".sqlite")) {
|
// - PathToProfileDir/storage/default/http+++www.example.com/
|
||||||
return null;
|
// idb/1556056096MeysDaabta.sqlite
|
||||||
}
|
// - PathToProfileDir/storage/permanent/http+++www.example.com/
|
||||||
|
// idb/1556056096MeysDaabta.sqlite
|
||||||
|
// - PathToProfileDir/storage/temporary/http+++www.example.com/
|
||||||
|
// idb/1556056096MeysDaabta.sqlite
|
||||||
|
//
|
||||||
|
// The subdirectory inside the storage folder is determined by the storage
|
||||||
|
// type:
|
||||||
|
// - default: { storage: "default" } or not specified.
|
||||||
|
// - permanent: { storage: "persistent" }.
|
||||||
|
// - temporary: { storage: "temporary" }.
|
||||||
|
let sqliteFiles = yield this.gatherFilesOrFolders(storagePath, path => {
|
||||||
|
if (path.endsWith(".sqlite")) {
|
||||||
|
let { components } = OS.Path.split(path);
|
||||||
|
let isIDB = components[components.length - 2] === "idb";
|
||||||
|
|
||||||
return this.getNameFromDatabaseFile(file.path).then(name => {
|
return isIDB;
|
||||||
if (name) {
|
}
|
||||||
names.push(name);
|
return false;
|
||||||
}
|
});
|
||||||
return null;
|
|
||||||
|
for (let file of sqliteFiles) {
|
||||||
|
let splitPath = OS.Path.split(file).components;
|
||||||
|
let idbIndex = splitPath.indexOf("idb");
|
||||||
|
let name = splitPath[idbIndex - 1];
|
||||||
|
let storage = splitPath[idbIndex - 2];
|
||||||
|
let relative = file.substr(profileDir.length + 1);
|
||||||
|
|
||||||
|
if (name.startsWith(sanitizedHost)) {
|
||||||
|
files.push({
|
||||||
|
file: relative,
|
||||||
|
storage: storage === "permanent" ? "persistent" : storage
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
} finally {
|
|
||||||
dirIterator.close();
|
|
||||||
}
|
}
|
||||||
return this.backToChild("getDBNamesForHost", {names: names});
|
|
||||||
|
if (files.length > 0) {
|
||||||
|
for (let {file, storage} of files) {
|
||||||
|
let name = yield this.getNameFromDatabaseFile(file);
|
||||||
|
if (name) {
|
||||||
|
names.push({
|
||||||
|
name,
|
||||||
|
storage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.backToChild("getDBNamesForHost", {names});
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gather together all of the files in path and pass each path through a
|
||||||
|
* validation function.
|
||||||
|
*
|
||||||
|
* @param {String}
|
||||||
|
* Path in which to begin searching.
|
||||||
|
* @param {Function}
|
||||||
|
* Validation function, which checks each file path. If this function
|
||||||
|
* Returns true the file path is kept.
|
||||||
|
*
|
||||||
|
* @returns {Array}
|
||||||
|
* An array of file paths.
|
||||||
|
*/
|
||||||
|
gatherFilesOrFolders: Task.async(function* (path, validationFunc) {
|
||||||
|
let files = [];
|
||||||
|
let iterator;
|
||||||
|
let paths = [path];
|
||||||
|
|
||||||
|
while (paths.length > 0) {
|
||||||
|
try {
|
||||||
|
iterator = new OS.File.DirectoryIterator(paths.pop());
|
||||||
|
|
||||||
|
for (let child in iterator) {
|
||||||
|
child = yield child;
|
||||||
|
|
||||||
|
path = child.path;
|
||||||
|
|
||||||
|
if (child.isDir) {
|
||||||
|
paths.push(path);
|
||||||
|
} else if (validationFunc(path)) {
|
||||||
|
files.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
// Ignore StopIteration to prevent exiting the loop.
|
||||||
|
if (ex != StopIteration) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator.close();
|
||||||
|
|
||||||
|
return files;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1987,6 +2100,9 @@ var indexedDBHelpers = {
|
||||||
* name.
|
* name.
|
||||||
*/
|
*/
|
||||||
getSanitizedHost(host) {
|
getSanitizedHost(host) {
|
||||||
|
if (host.startsWith("about:")) {
|
||||||
|
host = "moz-safe-" + host;
|
||||||
|
}
|
||||||
return host.replace(ILLEGAL_CHAR_REGEX, "+");
|
return host.replace(ILLEGAL_CHAR_REGEX, "+");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -2000,7 +2116,7 @@ var indexedDBHelpers = {
|
||||||
|
|
||||||
// Content pages might be having an open transaction for the same indexed db
|
// Content pages might be having an open transaction for the same indexed db
|
||||||
// which this sqlite file belongs to. In that case, sqlite.openConnection
|
// which this sqlite file belongs to. In that case, sqlite.openConnection
|
||||||
// will throw. Thus we retey for some time to see if lock is removed.
|
// will throw. Thus we retry for some time to see if lock is removed.
|
||||||
while (!connection && retryCount++ < 25) {
|
while (!connection && retryCount++ < 25) {
|
||||||
try {
|
try {
|
||||||
connection = yield Sqlite.openConnection({ path: path });
|
connection = yield Sqlite.openConnection({ path: path });
|
||||||
|
|
@ -2061,8 +2177,14 @@ var indexedDBHelpers = {
|
||||||
return this.backToChild("getValuesForHost", {objectStores: objectStores});
|
return this.backToChild("getValuesForHost", {objectStores: objectStores});
|
||||||
}
|
}
|
||||||
// Get either all entries from the object store, or a particular id
|
// Get either all entries from the object store, or a particular id
|
||||||
let result = yield this.getObjectStoreData(host, principal, db2,
|
let storage = hostVsStores.get(host).get(db2).storage;
|
||||||
objectStore, id, options.index, options.size);
|
let result = yield this.getObjectStoreData(host, principal, db2, storage, {
|
||||||
|
objectStore: objectStore,
|
||||||
|
id: id,
|
||||||
|
index: options.index,
|
||||||
|
offset: 0,
|
||||||
|
size: options.size
|
||||||
|
});
|
||||||
return this.backToChild("getValuesForHost", {result: result});
|
return this.backToChild("getValuesForHost", {result: result});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -2076,23 +2198,27 @@ var indexedDBHelpers = {
|
||||||
* The principal of the given document.
|
* The principal of the given document.
|
||||||
* @param {string} dbName
|
* @param {string} dbName
|
||||||
* The name of the indexed db from the above host.
|
* The name of the indexed db from the above host.
|
||||||
* @param {string} objectStore
|
* @param {String} storage
|
||||||
* The name of the object store from the above db.
|
* Storage type, either "temporary", "default" or "persistent".
|
||||||
* @param {string} id
|
* @param {Object} requestOptions
|
||||||
* id of the requested entry from the above object store.
|
* An object in the following format:
|
||||||
* null if all entries from the above object store are requested.
|
* {
|
||||||
* @param {string} index
|
* objectStore: The name of the object store from the above db,
|
||||||
* name of the IDBIndex to be iterated on while fetching entries.
|
* id: Id of the requested entry from the above object
|
||||||
* null or "name" if no index is to be iterated.
|
* store. null if all entries from the above object
|
||||||
* @param {number} offset
|
* store are requested,
|
||||||
* ofsset of the entries to be fetched.
|
* index: Name of the IDBIndex to be iterated on while fetching
|
||||||
* @param {number} size
|
* entries. null or "name" if no index is to be
|
||||||
* The intended size of the entries to be fetched.
|
* iterated,
|
||||||
|
* offset: offset of the entries to be fetched,
|
||||||
|
* size: The intended size of the entries to be fetched
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
getObjectStoreData(host, principal, dbName, objectStore, id, index,
|
getObjectStoreData(host, principal, dbName, storage, requestOptions) {
|
||||||
offset, size) {
|
let {name} = this.splitNameAndStorage(dbName);
|
||||||
let request = this.openWithPrincipal(principal, dbName);
|
let request = this.openWithPrincipal(principal, name, storage);
|
||||||
let success = promise.defer();
|
let success = promise.defer();
|
||||||
|
let {objectStore, id, index, offset, size} = requestOptions;
|
||||||
let data = [];
|
let data = [];
|
||||||
let db;
|
let db;
|
||||||
|
|
||||||
|
|
@ -2194,8 +2320,12 @@ var indexedDBHelpers = {
|
||||||
|
|
||||||
switch (msg.json.method) {
|
switch (msg.json.method) {
|
||||||
case "getDBMetaData": {
|
case "getDBMetaData": {
|
||||||
let [host, principal, name] = args;
|
let [host, principal, name, storage] = args;
|
||||||
return indexedDBHelpers.getDBMetaData(host, principal, name);
|
return indexedDBHelpers.getDBMetaData(host, principal, name, storage);
|
||||||
|
}
|
||||||
|
case "splitNameAndStorage": {
|
||||||
|
let [name] = args;
|
||||||
|
return indexedDBHelpers.splitNameAndStorage(name);
|
||||||
}
|
}
|
||||||
case "getDBNamesForHost": {
|
case "getDBNamesForHost": {
|
||||||
let [host] = args;
|
let [host] = args;
|
||||||
|
|
@ -2207,8 +2337,8 @@ var indexedDBHelpers = {
|
||||||
hostVsStores, principal);
|
hostVsStores, principal);
|
||||||
}
|
}
|
||||||
case "removeDB": {
|
case "removeDB": {
|
||||||
let [host, principal, name] = args;
|
let [host, principal, dbName] = args;
|
||||||
return indexedDBHelpers.removeDB(host, principal, name);
|
return indexedDBHelpers.removeDB(host, principal, dbName);
|
||||||
}
|
}
|
||||||
case "removeDBRecord": {
|
case "removeDBRecord": {
|
||||||
let [host, principal, db, store, id] = args;
|
let [host, principal, db, store, id] = args;
|
||||||
|
|
|
||||||
|
|
@ -121,24 +121,24 @@ const storeMap = {
|
||||||
const IDBValues = {
|
const IDBValues = {
|
||||||
listStoresResponse: {
|
listStoresResponse: {
|
||||||
"http://test1.example.org": [
|
"http://test1.example.org": [
|
||||||
["idb1", "obj1"], ["idb1", "obj2"], ["idb2", "obj3"]
|
["idb1 (default)", "obj1"], ["idb1 (default)", "obj2"], ["idb2 (default)", "obj3"]
|
||||||
],
|
],
|
||||||
"http://sectest1.example.org": [
|
"http://sectest1.example.org": [
|
||||||
],
|
],
|
||||||
"https://sectest1.example.org": [
|
"https://sectest1.example.org": [
|
||||||
["idb-s1", "obj-s1"], ["idb-s2", "obj-s2"]
|
["idb-s1 (default)", "obj-s1"], ["idb-s2 (default)", "obj-s2"]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
dbDetails : {
|
dbDetails: {
|
||||||
"http://test1.example.org": [
|
"http://test1.example.org": [
|
||||||
{
|
{
|
||||||
db: "idb1",
|
db: "idb1 (default)",
|
||||||
origin: "http://test1.example.org",
|
origin: "http://test1.example.org",
|
||||||
version: 1,
|
version: 1,
|
||||||
objectStores: 2
|
objectStores: 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
db: "idb2",
|
db: "idb2 (default)",
|
||||||
origin: "http://test1.example.org",
|
origin: "http://test1.example.org",
|
||||||
version: 1,
|
version: 1,
|
||||||
objectStores: 1
|
objectStores: 1
|
||||||
|
|
@ -148,13 +148,13 @@ const IDBValues = {
|
||||||
],
|
],
|
||||||
"https://sectest1.example.org": [
|
"https://sectest1.example.org": [
|
||||||
{
|
{
|
||||||
db: "idb-s1",
|
db: "idb-s1 (default)",
|
||||||
origin: "https://sectest1.example.org",
|
origin: "https://sectest1.example.org",
|
||||||
version: 1,
|
version: 1,
|
||||||
objectStores: 1
|
objectStores: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
db: "idb-s2",
|
db: "idb-s2 (default)",
|
||||||
origin: "https://sectest1.example.org",
|
origin: "https://sectest1.example.org",
|
||||||
version: 1,
|
version: 1,
|
||||||
objectStores: 1
|
objectStores: 1
|
||||||
|
|
@ -163,7 +163,7 @@ const IDBValues = {
|
||||||
},
|
},
|
||||||
objectStoreDetails: {
|
objectStoreDetails: {
|
||||||
"http://test1.example.org": {
|
"http://test1.example.org": {
|
||||||
idb1: [
|
"idb1 (default)": [
|
||||||
{
|
{
|
||||||
objectStore: "obj1",
|
objectStore: "obj1",
|
||||||
keyPath: "id",
|
keyPath: "id",
|
||||||
|
|
@ -190,7 +190,7 @@ const IDBValues = {
|
||||||
indexes: []
|
indexes: []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
idb2: [
|
"idb2 (default)": [
|
||||||
{
|
{
|
||||||
objectStore: "obj3",
|
objectStore: "obj3",
|
||||||
keyPath: "id3",
|
keyPath: "id3",
|
||||||
|
|
@ -208,7 +208,7 @@ const IDBValues = {
|
||||||
},
|
},
|
||||||
"http://sectest1.example.org" : {},
|
"http://sectest1.example.org" : {},
|
||||||
"https://sectest1.example.org": {
|
"https://sectest1.example.org": {
|
||||||
"idb-s1": [
|
"idb-s1 (default)": [
|
||||||
{
|
{
|
||||||
objectStore: "obj-s1",
|
objectStore: "obj-s1",
|
||||||
keyPath: "id",
|
keyPath: "id",
|
||||||
|
|
@ -216,7 +216,7 @@ const IDBValues = {
|
||||||
indexes: []
|
indexes: []
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"idb-s2": [
|
"idb-s2 (default)": [
|
||||||
{
|
{
|
||||||
objectStore: "obj-s2",
|
objectStore: "obj-s2",
|
||||||
keyPath: "id3",
|
keyPath: "id3",
|
||||||
|
|
@ -236,7 +236,7 @@ const IDBValues = {
|
||||||
},
|
},
|
||||||
entries: {
|
entries: {
|
||||||
"http://test1.example.org": {
|
"http://test1.example.org": {
|
||||||
"idb1#obj1": [
|
"idb1 (default)#obj1": [
|
||||||
{
|
{
|
||||||
name: 1,
|
name: 1,
|
||||||
value: {
|
value: {
|
||||||
|
|
@ -262,7 +262,7 @@ const IDBValues = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idb1#obj2": [
|
"idb1 (default)#obj2": [
|
||||||
{
|
{
|
||||||
name: 1,
|
name: 1,
|
||||||
value: {
|
value: {
|
||||||
|
|
@ -273,11 +273,11 @@ const IDBValues = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idb2#obj3": []
|
"idb2 (default)#obj3": []
|
||||||
},
|
},
|
||||||
"http://sectest1.example.org" : {},
|
"http://sectest1.example.org" : {},
|
||||||
"https://sectest1.example.org": {
|
"https://sectest1.example.org": {
|
||||||
"idb-s1#obj-s1": [
|
"idb-s1 (default)#obj-s1": [
|
||||||
{
|
{
|
||||||
name: 6,
|
name: 6,
|
||||||
value: {
|
value: {
|
||||||
|
|
@ -295,7 +295,7 @@ const IDBValues = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idb-s2#obj-s2": [
|
"idb-s2 (default)#obj-s2": [
|
||||||
{
|
{
|
||||||
name: 13,
|
name: 13,
|
||||||
value: {
|
value: {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ types.addDictType("cookiestoreobject", {
|
||||||
|
|
||||||
// Common methods for edit/remove
|
// Common methods for edit/remove
|
||||||
const editRemoveMethods = {
|
const editRemoveMethods = {
|
||||||
getEditableFields: {
|
getFields: {
|
||||||
request: {},
|
request: {},
|
||||||
response: {
|
response: {
|
||||||
value: RetVal("json")
|
value: RetVal("json")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue