Bug 1355576 - Add ability to clear all localStorage with the browsingData API; r=bsilverberg,janv

MozReview-Commit-ID: 4UUqg62yIo9

--HG--
extra : rebase_source : d38ee312dbfb3b7f46893d7af200b564876c82d1
This commit is contained in:
Thomas Wisniewski 2017-07-04 20:59:26 -04:00
Родитель 2b4bb85b58
Коммит 5eeefa573d
7 изменённых файлов: 118 добавлений и 3 удалений

Просмотреть файл

@ -83,6 +83,10 @@ const clearHistory = options => {
return sanitizer.items.history.clear(makeRange(options));
};
const clearLocalStorage = async function(options) {
Services.obs.notifyObservers(null, "extension:purge-localStorage");
};
const clearPasswords = async function(options) {
let loginManager = Services.logins;
let yieldCounter = 0;
@ -152,6 +156,9 @@ const doRemoval = (options, dataToRemove, extension) => {
case "history":
removalPromises.push(clearHistory(options));
break;
case "localStorage":
removalPromises.push(clearLocalStorage(options));
break;
case "passwords":
removalPromises.push(clearPasswords(options));
break;
@ -225,6 +232,9 @@ this.browsingData = class extends ExtensionAPI {
removeHistory(options) {
return doRemoval(options, {history: true});
},
removeLocalStorage(options) {
return doRemoval(options, {localStorage: true});
},
removePasswords(options) {
return doRemoval(options, {passwords: true});
},

Просмотреть файл

@ -341,7 +341,6 @@
"description": "Clears websites' local storage data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",

Просмотреть файл

@ -46,6 +46,7 @@ skip-if = (os == 'win' && !debug) # bug 1352668
[browser_ext_browserAction_theme_icons.js]
[browser_ext_browsingData_formData.js]
[browser_ext_browsingData_history.js]
[browser_ext_browsingData_localStorage.js]
[browser_ext_browsingData_pluginData.js]
[browser_ext_browsingData_serviceWorkers.js]
[browser_ext_commands_execute_browser_action.js]

Просмотреть файл

@ -0,0 +1,93 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
add_task(async function testLocalStorage() {
async function background() {
function openTabs() {
let promise = new Promise(resolve => {
let tabURLs = [
"http://example.com/",
"http://example.net/",
];
let tabs;
let waitingCount = tabURLs.length;
let listener = async msg => {
if (msg !== "content-script-ready" || --waitingCount) {
return;
}
browser.runtime.onMessage.removeListener(listener);
resolve(Promise.all(tabs));
};
browser.runtime.onMessage.addListener(listener);
tabs = tabURLs.map(url => {
return browser.tabs.create({url: url});
});
});
return promise;
}
function sendMessageToTabs(tabs, message) {
return Promise.all(
tabs.map(tab => { return browser.tabs.sendMessage(tab.id, message); }));
}
let tabs = await openTabs();
await sendMessageToTabs(tabs, "resetLocalStorage");
await sendMessageToTabs(tabs, "checkLocalStorageSet");
await browser.browsingData.removeLocalStorage({});
await sendMessageToTabs(tabs, "checkLocalStorageCleared");
await sendMessageToTabs(tabs, "resetLocalStorage");
await sendMessageToTabs(tabs, "checkLocalStorageSet");
await browser.browsingData.remove({}, {localStorage: true});
await sendMessageToTabs(tabs, "checkLocalStorageCleared");
browser.tabs.remove(tabs.map(tab => tab.id));
browser.test.notifyPass("done");
}
function contentScript() {
browser.runtime.onMessage.addListener(msg => {
if (msg === "resetLocalStorage") {
localStorage.clear();
localStorage.setItem("test", "test");
} else if (msg === "checkLocalStorageSet") {
browser.test.assertEq("test", localStorage.getItem("test"));
} else if (msg === "checkLocalStorageCleared") {
browser.test.assertEq(null, localStorage.getItem("test"));
}
});
browser.runtime.sendMessage("content-script-ready");
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
"permissions": ["browsingData"],
"content_scripts": [{
"matches": [
"http://example.com/",
"http://example.net/",
],
"js": ["content-script.js"],
"run_at": "document_start",
}],
},
files: {
"content-script.js": contentScript,
},
});
await extension.startup();
await extension.awaitFinish("done");
await extension.unload();
});

Просмотреть файл

@ -386,7 +386,8 @@ LocalStorageManager::Observe(const char* aTopic,
}
// Clear everything, caches + database
if (!strcmp(aTopic, "cookie-cleared")) {
if (!strcmp(aTopic, "cookie-cleared") ||
!strcmp(aTopic, "extension:purge-localStorage-caches")) {
ClearCaches(LocalStorageCache::kUnloadComplete, pattern, EmptyCString());
return NS_OK;
}

Просмотреть файл

@ -66,6 +66,7 @@ StorageObserver::Init()
obs->AddObserver(sSelf, "browser:purge-domain-data", true);
obs->AddObserver(sSelf, "last-pb-context-exited", true);
obs->AddObserver(sSelf, "clear-origin-attributes-data", true);
obs->AddObserver(sSelf, "extension:purge-localStorage", true);
// Shutdown
obs->AddObserver(sSelf, "profile-after-change", true);
@ -252,6 +253,17 @@ StorageObserver::Observe(nsISupports* aSubject,
return NS_OK;
}
if (!strcmp(aTopic, "extension:purge-localStorage")) {
StorageDBBridge* db = LocalStorageCache::StartDatabase();
NS_ENSURE_TRUE(db, NS_ERROR_FAILURE);
db->AsyncClearAll();
Notify("extension:purge-localStorage-caches");
return NS_OK;
}
// Clear everything (including so and pb data) from caches and database
// for the gived domain and subdomains.
if (!strcmp(aTopic, "browser:purge-domain-data")) {

Просмотреть файл

@ -345,7 +345,6 @@
"description": "Clears websites' local storage data.",
"type": "function",
"async": "callback",
"unsupported": true,
"parameters": [
{
"$ref": "RemovalOptions",