зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1424538 - Allow pageAction and sidebarAction set* methods to accept a null value (desktop). r=mixedpuppy
MozReview-Commit-ID: FqcRrFDYqWp --HG-- extra : rebase_source : 0ae2cfb1db75f3abbdc9b0e57c56848dadd3a431
This commit is contained in:
Родитель
2064ded574
Коммит
2259549f9d
|
@ -279,9 +279,7 @@ this.pageAction = class extends ExtensionAPI {
|
|||
|
||||
setTitle(details) {
|
||||
let tab = tabTracker.getTab(details.tabId);
|
||||
|
||||
// Clear the tab-specific title when given a null string.
|
||||
pageAction.setProperty(tab, "title", details.title || null);
|
||||
pageAction.setProperty(tab, "title", details.title);
|
||||
},
|
||||
|
||||
getTitle(details) {
|
||||
|
@ -295,6 +293,9 @@ this.pageAction = class extends ExtensionAPI {
|
|||
let tab = tabTracker.getTab(details.tabId);
|
||||
|
||||
let icon = IconDetails.normalize(details, extension, context);
|
||||
if (!Object.keys(icon).length) {
|
||||
icon = null;
|
||||
}
|
||||
pageAction.setProperty(tab, "icon", icon);
|
||||
},
|
||||
|
||||
|
|
|
@ -8,10 +8,6 @@
|
|||
|
||||
Cu.import("resource://gre/modules/ExtensionParent.jsm");
|
||||
|
||||
var {
|
||||
ExtensionError,
|
||||
} = ExtensionUtils;
|
||||
|
||||
var {
|
||||
IconDetails,
|
||||
} = ExtensionParent;
|
||||
|
@ -56,13 +52,14 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
icon: IconDetails.normalize({path: options.default_icon}, extension),
|
||||
panel: options.default_panel || "",
|
||||
};
|
||||
this.globals = Object.create(this.defaults);
|
||||
|
||||
this.tabContext = new TabContext(tab => Object.create(this.defaults),
|
||||
this.tabContext = new TabContext(tab => Object.create(this.globals),
|
||||
extension);
|
||||
|
||||
// We need to ensure our elements are available before session restore.
|
||||
this.windowOpenListener = (window) => {
|
||||
this.createMenuItem(window, this.defaults);
|
||||
this.createMenuItem(window, this.globals);
|
||||
};
|
||||
windowTracker.addOpenListener(this.windowOpenListener);
|
||||
|
||||
|
@ -291,19 +288,23 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
* Value for property.
|
||||
*/
|
||||
setProperty(nativeTab, prop, value) {
|
||||
let values;
|
||||
if (nativeTab === null) {
|
||||
this.defaults[prop] = value;
|
||||
} else if (value !== null) {
|
||||
this.tabContext.get(nativeTab)[prop] = value;
|
||||
values = this.globals;
|
||||
} else {
|
||||
delete this.tabContext.get(nativeTab)[prop];
|
||||
values = this.tabContext.get(nativeTab);
|
||||
}
|
||||
if (value === null) {
|
||||
delete values[prop];
|
||||
} else {
|
||||
values[prop] = value;
|
||||
}
|
||||
|
||||
this.updateOnChange(nativeTab);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a property from the tab or defaults if tab is null.
|
||||
* Retrieve a property from the tab or globals if tab is null.
|
||||
*
|
||||
* @param {XULElement|null} nativeTab
|
||||
* Browser tab object, may be null.
|
||||
|
@ -314,7 +315,7 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
*/
|
||||
getProperty(nativeTab, prop) {
|
||||
if (nativeTab === null) {
|
||||
return this.defaults[prop];
|
||||
return this.globals[prop];
|
||||
}
|
||||
return this.tabContext.get(nativeTab)[prop];
|
||||
}
|
||||
|
@ -381,13 +382,7 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
sidebarAction: {
|
||||
async setTitle(details) {
|
||||
let nativeTab = getTab(details.tabId);
|
||||
|
||||
let title = details.title;
|
||||
// Clear the tab-specific title when given a null string.
|
||||
if (nativeTab && title === "") {
|
||||
title = null;
|
||||
}
|
||||
sidebarAction.setProperty(nativeTab, "title", title);
|
||||
sidebarAction.setProperty(nativeTab, "title", details.title);
|
||||
},
|
||||
|
||||
getTitle(details) {
|
||||
|
@ -401,6 +396,9 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
let nativeTab = getTab(details.tabId);
|
||||
|
||||
let icon = IconDetails.normalize(details, extension, context);
|
||||
if (!Object.keys(icon).length) {
|
||||
icon = null;
|
||||
}
|
||||
sidebarAction.setProperty(nativeTab, "icon", icon);
|
||||
},
|
||||
|
||||
|
@ -408,16 +406,14 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
let nativeTab = getTab(details.tabId);
|
||||
|
||||
let url;
|
||||
// Clear the tab-specific url when given a null string.
|
||||
if (nativeTab && details.panel === "") {
|
||||
// Clear the url when given null or empty string.
|
||||
if (!details.panel) {
|
||||
url = null;
|
||||
} else if (details.panel !== "") {
|
||||
} else {
|
||||
url = context.uri.resolve(details.panel);
|
||||
if (!context.checkLoadURL(url)) {
|
||||
return Promise.reject({message: `Access denied for URL ${url}`});
|
||||
}
|
||||
} else {
|
||||
throw new ExtensionError("Invalid url for sidebar panel.");
|
||||
}
|
||||
|
||||
sidebarAction.setProperty(nativeTab, "panel", url);
|
||||
|
|
|
@ -124,7 +124,13 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"tabId": {"type": "integer", "minimum": 0, "description": "The id of the tab for which you want to modify the page action."},
|
||||
"title": {"type": "string", "description": "The tooltip string."}
|
||||
"title": {
|
||||
"choices": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The tooltip string."
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -216,7 +222,10 @@
|
|||
"properties": {
|
||||
"tabId": {"type": "integer", "minimum": 0, "description": "The id of the tab for which you want to modify the page action."},
|
||||
"popup": {
|
||||
"type": "string",
|
||||
"choices": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The html file to show in a popup. If set to the empty string (''), no popup is shown."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,10 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"choices": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The string the sidebar action should display when moused over."
|
||||
},
|
||||
"tabId": {
|
||||
|
@ -156,7 +159,10 @@
|
|||
"description": "Sets the sidebar url for the tab specified by tabId. Automatically resets when the tab is closed."
|
||||
},
|
||||
"panel": {
|
||||
"type": "string",
|
||||
"choices": [
|
||||
{"type": "string"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The url to the html file to show in a sidebar. If set to the empty string (''), no sidebar is shown."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -473,7 +473,7 @@ add_task(async function testPropertyRemoval() {
|
|||
},
|
||||
|
||||
getTests: function(tabs, expectGlobals) {
|
||||
let contextUri = browser.runtime.getURL("_generated_background_page.html");
|
||||
let defaultIcon = "chrome://browser/content/extension.svg";
|
||||
let details = [
|
||||
{"icon": browser.runtime.getURL("default.png"),
|
||||
"popup": browser.runtime.getURL("default.html"),
|
||||
|
@ -490,7 +490,7 @@ add_task(async function testPropertyRemoval() {
|
|||
"title": "t2",
|
||||
"badge": "b2",
|
||||
"badgeBackgroundColor": [0x22, 0x22, 0x22, 0xFF]},
|
||||
{"icon": contextUri,
|
||||
{"icon": defaultIcon,
|
||||
"popup": "",
|
||||
"title": "",
|
||||
"badge": "",
|
||||
|
|
|
@ -52,6 +52,7 @@ add_task(async function testTabSwitchContext() {
|
|||
},
|
||||
|
||||
getTests: function(tabs) {
|
||||
let defaultIcon = "chrome://browser/content/extension.svg";
|
||||
let details = [
|
||||
{"icon": browser.runtime.getURL("default.png"),
|
||||
"popup": browser.runtime.getURL("default.html"),
|
||||
|
@ -62,9 +63,9 @@ add_task(async function testTabSwitchContext() {
|
|||
{"icon": browser.runtime.getURL("2.png"),
|
||||
"popup": browser.runtime.getURL("2.html"),
|
||||
"title": "Title 2"},
|
||||
{"icon": browser.runtime.getURL("2.png"),
|
||||
"popup": browser.runtime.getURL("2.html"),
|
||||
"title": "Default T\u00edtulo \u263a"},
|
||||
{"icon": defaultIcon,
|
||||
"popup": "",
|
||||
"title": ""},
|
||||
];
|
||||
|
||||
let promiseTabLoad = details => {
|
||||
|
@ -124,11 +125,21 @@ add_task(async function testTabSwitchContext() {
|
|||
expect(details[2]);
|
||||
},
|
||||
expect => {
|
||||
browser.test.log("Clear the title. Expect default title.");
|
||||
browser.test.log("Set empty string values. Expect empty strings but default icon.");
|
||||
browser.pageAction.setIcon({tabId: tabs[1], path: ""});
|
||||
browser.pageAction.setPopup({tabId: tabs[1], popup: ""});
|
||||
browser.pageAction.setTitle({tabId: tabs[1], title: ""});
|
||||
|
||||
expect(details[3]);
|
||||
},
|
||||
expect => {
|
||||
browser.test.log("Clear the values. Expect default ones.");
|
||||
browser.pageAction.setIcon({tabId: tabs[1], path: null});
|
||||
browser.pageAction.setPopup({tabId: tabs[1], popup: null});
|
||||
browser.pageAction.setTitle({tabId: tabs[1], title: null});
|
||||
|
||||
expect(details[0]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Navigate to a new page. Expect icon hidden.");
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@ add_task(async function testTabSwitchContext() {
|
|||
{"icon": browser.runtime.getURL("2.png"),
|
||||
"popup": browser.runtime.getURL("2.html"),
|
||||
"title": "Title 2"},
|
||||
{"icon": browser.runtime.getURL("2.png"),
|
||||
"popup": browser.runtime.getURL("2.html"),
|
||||
"title": ""},
|
||||
{"icon": browser.runtime.getURL("2.png"),
|
||||
"popup": browser.runtime.getURL("2.html"),
|
||||
"title": "Default T\u00edtulo \u263a"},
|
||||
|
@ -124,11 +127,17 @@ add_task(async function testTabSwitchContext() {
|
|||
expect(details[2]);
|
||||
},
|
||||
expect => {
|
||||
browser.test.log("Clear the title. Expect default title.");
|
||||
browser.test.log("Set empty title. Expect empty title.");
|
||||
browser.pageAction.setTitle({tabId: tabs[1], title: ""});
|
||||
|
||||
expect(details[3]);
|
||||
},
|
||||
expect => {
|
||||
browser.test.log("Clear the title. Expect default title.");
|
||||
browser.pageAction.setTitle({tabId: tabs[1], title: null});
|
||||
|
||||
expect(details[4]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Navigate to a new page. Expect icon hidden.");
|
||||
|
||||
|
@ -196,6 +205,9 @@ add_task(async function testDefaultTitle() {
|
|||
{"title": "Foo Title",
|
||||
"popup": "",
|
||||
"icon": browser.runtime.getURL("icon.png")},
|
||||
{"title": "",
|
||||
"popup": "",
|
||||
"icon": browser.runtime.getURL("icon.png")},
|
||||
];
|
||||
|
||||
return [
|
||||
|
@ -214,8 +226,13 @@ add_task(async function testDefaultTitle() {
|
|||
expect(details[1]);
|
||||
},
|
||||
expect => {
|
||||
browser.test.log("Clear the title. Expect extension title.");
|
||||
browser.test.log("Set empty title. Expect empty title.");
|
||||
browser.pageAction.setTitle({tabId: tabs[0], title: ""});
|
||||
expect(details[2]);
|
||||
},
|
||||
expect => {
|
||||
browser.test.log("Clear the title. Expect extension title.");
|
||||
browser.pageAction.setTitle({tabId: tabs[0], title: null});
|
||||
expect(details[0]);
|
||||
},
|
||||
];
|
||||
|
|
|
@ -34,11 +34,12 @@ let extData = {
|
|||
background: function() {
|
||||
browser.test.onMessage.addListener(async ({msg, data}) => {
|
||||
if (msg === "set-panel") {
|
||||
await browser.sidebarAction.setPanel({panel: ""}).then(() => {
|
||||
browser.test.notifyFail("empty panel settable");
|
||||
}).catch(() => {
|
||||
browser.test.notifyPass("unable to set empty panel");
|
||||
});
|
||||
await browser.sidebarAction.setPanel({panel: null});
|
||||
browser.test.assertEq(
|
||||
await browser.sidebarAction.getPanel({}),
|
||||
browser.runtime.getURL("sidebar.html"),
|
||||
"Global panel can be reverted to the default."
|
||||
);
|
||||
} else if (msg === "isOpen") {
|
||||
let {arg = {}, result} = data;
|
||||
let isOpen = await browser.sidebarAction.isOpen(arg);
|
||||
|
@ -96,7 +97,6 @@ add_task(async function sidebar_empty_panel() {
|
|||
await extension.awaitMessage("sidebar");
|
||||
ok(!document.getElementById("sidebar-box").hidden, "sidebar box is visible in first window");
|
||||
await sendMessage(extension, "set-panel");
|
||||
await extension.awaitFinish();
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
|
|
|
@ -298,7 +298,7 @@ add_task(async function testTabSwitchContext() {
|
|||
async expect => {
|
||||
browser.test.log("Revert tab panel.");
|
||||
let tabId = tabs[0];
|
||||
await browser.sidebarAction.setPanel({tabId, panel: ""});
|
||||
await browser.sidebarAction.setPanel({tabId, panel: null});
|
||||
expect(details[4]);
|
||||
},
|
||||
];
|
||||
|
@ -324,7 +324,7 @@ add_task(async function testDefaultTitle() {
|
|||
"icon.png": imageBuffer,
|
||||
},
|
||||
|
||||
getTests: function(tabs, expectDefaults) {
|
||||
getTests: function(tabs, expectGlobals) {
|
||||
let details = [
|
||||
{"title": "Foo Extension",
|
||||
"panel": browser.runtime.getURL("sidebar.html"),
|
||||
|
@ -335,45 +335,42 @@ add_task(async function testDefaultTitle() {
|
|||
{"title": "Bar Title",
|
||||
"panel": browser.runtime.getURL("sidebar.html"),
|
||||
"icon": browser.runtime.getURL("icon.png")},
|
||||
{"title": "",
|
||||
"panel": browser.runtime.getURL("sidebar.html"),
|
||||
"icon": browser.runtime.getURL("icon.png")},
|
||||
];
|
||||
|
||||
return [
|
||||
async expect => {
|
||||
browser.test.log("Initial state. Expect extension title as default title.");
|
||||
browser.test.log("Initial state. Expect default extension title.");
|
||||
|
||||
await expectDefaults(details[0]);
|
||||
await expectGlobals(details[0]);
|
||||
expect(details[0]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Change the title. Expect new title.");
|
||||
browser.test.log("Change the tab title. Expect new title.");
|
||||
browser.sidebarAction.setTitle({tabId: tabs[0], title: "Foo Title"});
|
||||
|
||||
await expectDefaults(details[0]);
|
||||
await expectGlobals(details[0]);
|
||||
expect(details[1]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Change the default. Expect same properties.");
|
||||
browser.test.log("Change the global title. Expect same properties.");
|
||||
browser.sidebarAction.setTitle({title: "Bar Title"});
|
||||
|
||||
await expectDefaults(details[2]);
|
||||
await expectGlobals(details[2]);
|
||||
expect(details[1]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Clear the title. Expect new default title.");
|
||||
browser.sidebarAction.setTitle({tabId: tabs[0], title: ""});
|
||||
browser.test.log("Clear the tab title. Expect new global title.");
|
||||
browser.sidebarAction.setTitle({tabId: tabs[0], title: null});
|
||||
|
||||
await expectDefaults(details[2]);
|
||||
await expectGlobals(details[2]);
|
||||
expect(details[2]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Set default title to null string. Expect null string from API, extension title in UI.");
|
||||
browser.sidebarAction.setTitle({title: ""});
|
||||
browser.test.log("Clear the global title. Expect default title.");
|
||||
browser.sidebarAction.setTitle({title: null});
|
||||
|
||||
await expectDefaults(details[3]);
|
||||
expect(details[3]);
|
||||
await expectGlobals(details[0]);
|
||||
expect(details[0]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.assertRejects(
|
||||
|
@ -381,8 +378,115 @@ add_task(async function testDefaultTitle() {
|
|||
/Access denied for URL about:addons/,
|
||||
"unable to set panel to about:addons");
|
||||
|
||||
await expectDefaults(details[3]);
|
||||
expect(details[3]);
|
||||
await expectGlobals(details[0]);
|
||||
expect(details[0]);
|
||||
},
|
||||
];
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testPropertyRemoval() {
|
||||
await runTests({
|
||||
manifest: {
|
||||
"name": "Foo Extension",
|
||||
|
||||
"sidebar_action": {
|
||||
"default_icon": "default.png",
|
||||
"default_panel": "default.html",
|
||||
"default_title": "Default Title",
|
||||
},
|
||||
|
||||
"permissions": ["tabs"],
|
||||
},
|
||||
|
||||
files: {
|
||||
"default.html": sidebar,
|
||||
"p1.html": sidebar,
|
||||
"p2.html": sidebar,
|
||||
"p3.html": sidebar,
|
||||
"default.png": imageBuffer,
|
||||
"i1.png": imageBuffer,
|
||||
"i2.png": imageBuffer,
|
||||
"i3.png": imageBuffer,
|
||||
},
|
||||
|
||||
getTests: function(tabs, expectGlobals) {
|
||||
let defaultIcon = "chrome://browser/content/extension.svg";
|
||||
let details = [
|
||||
{"icon": browser.runtime.getURL("default.png"),
|
||||
"panel": browser.runtime.getURL("default.html"),
|
||||
"title": "Default Title"},
|
||||
{"icon": browser.runtime.getURL("i1.png"),
|
||||
"panel": browser.runtime.getURL("p1.html"),
|
||||
"title": "t1"},
|
||||
{"icon": browser.runtime.getURL("i2.png"),
|
||||
"panel": browser.runtime.getURL("p2.html"),
|
||||
"title": "t2"},
|
||||
{"icon": defaultIcon,
|
||||
"panel": browser.runtime.getURL("p1.html"),
|
||||
"title": ""},
|
||||
{"icon": browser.runtime.getURL("i3.png"),
|
||||
"panel": browser.runtime.getURL("p3.html"),
|
||||
"title": "t3"},
|
||||
];
|
||||
|
||||
return [
|
||||
async expect => {
|
||||
browser.test.log("Initial state, expect default properties.");
|
||||
await expectGlobals(details[0]);
|
||||
expect(details[0]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Set global values, expect the new values.");
|
||||
browser.sidebarAction.setIcon({path: "i1.png"});
|
||||
browser.sidebarAction.setPanel({panel: "p1.html"});
|
||||
browser.sidebarAction.setTitle({title: "t1"});
|
||||
await expectGlobals(details[1]);
|
||||
expect(details[1]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Set tab values, expect the new values.");
|
||||
let tabId = tabs[0];
|
||||
browser.sidebarAction.setIcon({tabId, path: "i2.png"});
|
||||
browser.sidebarAction.setPanel({tabId, panel: "p2.html"});
|
||||
browser.sidebarAction.setTitle({tabId, title: "t2"});
|
||||
await expectGlobals(details[1]);
|
||||
expect(details[2]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Set empty tab values.");
|
||||
let tabId = tabs[0];
|
||||
browser.sidebarAction.setIcon({tabId, path: ""});
|
||||
browser.sidebarAction.setPanel({tabId, panel: ""});
|
||||
browser.sidebarAction.setTitle({tabId, title: ""});
|
||||
await expectGlobals(details[1]);
|
||||
expect(details[3]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Remove tab values, expect global values.");
|
||||
let tabId = tabs[0];
|
||||
browser.sidebarAction.setIcon({tabId, path: null});
|
||||
browser.sidebarAction.setPanel({tabId, panel: null});
|
||||
browser.sidebarAction.setTitle({tabId, title: null});
|
||||
await expectGlobals(details[1]);
|
||||
expect(details[1]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Change global values, expect the new values.");
|
||||
browser.sidebarAction.setIcon({path: "i3.png"});
|
||||
browser.sidebarAction.setPanel({panel: "p3.html"});
|
||||
browser.sidebarAction.setTitle({title: "t3"});
|
||||
await expectGlobals(details[4]);
|
||||
expect(details[4]);
|
||||
},
|
||||
async expect => {
|
||||
browser.test.log("Remove global values, expect defaults.");
|
||||
browser.sidebarAction.setIcon({path: null});
|
||||
browser.sidebarAction.setPanel({panel: null});
|
||||
browser.sidebarAction.setTitle({title: null});
|
||||
await expectGlobals(details[0]);
|
||||
expect(details[0]);
|
||||
},
|
||||
];
|
||||
},
|
||||
|
|
|
@ -1299,14 +1299,16 @@ let IconDetails = {
|
|||
}
|
||||
|
||||
for (let size of Object.keys(path)) {
|
||||
let url = baseURI.resolve(path[size]);
|
||||
|
||||
// The Chrome documentation specifies these parameters as
|
||||
// relative paths. We currently accept absolute URLs as well,
|
||||
// which means we need to check that the extension is allowed
|
||||
// to load them. This will throw an error if it's not allowed.
|
||||
this._checkURL(url, extension);
|
||||
let url = path[size];
|
||||
if (url) {
|
||||
url = baseURI.resolve(path[size]);
|
||||
|
||||
// The Chrome documentation specifies these parameters as
|
||||
// relative paths. We currently accept absolute URLs as well,
|
||||
// which means we need to check that the extension is allowed
|
||||
// to load them. This will throw an error if it's not allowed.
|
||||
this._checkURL(url, extension);
|
||||
}
|
||||
result[size] = url;
|
||||
}
|
||||
}
|
||||
|
@ -1368,7 +1370,7 @@ let IconDetails = {
|
|||
}
|
||||
|
||||
if (bestSize) {
|
||||
return {size: bestSize, icon: icons[bestSize]};
|
||||
return {size: bestSize, icon: icons[bestSize] || DEFAULT};
|
||||
}
|
||||
|
||||
return {size, icon: DEFAULT};
|
||||
|
|
Загрузка…
Ссылка в новой задаче