зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1003860 - Service worker cache for storage actor. r=mratcliffe
This commit is contained in:
Родитель
967f4a01c6
Коммит
a6f117c118
|
@ -54,6 +54,7 @@ tree.labels.cookies=Cookies
|
|||
tree.labels.localStorage=Local Storage
|
||||
tree.labels.sessionStorage=Session Storage
|
||||
tree.labels.indexedDB=Indexed DB
|
||||
tree.labels.Cache=Cache Storage
|
||||
|
||||
# LOCALIZATION NOTE (table.headers.*.*):
|
||||
# These strings are the header names of the columns in the Storage Table for
|
||||
|
@ -84,6 +85,9 @@ table.headers.localStorage.value=Value
|
|||
table.headers.sessionStorage.name=Key
|
||||
table.headers.sessionStorage.value=Value
|
||||
|
||||
table.headers.Cache.url=URL
|
||||
table.headers.Cache.status=Status
|
||||
|
||||
table.headers.indexedDB.name=Key
|
||||
table.headers.indexedDB.db=Database Name
|
||||
table.headers.indexedDB.objectStore=Object Store Name
|
||||
|
|
|
@ -61,6 +61,9 @@ const testCases = [
|
|||
[6, 7]],
|
||||
[["indexedDB", "https://sectest1.example.org", "idb-s2", "obj-s2"],
|
||||
[16]],
|
||||
[["Cache", "http://test1.example.org", "plop"],
|
||||
[MAIN_DOMAIN + "404_cached_file.js", MAIN_DOMAIN + "browser_storage_basic.js"]],
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,8 @@ const SPLIT_CONSOLE_PREF = "devtools.toolbox.splitconsoleEnabled";
|
|||
const STORAGE_PREF = "devtools.storage.enabled";
|
||||
const DUMPEMIT_PREF = "devtools.dump.emit";
|
||||
const DEBUGGERLOG_PREF = "devtools.debugger.log";
|
||||
// Allows Cache API to be working on usage `http` test page
|
||||
const CACHES_ON_HTTP_PREF = "dom.caches.testing.enabled";
|
||||
const PATH = "browser/devtools/client/storage/test/";
|
||||
const MAIN_DOMAIN = "http://test1.example.org/" + PATH;
|
||||
const ALT_DOMAIN = "http://sectest1.example.org/" + PATH;
|
||||
|
@ -27,6 +29,7 @@ var gToolbox, gPanelWindow, gWindow, gUI;
|
|||
// Services.prefs.setBoolPref(DEBUGGERLOG_PREF, true);
|
||||
|
||||
Services.prefs.setBoolPref(STORAGE_PREF, true);
|
||||
Services.prefs.setBoolPref(CACHES_ON_HTTP_PREF, true);
|
||||
DevToolsUtils.testing = true;
|
||||
registerCleanupFunction(() => {
|
||||
gToolbox = gPanelWindow = gWindow = gUI = null;
|
||||
|
@ -34,6 +37,7 @@ registerCleanupFunction(() => {
|
|||
Services.prefs.clearUserPref(SPLIT_CONSOLE_PREF);
|
||||
Services.prefs.clearUserPref(DUMPEMIT_PREF);
|
||||
Services.prefs.clearUserPref(DEBUGGERLOG_PREF);
|
||||
Services.prefs.clearUserPref(CACHES_ON_HTTP_PREF);
|
||||
DevToolsUtils.testing = false;
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
|
|
|
@ -97,8 +97,15 @@ function deleteDB(dbName) {
|
|||
});
|
||||
}
|
||||
|
||||
let cacheGenerator = function*() {
|
||||
let cache = yield caches.open("plop");
|
||||
yield cache.add("404_cached_file.js");
|
||||
yield cache.add("browser_storage_basic.js");
|
||||
};
|
||||
|
||||
window.setup = function*() {
|
||||
yield idbGenerator();
|
||||
yield cacheGenerator();
|
||||
};
|
||||
|
||||
window.clear = function*() {
|
||||
|
@ -115,6 +122,8 @@ window.clear = function*() {
|
|||
yield deleteDB("idb1");
|
||||
yield deleteDB("idb2");
|
||||
|
||||
yield caches.delete("plop");
|
||||
|
||||
dump("removed cookies, localStorage, sessionStorage and indexedDB data " +
|
||||
"from " + document.location + "\n");
|
||||
};
|
||||
|
|
|
@ -922,6 +922,125 @@ StorageActors.createActor({
|
|||
storeObjectType: "storagestoreobject"
|
||||
}, getObjectForLocalOrSessionStorage("sessionStorage"));
|
||||
|
||||
|
||||
let CacheAttributes = [
|
||||
"url",
|
||||
"status",
|
||||
];
|
||||
types.addDictType("cacheobject", {
|
||||
"url": "string",
|
||||
"status": "string"
|
||||
});
|
||||
|
||||
// Array of Cache store objects
|
||||
types.addDictType("cachestoreobject", {
|
||||
total: "number",
|
||||
offset: "number",
|
||||
data: "array:nullable:cacheobject"
|
||||
});
|
||||
|
||||
StorageActors.createActor({
|
||||
typeName: "Cache",
|
||||
storeObjectType: "cachestoreobject"
|
||||
}, {
|
||||
getCachesForHost: Task.async(function*(host) {
|
||||
let uri = Services.io.newURI(host, null, null);
|
||||
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
|
||||
|
||||
// The first argument tells if you want to get |content| cache or |chrome| cache.
|
||||
// The |content| cache is the cache explicitely named by the web content
|
||||
// (service worker or web page).
|
||||
// The |chrome| cache is the cache implicitely cached by the platform, hosting the
|
||||
// source file of the service worker.
|
||||
let { CacheStorage } = this.storageActor.window;
|
||||
let cache = new CacheStorage("content", principal);
|
||||
return cache;
|
||||
}),
|
||||
|
||||
preListStores: Task.async(function*() {
|
||||
this.hostVsStores = new Map();
|
||||
for (let host of this.hosts) {
|
||||
yield this.populateStoresForHost(host);
|
||||
}
|
||||
}),
|
||||
|
||||
form: function(form, detail) {
|
||||
if (detail === "actorid") {
|
||||
return this.actorID;
|
||||
}
|
||||
|
||||
let hosts = {};
|
||||
for (let host of this.hosts) {
|
||||
hosts[host] = this.getNamesForHost(host);
|
||||
}
|
||||
|
||||
return {
|
||||
actor: this.actorID,
|
||||
hosts: hosts
|
||||
};
|
||||
},
|
||||
|
||||
getNamesForHost: function(host) {
|
||||
// UI code expect each name to be a JSON string of an array :/
|
||||
return [...this.hostVsStores.get(host).keys()].map(a => JSON.stringify([a]));
|
||||
},
|
||||
|
||||
getValuesForHost: Task.async(function*(host, name) {
|
||||
if (!name) return [];
|
||||
// UI is weird and expect a JSON stringified array... and pass it back :/
|
||||
name = JSON.parse(name)[0];
|
||||
|
||||
let cache = this.hostVsStores.get(host).get(name);
|
||||
let requests = yield cache.keys();
|
||||
let results = [];
|
||||
for(let request of requests) {
|
||||
let response = yield cache.match(request);
|
||||
// Unwrap the response to get access to all its properties if the
|
||||
// response happen to be 'opaque', when it is a Cross Origin Request.
|
||||
response = response.cloneUnfiltered();
|
||||
results.push(yield this.processEntry(request, response));
|
||||
}
|
||||
return results;
|
||||
}),
|
||||
|
||||
processEntry: Task.async(function*(request, response) {
|
||||
return {
|
||||
url: String(request.url),
|
||||
status: String(response.statusText),
|
||||
};
|
||||
}),
|
||||
|
||||
getHostName: function(location) {
|
||||
if (!location.host) {
|
||||
return location.href;
|
||||
}
|
||||
return location.protocol + "//" + location.host;
|
||||
},
|
||||
|
||||
populateStoresForHost: Task.async(function*(host, window) {
|
||||
let storeMap = new Map();
|
||||
let caches = yield this.getCachesForHost(host);
|
||||
for (let name of (yield caches.keys())) {
|
||||
storeMap.set(name, (yield caches.open(name)));
|
||||
}
|
||||
this.hostVsStores.set(host, storeMap);
|
||||
}),
|
||||
|
||||
populateStoresForHosts: function() {},
|
||||
|
||||
/**
|
||||
* Given a url, correctly determine its protocol + hostname part.
|
||||
*/
|
||||
getSchemaAndHost: function(url) {
|
||||
let uri = Services.io.newURI(url, null, null);
|
||||
return uri.scheme + "://" + uri.hostPort;
|
||||
},
|
||||
|
||||
toStoreObject: function(item) {
|
||||
return item;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Code related to the Indexed DB actor and front
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче