зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1231437 - Storage Inspector: context menu to remove cookie/storage item r=mratcliffe
--HG-- extra : rebase_source : 9fa5cccee28309f9da368275f6cb80f684aaa39f
This commit is contained in:
Родитель
33f188faf9
Коммит
cc61dccc0d
|
@ -306,3 +306,50 @@ function evalInDebuggee (mm, script) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for a context menu popup to open.
|
||||||
|
*
|
||||||
|
* @param nsIDOMElement popup
|
||||||
|
* The XUL popup you expect to open.
|
||||||
|
* @param nsIDOMElement button
|
||||||
|
* The button/element that receives the contextmenu event. This is
|
||||||
|
* expected to open the popup.
|
||||||
|
* @param function onShown
|
||||||
|
* Function to invoke on popupshown event.
|
||||||
|
* @param function onHidden
|
||||||
|
* Function to invoke on popuphidden event.
|
||||||
|
* @return object
|
||||||
|
* A Promise object that is resolved after the popuphidden event
|
||||||
|
* callback is invoked.
|
||||||
|
*/
|
||||||
|
function waitForContextMenu(popup, button, onShown, onHidden) {
|
||||||
|
let deferred = promise.defer();
|
||||||
|
|
||||||
|
function onPopupShown() {
|
||||||
|
info("onPopupShown");
|
||||||
|
popup.removeEventListener("popupshown", onPopupShown);
|
||||||
|
|
||||||
|
onShown && onShown();
|
||||||
|
|
||||||
|
// Use executeSoon() to get out of the popupshown event.
|
||||||
|
popup.addEventListener("popuphidden", onPopupHidden);
|
||||||
|
executeSoon(() => popup.hidePopup());
|
||||||
|
}
|
||||||
|
function onPopupHidden() {
|
||||||
|
info("onPopupHidden");
|
||||||
|
popup.removeEventListener("popuphidden", onPopupHidden);
|
||||||
|
|
||||||
|
onHidden && onHidden();
|
||||||
|
|
||||||
|
deferred.resolve(popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.addEventListener("popupshown", onPopupShown);
|
||||||
|
|
||||||
|
info("wait for the context menu to open");
|
||||||
|
let eventDetails = {type: "contextmenu", button: 2};
|
||||||
|
EventUtils.synthesizeMouse(button, 2, 2, eventDetails,
|
||||||
|
button.ownerDocument.defaultView);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
|
@ -115,3 +115,7 @@ storage.data.label=Data
|
||||||
# LOCALIZATION NOTE (storage.parsedValue.label):
|
# LOCALIZATION NOTE (storage.parsedValue.label):
|
||||||
# This is the heading displayed over the item parsed value in the sidebar
|
# This is the heading displayed over the item parsed value in the sidebar
|
||||||
storage.parsedValue.label=Parsed Value
|
storage.parsedValue.label=Parsed Value
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (storage.popupMenu.deleteLabel):
|
||||||
|
# Label of popup menu action to delete storage item.
|
||||||
|
storage.popupMenu.deleteLabel=Delete "%S"
|
||||||
|
|
|
@ -57,6 +57,8 @@ const MAX_VISIBLE_STRING_SIZE = 100;
|
||||||
* - removableColumns: Whether columns are removeable. If set to false,
|
* - removableColumns: Whether columns are removeable. If set to false,
|
||||||
* the context menu in the headers will not appear.
|
* the context menu in the headers will not appear.
|
||||||
* - firstColumn: key of the first column that should appear.
|
* - firstColumn: key of the first column that should appear.
|
||||||
|
* - cellContextMenuId: ID of a <menupopup> element to be set as a
|
||||||
|
* context menu of every cell.
|
||||||
*/
|
*/
|
||||||
function TableWidget(node, options = {}) {
|
function TableWidget(node, options = {}) {
|
||||||
EventEmitter.decorate(this);
|
EventEmitter.decorate(this);
|
||||||
|
@ -66,12 +68,13 @@ function TableWidget(node, options = {}) {
|
||||||
this._parent = node;
|
this._parent = node;
|
||||||
|
|
||||||
let {initialColumns, emptyText, uniqueId, highlightUpdated, removableColumns,
|
let {initialColumns, emptyText, uniqueId, highlightUpdated, removableColumns,
|
||||||
firstColumn} = options;
|
firstColumn, cellContextMenuId} = options;
|
||||||
this.emptyText = emptyText || "";
|
this.emptyText = emptyText || "";
|
||||||
this.uniqueId = uniqueId || "name";
|
this.uniqueId = uniqueId || "name";
|
||||||
this.firstColumn = firstColumn || "";
|
this.firstColumn = firstColumn || "";
|
||||||
this.highlightUpdated = highlightUpdated || false;
|
this.highlightUpdated = highlightUpdated || false;
|
||||||
this.removableColumns = removableColumns !== false;
|
this.removableColumns = removableColumns !== false;
|
||||||
|
this.cellContextMenuId = cellContextMenuId;
|
||||||
|
|
||||||
this.tbody = this.document.createElementNS(XUL_NS, "hbox");
|
this.tbody = this.document.createElementNS(XUL_NS, "hbox");
|
||||||
this.tbody.className = "table-widget-body theme-body";
|
this.tbody.className = "table-widget-body theme-body";
|
||||||
|
@ -807,6 +810,7 @@ TableWidget.prototype = {
|
||||||
}
|
}
|
||||||
for (let column of this.columns.values()) {
|
for (let column of this.columns.values()) {
|
||||||
column.remove(item);
|
column.remove(item);
|
||||||
|
column.updateZebra();
|
||||||
}
|
}
|
||||||
if (this.items.size == 0) {
|
if (this.items.size == 0) {
|
||||||
this.tbody.setAttribute("empty", "empty");
|
this.tbody.setAttribute("empty", "empty");
|
||||||
|
@ -1449,6 +1453,15 @@ function Cell(column, item, nextCell) {
|
||||||
column.column.appendChild(this.label);
|
column.column.appendChild(this.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (column.table.cellContextMenuId) {
|
||||||
|
this.label.setAttribute("context", column.table.cellContextMenuId);
|
||||||
|
this.label.addEventListener("contextmenu", (event) => {
|
||||||
|
// Make the ID of the clicked cell available as a property on the table.
|
||||||
|
// It's then available for the popupshowing or command handler.
|
||||||
|
column.table.contextMenuRowId = this.id;
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
this.value = item[column.id];
|
this.value = item[column.id];
|
||||||
this.id = item[column.uniqueId];
|
this.id = item[column.uniqueId];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
|
|
||||||
<commandset id="editMenuCommands"/>
|
<commandset id="editMenuCommands"/>
|
||||||
|
|
||||||
|
<popupset id="storagePopupSet">
|
||||||
|
<menupopup id="storage-table-popup">
|
||||||
|
<menuitem id="storage-table-popup-delete"/>
|
||||||
|
</menupopup>
|
||||||
|
</popupset>
|
||||||
|
|
||||||
<box flex="1" class="devtools-responsive-container theme-body">
|
<box flex="1" class="devtools-responsive-container theme-body">
|
||||||
<vbox id="storage-tree"/>
|
<vbox id="storage-tree"/>
|
||||||
<splitter class="devtools-side-splitter"/>
|
<splitter class="devtools-side-splitter"/>
|
||||||
|
|
|
@ -20,6 +20,7 @@ support-files =
|
||||||
[browser_storage_cookies_tab_navigation.js]
|
[browser_storage_cookies_tab_navigation.js]
|
||||||
[browser_storage_dynamic_updates.js]
|
[browser_storage_dynamic_updates.js]
|
||||||
[browser_storage_localstorage_edit.js]
|
[browser_storage_localstorage_edit.js]
|
||||||
|
[browser_storage_delete.js]
|
||||||
[browser_storage_overflow.js]
|
[browser_storage_overflow.js]
|
||||||
[browser_storage_search.js]
|
[browser_storage_search.js]
|
||||||
skip-if = os == "linux" && e10s # Bug 1240804 - unhandled promise rejections
|
skip-if = os == "linux" && e10s # Bug 1240804 - unhandled promise rejections
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
/* import-globals-from ../../framework/test/shared-head.js */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Test deleting storage items
|
||||||
|
|
||||||
|
const TEST_CASES = [
|
||||||
|
[["localStorage", "http://test1.example.org"],
|
||||||
|
"ls1", "name"],
|
||||||
|
[["sessionStorage", "http://test1.example.org"],
|
||||||
|
"ss1", "name"],
|
||||||
|
[["cookies", "test1.example.org"],
|
||||||
|
"c1", "name"]
|
||||||
|
];
|
||||||
|
|
||||||
|
add_task(function*() {
|
||||||
|
yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html");
|
||||||
|
|
||||||
|
let contextMenu = gPanelWindow.document.getElementById("storage-table-popup");
|
||||||
|
let menuDeleteItem = contextMenu.querySelector("#storage-table-popup-delete");
|
||||||
|
|
||||||
|
for (let [ [store, host], rowName, cellToClick] of TEST_CASES) {
|
||||||
|
info(`Selecting tree item ${store} > ${host}`);
|
||||||
|
yield selectTreeItem([store, host]);
|
||||||
|
|
||||||
|
let row = getRowCells(rowName);
|
||||||
|
|
||||||
|
ok(gUI.table.items.has(rowName),
|
||||||
|
`There is a row '${rowName}' in ${store} > ${host}`);
|
||||||
|
|
||||||
|
yield waitForContextMenu(contextMenu, row[cellToClick], () => {
|
||||||
|
info(`Opened context menu in ${store} > ${host}, row '${rowName}'`);
|
||||||
|
menuDeleteItem.click();
|
||||||
|
ok(menuDeleteItem.getAttribute("label").includes(rowName),
|
||||||
|
`Context menu item label contains '${rowName}'`);
|
||||||
|
});
|
||||||
|
|
||||||
|
yield gUI.once("store-objects-updated");
|
||||||
|
|
||||||
|
ok(!gUI.table.items.has(rowName),
|
||||||
|
`There is no row '${rowName}' in ${store} > ${host} after deletion`);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield finishTests();
|
||||||
|
});
|
|
@ -5,11 +5,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
||||||
|
/* import-globals-from ../../framework/test/shared-head.js */
|
||||||
|
|
||||||
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
// shared-head.js handles imports, constants, and utility functions
|
||||||
var { TargetFactory } = require("devtools/client/framework/target");
|
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
|
||||||
var promise = require("promise");
|
|
||||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
|
||||||
|
|
||||||
const {TableWidget} = require("devtools/client/shared/widgets/TableWidget");
|
const {TableWidget} = require("devtools/client/shared/widgets/TableWidget");
|
||||||
const SPLIT_CONSOLE_PREF = "devtools.toolbox.splitconsoleEnabled";
|
const SPLIT_CONSOLE_PREF = "devtools.toolbox.splitconsoleEnabled";
|
||||||
|
@ -23,8 +22,6 @@ const MAIN_DOMAIN = "http://test1.example.org/" + PATH;
|
||||||
const ALT_DOMAIN = "http://sectest1.example.org/" + PATH;
|
const ALT_DOMAIN = "http://sectest1.example.org/" + PATH;
|
||||||
const ALT_DOMAIN_SECURED = "https://sectest1.example.org:443/" + PATH;
|
const ALT_DOMAIN_SECURED = "https://sectest1.example.org:443/" + PATH;
|
||||||
|
|
||||||
waitForExplicitFinish();
|
|
||||||
|
|
||||||
var gToolbox, gPanelWindow, gWindow, gUI;
|
var gToolbox, gPanelWindow, gWindow, gUI;
|
||||||
|
|
||||||
// Services.prefs.setBoolPref(DUMPEMIT_PREF, true);
|
// Services.prefs.setBoolPref(DUMPEMIT_PREF, true);
|
||||||
|
|
|
@ -47,6 +47,10 @@ const REASON = {
|
||||||
UPDATE: "update"
|
UPDATE: "update"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Maximum length of item name to show in context menu label - will be
|
||||||
|
// trimmed with ellipsis if it's longer.
|
||||||
|
const ITEM_NAME_MAX_LENGTH = 32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StorageUI is controls and builds the UI of the Storage Inspector.
|
* StorageUI is controls and builds the UI of the Storage Inspector.
|
||||||
*
|
*
|
||||||
|
@ -74,6 +78,7 @@ var StorageUI = this.StorageUI = function StorageUI(front, target, panelWin) {
|
||||||
this.table = new TableWidget(tableNode, {
|
this.table = new TableWidget(tableNode, {
|
||||||
emptyText: L10N.getStr("table.emptyText"),
|
emptyText: L10N.getStr("table.emptyText"),
|
||||||
highlightUpdated: true,
|
highlightUpdated: true,
|
||||||
|
cellContextMenuId: "storage-table-popup"
|
||||||
});
|
});
|
||||||
|
|
||||||
this.displayObjectSidebar = this.displayObjectSidebar.bind(this);
|
this.displayObjectSidebar = this.displayObjectSidebar.bind(this);
|
||||||
|
@ -105,6 +110,15 @@ var StorageUI = this.StorageUI = function StorageUI(front, target, panelWin) {
|
||||||
|
|
||||||
this.handleKeypress = this.handleKeypress.bind(this);
|
this.handleKeypress = this.handleKeypress.bind(this);
|
||||||
this._panelDoc.addEventListener("keypress", this.handleKeypress);
|
this._panelDoc.addEventListener("keypress", this.handleKeypress);
|
||||||
|
|
||||||
|
this.onPopupShowing = this.onPopupShowing.bind(this);
|
||||||
|
this._tablePopup = this._panelDoc.getElementById("storage-table-popup");
|
||||||
|
this._tablePopup.addEventListener("popupshowing", this.onPopupShowing, false);
|
||||||
|
|
||||||
|
this.onRemoveItem = this.onRemoveItem.bind(this);
|
||||||
|
this._tablePopupDelete = this._panelDoc.getElementById(
|
||||||
|
"storage-table-popup-delete");
|
||||||
|
this._tablePopupDelete.addEventListener("command", this.onRemoveItem, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.StorageUI = StorageUI;
|
exports.StorageUI = StorageUI;
|
||||||
|
@ -130,6 +144,9 @@ StorageUI.prototype = {
|
||||||
this._panelDoc.removeEventListener("keypress", this.handleKeypress);
|
this._panelDoc.removeEventListener("keypress", this.handleKeypress);
|
||||||
this.searchBox.removeEventListener("input", this.filterItems);
|
this.searchBox.removeEventListener("input", this.filterItems);
|
||||||
this.searchBox = null;
|
this.searchBox = null;
|
||||||
|
|
||||||
|
this._tablePopup.removeEventListener("popupshowing", this.onPopupShowing);
|
||||||
|
this._tablePopupDelete.removeEventListener("command", this.onRemoveItem);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -731,5 +748,41 @@ StorageUI.prototype = {
|
||||||
names = [JSON.stringify(item.slice(2))];
|
names = [JSON.stringify(item.slice(2))];
|
||||||
}
|
}
|
||||||
this.fetchStorageObjects(type, host, names, REASON.NEXT_50_ITEMS);
|
this.fetchStorageObjects(type, host, names, REASON.NEXT_50_ITEMS);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires before a cell context menu with the "Delete" action is shown.
|
||||||
|
* If the current storage actor doesn't support removing items, prevent
|
||||||
|
* showing the menu.
|
||||||
|
*/
|
||||||
|
onPopupShowing: function(event) {
|
||||||
|
if (!this.getCurrentActor().removeItem) {
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let rowId = this.table.contextMenuRowId;
|
||||||
|
let data = this.table.items.get(rowId);
|
||||||
|
let name = data[this.table.uniqueId];
|
||||||
|
|
||||||
|
const maxLen = ITEM_NAME_MAX_LENGTH;
|
||||||
|
if (name.length > maxLen) {
|
||||||
|
name = name.substr(0, maxLen) + L10N.ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._tablePopupDelete.setAttribute("label",
|
||||||
|
L10N.getFormatStr("storage.popupMenu.deleteLabel", name));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles removing an item from the storage
|
||||||
|
*/
|
||||||
|
onRemoveItem: function() {
|
||||||
|
let [, host] = this.tree.selectedItem;
|
||||||
|
let actor = this.getCurrentActor();
|
||||||
|
let rowId = this.table.contextMenuRowId;
|
||||||
|
let data = this.table.items.get(rowId);
|
||||||
|
|
||||||
|
actor.removeItem(host, data[this.table.uniqueId]);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -241,53 +241,6 @@ var closeConsole = Task.async(function* (tab) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for a context menu popup to open.
|
|
||||||
*
|
|
||||||
* @param nsIDOMElement popup
|
|
||||||
* The XUL popup you expect to open.
|
|
||||||
* @param nsIDOMElement button
|
|
||||||
* The button/element that receives the contextmenu event. This is
|
|
||||||
* expected to open the popup.
|
|
||||||
* @param function onShown
|
|
||||||
* Function to invoke on popupshown event.
|
|
||||||
* @param function onHidden
|
|
||||||
* Function to invoke on popuphidden event.
|
|
||||||
* @return object
|
|
||||||
* A Promise object that is resolved after the popuphidden event
|
|
||||||
* callback is invoked.
|
|
||||||
*/
|
|
||||||
function waitForContextMenu(popup, button, onShown, onHidden) {
|
|
||||||
let deferred = promise.defer();
|
|
||||||
|
|
||||||
function onPopupShown() {
|
|
||||||
info("onPopupShown");
|
|
||||||
popup.removeEventListener("popupshown", onPopupShown);
|
|
||||||
|
|
||||||
onShown && onShown();
|
|
||||||
|
|
||||||
// Use executeSoon() to get out of the popupshown event.
|
|
||||||
popup.addEventListener("popuphidden", onPopupHidden);
|
|
||||||
executeSoon(() => popup.hidePopup());
|
|
||||||
}
|
|
||||||
function onPopupHidden() {
|
|
||||||
info("onPopupHidden");
|
|
||||||
popup.removeEventListener("popuphidden", onPopupHidden);
|
|
||||||
|
|
||||||
onHidden && onHidden();
|
|
||||||
|
|
||||||
deferred.resolve(popup);
|
|
||||||
}
|
|
||||||
|
|
||||||
popup.addEventListener("popupshown", onPopupShown);
|
|
||||||
|
|
||||||
info("wait for the context menu to open");
|
|
||||||
let eventDetails = {type: "contextmenu", button: 2};
|
|
||||||
EventUtils.synthesizeMouse(button, 2, 2, eventDetails,
|
|
||||||
button.ownerDocument.defaultView);
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen for a new tab to open and return a promise that resolves when one
|
* Listen for a new tab to open and return a promise that resolves when one
|
||||||
* does and completes the load event.
|
* does and completes the load event.
|
||||||
|
|
|
@ -426,7 +426,7 @@ StorageActors.defaults = function(typeName, observationTopic, storeObjectType) {
|
||||||
* - storeObjectType {string}
|
* - storeObjectType {string}
|
||||||
* The RetVal type of the store object of this actor.
|
* The RetVal type of the store object of this actor.
|
||||||
* @param {object} overrides
|
* @param {object} overrides
|
||||||
* All the methods which you want to be differnt from the ones in
|
* All the methods which you want to be different from the ones in
|
||||||
* StorageActors.defaults method plus the required ones described there.
|
* StorageActors.defaults method plus the required ones described there.
|
||||||
*/
|
*/
|
||||||
StorageActors.createActor = function(options = {}, overrides = {}) {
|
StorageActors.createActor = function(options = {}, overrides = {}) {
|
||||||
|
@ -674,6 +674,16 @@ StorageActors.createActor({
|
||||||
response: {}
|
response: {}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
removeItem: method(Task.async(function*(host, name) {
|
||||||
|
this.removeCookie(host, name);
|
||||||
|
}), {
|
||||||
|
request: {
|
||||||
|
host: Arg(0),
|
||||||
|
name: Arg(1),
|
||||||
|
},
|
||||||
|
response: {}
|
||||||
|
}),
|
||||||
|
|
||||||
maybeSetupChildProcess: function() {
|
maybeSetupChildProcess: function() {
|
||||||
cookieHelpers.onCookieChanged = this.onCookieChanged.bind(this);
|
cookieHelpers.onCookieChanged = this.onCookieChanged.bind(this);
|
||||||
|
|
||||||
|
@ -682,6 +692,7 @@ StorageActors.createActor({
|
||||||
this.addCookieObservers = cookieHelpers.addCookieObservers;
|
this.addCookieObservers = cookieHelpers.addCookieObservers;
|
||||||
this.removeCookieObservers = cookieHelpers.removeCookieObservers;
|
this.removeCookieObservers = cookieHelpers.removeCookieObservers;
|
||||||
this.editCookie = cookieHelpers.editCookie;
|
this.editCookie = cookieHelpers.editCookie;
|
||||||
|
this.removeCookie = cookieHelpers.removeCookie;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,6 +712,8 @@ StorageActors.createActor({
|
||||||
callParentProcess.bind(null, "removeCookieObservers");
|
callParentProcess.bind(null, "removeCookieObservers");
|
||||||
this.editCookie =
|
this.editCookie =
|
||||||
callParentProcess.bind(null, "editCookie");
|
callParentProcess.bind(null, "editCookie");
|
||||||
|
this.removeCookie =
|
||||||
|
callParentProcess.bind(null, "removeCookie");
|
||||||
|
|
||||||
addMessageListener("storage:storage-cookie-request-child",
|
addMessageListener("storage:storage-cookie-request-child",
|
||||||
cookieHelpers.handleParentRequest);
|
cookieHelpers.handleParentRequest);
|
||||||
|
@ -854,6 +867,32 @@ var cookieHelpers = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeCookie: function(host, name) {
|
||||||
|
function hostMatches(cookieHost, matchHost) {
|
||||||
|
if (cookieHost == null) {
|
||||||
|
return matchHost == null;
|
||||||
|
}
|
||||||
|
if (cookieHost.startsWith(".")) {
|
||||||
|
return matchHost.endsWith(cookieHost);
|
||||||
|
}
|
||||||
|
return cookieHost == host;
|
||||||
|
}
|
||||||
|
|
||||||
|
let enumerator = Services.cookies.getCookiesFromHost(host);
|
||||||
|
while (enumerator.hasMoreElements()) {
|
||||||
|
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
||||||
|
if (hostMatches(cookie.host, host) && cookie.name === name) {
|
||||||
|
Services.cookies.remove(
|
||||||
|
cookie.host,
|
||||||
|
cookie.name,
|
||||||
|
cookie.path,
|
||||||
|
cookie.originAttributes,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addCookieObservers: function() {
|
addCookieObservers: function() {
|
||||||
Services.obs.addObserver(cookieHelpers, "cookie-changed", false);
|
Services.obs.addObserver(cookieHelpers, "cookie-changed", false);
|
||||||
return null;
|
return null;
|
||||||
|
@ -902,17 +941,26 @@ var cookieHelpers = {
|
||||||
|
|
||||||
handleChildRequest: function(msg) {
|
handleChildRequest: function(msg) {
|
||||||
switch (msg.json.method) {
|
switch (msg.json.method) {
|
||||||
case "getCookiesFromHost":
|
case "getCookiesFromHost": {
|
||||||
let host = msg.data.args[0];
|
let host = msg.data.args[0];
|
||||||
let cookies = cookieHelpers.getCookiesFromHost(host);
|
let cookies = cookieHelpers.getCookiesFromHost(host);
|
||||||
return JSON.stringify(cookies);
|
return JSON.stringify(cookies);
|
||||||
case "addCookieObservers":
|
}
|
||||||
|
case "addCookieObservers": {
|
||||||
return cookieHelpers.addCookieObservers();
|
return cookieHelpers.addCookieObservers();
|
||||||
case "removeCookieObservers":
|
}
|
||||||
|
case "removeCookieObservers": {
|
||||||
return cookieHelpers.removeCookieObservers();
|
return cookieHelpers.removeCookieObservers();
|
||||||
case "editCookie":
|
}
|
||||||
|
case "editCookie": {
|
||||||
let rowdata = msg.data.args[0];
|
let rowdata = msg.data.args[0];
|
||||||
return cookieHelpers.editCookie(rowdata);
|
return cookieHelpers.editCookie(rowdata);
|
||||||
|
}
|
||||||
|
case "removeCookie": {
|
||||||
|
let host = msg.data.args[0];
|
||||||
|
let name = msg.data.args[1];
|
||||||
|
return cookieHelpers.removeCookie(host, name);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
console.error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD", msg.json.method);
|
console.error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD", msg.json.method);
|
||||||
throw new Error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD");
|
throw new Error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD");
|
||||||
|
@ -1113,6 +1161,17 @@ function getObjectForLocalOrSessionStorage(type) {
|
||||||
value: new LongStringActor(this.conn, item.value || "")
|
value: new LongStringActor(this.conn, item.value || "")
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeItem: method(Task.async(function*(host, name) {
|
||||||
|
let storage = this.hostVsStores.get(host);
|
||||||
|
storage.removeItem(name);
|
||||||
|
}), {
|
||||||
|
request: {
|
||||||
|
host: Arg(0),
|
||||||
|
name: Arg(1),
|
||||||
|
},
|
||||||
|
response: {}
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче