bug 1274809 - Add missing properties to OnClicked data, r?aswan
MozReview-Commit-ID: 4BodpIuKCz2
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -169,33 +169,34 @@ var gMenuBuilder = {
if (!item.enabled) {
element.setAttribute("disabled", "true");
}
element.addEventListener("command", event => { // eslint-disable-line mozilla/balanced-listeners
if (event.target !== event.currentTarget) {
return;
}
+ const wasChecked = item.checked;
if (item.type == "checkbox") {
item.checked = !item.checked;
} else if (item.type == "radio") {
// Deselect all radio items in the current radio group.
for (let child of item.parent.children) {
if (child.type == "radio" && child.groupName == item.groupName) {
child.checked = false;
}
}
// Select the clicked radio item.
item.checked = true;
}
item.tabManager.addActiveTabPermission();
let tab = item.tabManager.convert(contextData.tab);
- let info = item.getClickInfo(contextData, event);
+ let info = item.getClickInfo(contextData, wasChecked);
item.extension.emit("webext-contextmenu-menuitem-click", info, tab);
if (item.onclick) {
runSafe(item.extContext, item.onclick, info, tab);
}
});
return element;
},
@@ -394,46 +395,51 @@ MenuItem.prototype = {
let menuMap = gContextMenuMap.get(this.extension);
menuMap.delete(this.id);
if (this.root == this) {
gRootItems.delete(this.extension);
}
},
- getClickInfo(contextData, event) {
+ getClickInfo(contextData, wasChecked) {
let mediaType;
if (contextData.onVideo) {
mediaType = "video";
}
if (contextData.onAudio) {
mediaType = "audio";
}
if (contextData.onImage) {
mediaType = "image";
}
let info = {
menuItemId: this.id,
+ editable: contextData.onEditableArea,
};
function setIfDefined(argName, value) {
- if (value) {
+ if (value !== undefined) {
info[argName] = value;
}
}
setIfDefined("parentMenuItemId", this.parentId);
setIfDefined("mediaType", mediaType);
setIfDefined("linkUrl", contextData.linkUrl);
setIfDefined("srcUrl", contextData.srcUrl);
setIfDefined("pageUrl", contextData.pageUrl);
setIfDefined("frameUrl", contextData.frameUrl);
setIfDefined("selectionText", contextData.selectionText);
- setIfDefined("editable", contextData.onEditableArea);
+
+ if ((this.type === "checkbox") || (this.type === "radio")) {
+ info.checked = this.checked;
+ info.wasChecked = wasChecked;
+ }
return info;
},
enabledForContext(contextData) {
let contexts = getContexts(contextData);
if (!this.contexts.some(n => contexts.has(n))) {
return false;
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus.js
@@ -65,17 +65,17 @@ add_task(function* () {
browser.test.sendMessage("browser.contextMenus.onClicked", {info, tab});
});
browser.contextMenus.create({
contexts: ["all"],
type: "separator",
});
- let contexts = ["page", "selection", "image"];
+ let contexts = ["page", "selection", "image", "editable"];
for (let i = 0; i < contexts.length; i++) {
let context = contexts[i];
let title = context;
browser.contextMenus.create({
title: title,
contexts: [context],
id: "ext-" + context,
onclick: genericOnClick,
@@ -139,22 +139,23 @@ add_task(function* () {
yield extension.startup();
yield extension.awaitFinish("contextmenus");
let expectedClickInfo = {
menuItemId: "ext-image",
mediaType: "image",
srcUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/ctxmenu-image.png",
pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
+ editable: false,
};
function checkClickInfo(result) {
for (let i of Object.keys(expectedClickInfo)) {
is(result.info[i], expectedClickInfo[i],
- "click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + info[i]);
+ "click info " + i + " expected to be: " + expectedClickInfo[i] + " but was: " + result.info[i]);
}
is(expectedClickInfo.pageSrc, result.tab.url);
}
let extensionMenuRoot = yield openExtensionContextMenu();
// Check some menu items
let items = extensionMenuRoot.getElementsByAttribute("label", "image");
@@ -175,16 +176,40 @@ add_task(function* () {
// Click on ext-image item and check the click results
yield closeExtensionContextMenu(image);
let result = yield extension.awaitMessage("onclick");
checkClickInfo(result);
result = yield extension.awaitMessage("browser.contextMenus.onClicked");
checkClickInfo(result);
+
+ // Test "editable" context and OnClick data property.
+ extensionMenuRoot = yield openExtensionContextMenu("#edit-me");
+
+ // Check some menu items.
+ items = extensionMenuRoot.getElementsByAttribute("label", "editable");
+ is(items.length, 1, "contextMenu item for text input element was found (context=editable)");
+ let editable = items[0];
+
+ // Click on ext-editable item and check the click results.
+ yield closeExtensionContextMenu(editable);
+
+ expectedClickInfo = {
+ menuItemId: "ext-editable",
+ pageUrl: "http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html",
+ editable: true,
+ };
+
+ result = yield extension.awaitMessage("onclick");
+ checkClickInfo(result);
+ result = yield extension.awaitMessage("browser.contextMenus.onClicked");
+ checkClickInfo(result);
+
+
// Select some text
yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
let doc = content.document;
let range = doc.createRange();
let selection = content.getSelection();
selection.removeAllRanges();
let textNode = doc.getElementById("img1").previousSibling;
range.setStart(textNode, 0);
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_checkboxes.js
@@ -9,16 +9,21 @@ add_task(function* () {
gBrowser.selectedTab = tab1;
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["contextMenus"],
},
background: function() {
+ // Report onClickData info back.
+ browser.contextMenus.onClicked.addListener(info => {
+ browser.test.sendMessage("contextmenus-click", info);
+ });
+
browser.contextMenus.create({
title: "Checkbox",
type: "checkbox",
});
browser.contextMenus.create({
type: "separator",
});
@@ -48,27 +53,44 @@ add_task(function* () {
is(checkboxItems[0].hasAttribute("checked"), expectedStates[0], `checkbox item 1 has state (checked=${expectedStates[0]})`);
is(checkboxItems[1].hasAttribute("checked"), expectedStates[1], `checkbox item 2 has state (checked=${expectedStates[1]})`);
is(checkboxItems[2].hasAttribute("checked"), expectedStates[2], `checkbox item 3 has state (checked=${expectedStates[2]})`);
return extensionMenuRoot.getElementsByAttribute("type", "checkbox");
}
+ function confirmOnClickData(onClickData, id, was, checked) {
+ is(onClickData.wasChecked, was, `checkbox item ${id} was ${was ? "" : "not "}checked before the click`);
+ is(onClickData.checked, checked, `checkbox item ${id} is ${checked ? "" : "not "}checked after the click`);
+ }
+
let extensionMenuRoot = yield openExtensionContextMenu();
let items = confirmCheckboxStates(extensionMenuRoot, [false, true, false]);
yield closeExtensionContextMenu(items[0]);
+ let result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 1, false, true);
+
extensionMenuRoot = yield openExtensionContextMenu();
items = confirmCheckboxStates(extensionMenuRoot, [true, true, false]);
yield closeExtensionContextMenu(items[2]);
+ result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 3, false, true);
+
extensionMenuRoot = yield openExtensionContextMenu();
items = confirmCheckboxStates(extensionMenuRoot, [true, true, true]);
yield closeExtensionContextMenu(items[0]);
+ result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 1, true, false);
+
extensionMenuRoot = yield openExtensionContextMenu();
items = confirmCheckboxStates(extensionMenuRoot, [false, true, true]);
yield closeExtensionContextMenu(items[2]);
+ result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 3, true, false);
+
yield extension.unload();
yield BrowserTestUtils.removeTab(tab1);
});
--- a/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js
+++ b/browser/components/extensions/test/browser/browser_ext_contextMenus_radioGroups.js
@@ -9,16 +9,21 @@ add_task(function* () {
gBrowser.selectedTab = tab1;
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"permissions": ["contextMenus"],
},
background: function() {
+ // Report onClickData info back.
+ browser.contextMenus.onClicked.addListener(info => {
+ browser.test.sendMessage("contextmenus-click", info);
+ });
+
browser.contextMenus.create({
title: "radio-group-1",
type: "radio",
checked: true,
});
browser.contextMenus.create({
type: "separator",
@@ -52,27 +57,44 @@ add_task(function* () {
is(radioGroup1[0].hasAttribute("checked"), expectedStates[0], `radio item 1 has state (checked=${expectedStates[0]})`);
is(radioGroup2[0].hasAttribute("checked"), expectedStates[1], `radio item 2 has state (checked=${expectedStates[1]})`);
is(radioGroup2[1].hasAttribute("checked"), expectedStates[2], `radio item 3 has state (checked=${expectedStates[2]})`);
return extensionMenuRoot.getElementsByAttribute("type", "radio");
}
+ function confirmOnClickData(onClickData, id, was, checked) {
+ is(onClickData.wasChecked, was, `radio item ${id} was ${was ? "" : "not "}checked before the click`);
+ is(onClickData.checked, checked, `radio item ${id} is ${checked ? "" : "not "}checked after the click`);
+ }
+
let extensionMenuRoot = yield openExtensionContextMenu();
let items = confirmRadioGroupStates(extensionMenuRoot, [true, false, false]);
yield closeExtensionContextMenu(items[1]);
+ let result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 2, false, true);
+
extensionMenuRoot = yield openExtensionContextMenu();
items = confirmRadioGroupStates(extensionMenuRoot, [true, true, false]);
yield closeExtensionContextMenu(items[2]);
- extensionMenuRoot = yield openExtensionContextMenu();
- items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
- yield closeExtensionContextMenu(items[0]);
+ result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 3, false, true);
extensionMenuRoot = yield openExtensionContextMenu();
items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
yield closeExtensionContextMenu(items[0]);
+ result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 1, true, true);
+
+ extensionMenuRoot = yield openExtensionContextMenu();
+ items = confirmRadioGroupStates(extensionMenuRoot, [true, false, true]);
+ yield closeExtensionContextMenu(items[0]);
+
+ result = yield extension.awaitMessage("contextmenus-click");
+ confirmOnClickData(result, 1, true, true);
+
yield extension.unload();
yield BrowserTestUtils.removeTab(tab1);
});
--- a/browser/components/extensions/test/browser/context.html
+++ b/browser/components/extensions/test/browser/context.html
@@ -9,10 +9,14 @@
<a href="some-link" id="link1">Some link</a>
</p>
<p>
<a href="image-around-some-link">
<img src="ctxmenu-image.png" id="img-wrapped-in-link">
</a>
</p>
+
+ <p>
+ <input type="text" id="edit-me">
+ </p>
</body>
</html>