Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Merge branch 'bug616758'
Browse files Browse the repository at this point in the history
  • Loading branch information
0c0w3 committed Dec 5, 2010
2 parents 10074f5 + 6c7a11a commit f801826
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 56 deletions.
80 changes: 46 additions & 34 deletions packages/addon-kit/docs/context-menu.md
Expand Up @@ -143,14 +143,15 @@ on a page whose URL contains "mozilla" as a substring:

var myItem = contextMenu.Item({
label: "My Mozilla Item",
contentScript: 'on("context", function (node) {' +
contentScript: 'on("context", function (event) {' +
' return /mozilla/.test(document.URL);' +
'});'
});

Note that the listener function has a parameter called `node`. This is the node
in the page that the user context-clicked to invoke the menu. You can use it to
determine whether your item should be shown.
Note that the listener function has a parameter called `event`. This is an
object with a single property `node`, which is the node in the page that the
user context-clicked to invoke the menu. You can use it to determine whether
your item should be shown.

You can both specify declarative contexts and listen for contexts in a content
script. In that case, the declarative contexts are evaluated first. If they
Expand All @@ -162,8 +163,8 @@ This example takes advantage of that fact. The listener can be assured that
var myItem = contextMenu.Item({
label: "My Mozilla Image Item",
context: contextMenu.SelectorContext("img"),
contentScript: 'on("context", function (node) {' +
' return /mozilla/.test(node.src);' +
contentScript: 'on("context", function (event) {' +
' return /mozilla/.test(event.node.src);' +
'});'
});

Expand All @@ -183,21 +184,23 @@ script like so:

var myItem = contextMenu.Item({
label: "My Item",
contentScript: 'on("click", function (node, data) {' +
contentScript: 'on("click", function (event) {' +
' console.log("Item clicked!");' +
'});'
});

Note that the listener function has parameters called `node` and `data`. `node`
is the node that the user context-clicked to invoke the menu. You can use it
when performing some action. `data` is the `data` property of the menu item
that was clicked. Since only top-level menu items have content scripts, this
comes in handy for `Menu`s with sub-items. For example:
Note that the listener function has a parameter called `event`. As with the
`"context"` event, this is an object that describes an event, in this case the
`"click"` event. It has two properties, `node` and `data`. `node` is the node
that the user context-clicked to invoke the menu. You can use it when
performing some action. `data` is the `data` property of the menu item that was
clicked. Since only top-level menu items have content scripts, `data` comes in
handy for `Menu`s with sub-items. For example:

var myMenu = contextMenu.Menu({
label: "My Menu",
contentScript: 'on("click", function (node, data) {' +
' console.log("You clicked " + data);' +
contentScript: 'on("click", function (event) {' +
' console.log("You clicked " + event.data);' +
'});',
items: [
contextMenu.Item({ label: "Item 1", data: "item1" }),
Expand All @@ -215,14 +218,19 @@ associated with the content script, the content script can call the global
var myItem = contextMenu.Item({
label: "Edit Image",
context: contextMenu.SelectorContext("img"),
contentScript: 'on("click", function (node, data) {' +
' postMessage(node.src);' +
contentScript: 'on("click", function (event) {' +
' postMessage(event.node.src);' +
'});',
onMessage: function (imgSrc) {
onMessage: function (event) {
var imgSrc = event.data;
openImageEditor(imgSrc);
}
});

The `event` object passed to `onMessage` has two properties, `data` and
`emitter`. `data` is the message passed from the content script's
`postMessage`. `emitter` is the item that owns the content script, in this
case `myItem`.


Examples
Expand All @@ -247,10 +255,11 @@ part of the page:

var pageSourceItem = contextMenu.Item({
label: "Edit Page Source",
contentScript: 'on("click", function (node, data) {' +
contentScript: 'on("click", function (event) {' +
' postMessage(document.URL);' +
'});',
onMessage: function (pageURL) {
onMessage: function (event) {
var pageURL = event.data;
editSource(page.URL);
}
});
Expand All @@ -260,10 +269,11 @@ Show an "Edit Image" item when the menu is invoked on an image:
var editImageItem = contextMenu.Item({
label: "Edit Image",
context: contextMenu.SelectorContext("img"),
contentScript: 'on("click", function (node, data) {' +
' postMessage(node.src);' +
contentScript: 'on("click", function (event) {' +
' postMessage(event.node.src);' +
'});',
onMessage: function (imgSrc) {
onMessage: function (event) {
var imgSrc = event.data;
openImageEditor(imgSrc);
}
});
Expand All @@ -277,10 +287,11 @@ mozilla.org or mozilla.com page:
contextMenu.URLContext(["*.mozilla.org", "*.mozilla.com"]),
contextMenu.SelectorContext("img")
],
contentScript: 'on("click", function (node, data) {' +
' postMessage(node.src);' +
contentScript: 'on("click", function (event) {' +
' postMessage(event.node.src);' +
'});',
onMessage: function (imgSrc) {
onMessage: function (event) {
var imgSrc = event.data;
openImageEditor(imgSrc);
}
});
Expand All @@ -291,18 +302,19 @@ Show an "Edit Page Images" item when the page contains at least one image:
label: "Edit Page Images",
// This ensures the item only appears during the page context.
context: contextMenu.PageContext(),
contentScript: 'on("context", function (node) {' +
contentScript: 'on("context", function (event) {' +
' var pageHasImgs = !!document.querySelector("img");' +
' return pageHasImgs;' +
'});' +
'on("click", function (node, data) {' +
'on("click", function (event) {' +
' var imgs = document.querySelectorAll("img");' +
' var imgSrcs = [];' +
' for (var i = 0 ; i < imgs.length; i++)' +
' imgSrcs.push(imgs[i].src);' +
' postMessage(imgSrcs);' +
'});',
onMessage: function (imgSrcs) {
onMessage: function (event) {
var imgSrcs = event.data;
openImageEditor(imgSrcs);
}
});
Expand All @@ -321,8 +333,8 @@ Google or Wikipedia with the text contained in the anchor:
var searchMenu = contextMenu.Menu({
label: "Search With",
context: contextMenu.SelectorContext("a[href]"),
contentScript: 'on("click", function (node, data) {' +
' var searchURL = data + node.textContent;' +
contentScript: 'on("click", function (event) {' +
' var searchURL = event.data + event.node.textContent;' +
' window.location.href = searchURL;' +
'});',
items: [googleItem, wikipediaItem]
Expand Down Expand Up @@ -359,8 +371,8 @@ A labeled menu item that can perform an action when clicked.
@prop [onMessage] {function}
If the item is contained in the top-level context menu, this function will
be called when the content script calls `postMessage`. It will be passed
the data that was passed to `postMessage`. Ignored if the item is contained
in a submenu.
an event object with one property `data` whose value is the data that was
passed to `postMessage`. Ignored if the item is contained in a submenu.
</api>
<api name="destroy">
@method
Expand Down Expand Up @@ -399,8 +411,8 @@ A labeled menu item that expands into a submenu.
@prop [onMessage] {function}
If the menu is contained in the top-level context menu, this function will
be called when the content script calls `postMessage`. It will be passed
the data that was passed to `postMessage`. Ignored if the menu is contained
in a submenu.
an event object with one property `data` whose value is the data that was
passed to `postMessage`. Ignored if the item is contained in a submenu.
</api>
<api name="destroy">
@method
Expand Down
6 changes: 3 additions & 3 deletions packages/addon-kit/lib/context-menu.js
Expand Up @@ -434,7 +434,7 @@ const ContextMenuWorker = Worker.compose({
isAnyContextCurrent: function CMW_isAnyContextCurrent(popupNode) {
let listeners = this._port._listeners("context");
for (let i = 0; i < listeners.length; i++)
if (listeners[i].call(this._port._sandbox, popupNode))
if (listeners[i].call(this._port._sandbox, { node: popupNode }))
return true;
return false;
},
Expand All @@ -443,7 +443,7 @@ const ContextMenuWorker = Worker.compose({
// context-clicked, and clickedItemData is the data of the item that was
// clicked.
fireClick: function CMW_fireClick(popupNode, clickedItemData) {
this._port._emit("click", popupNode, clickedItemData);
this._port._emit("click", { node: popupNode, data: clickedItemData });
},

// Frees the worker's resources.
Expand Down Expand Up @@ -609,7 +609,7 @@ WorkerRegistry.prototype = {
worker.on("message", function workerOnMessage(msg) {
if (item.onMessage) {
try {
item.onMessage(msg);
item.onMessage({ data: msg, emitter: item });
}
catch (err) {
console.exception(err);
Expand Down
40 changes: 21 additions & 19 deletions packages/addon-kit/tests/test-context-menu.js
Expand Up @@ -348,13 +348,14 @@ exports.testContentContextArgs = function (test) {

let item = new loader.cm.Item({
label: "item",
contentScript: 'on("context", function (node) {' +
contentScript: 'on("context", function (evt) {' +
' let Ci = Components.interfaces;' +
' postMessage(node instanceof Ci.nsIDOMHTMLElement);' +
' postMessage(evt.node instanceof Ci.nsIDOMHTMLElement);' +
' return false;' +
'});',
onMessage: function (isElt) {
test.assert(isElt, "node should be an HTML element");
onMessage: function (evt) {
test.assert(evt.data, "node should be an HTML element");
test.assertEqual(evt.emitter, item, "event.emitter should be item");
test.done();
}
});
Expand Down Expand Up @@ -760,17 +761,17 @@ exports.testItemClick = function (test) {
let item = new loader.cm.Item({
label: "item",
data: "item data",
contentScript: 'on("click", function (node, data) {' +
contentScript: 'on("click", function (evt) {' +
' let Ci = Components.interfaces;' +
' postMessage({' +
' isElt: node instanceof Ci.nsIDOMHTMLElement,' +
' data: data' +
' isElt: evt.node instanceof Ci.nsIDOMHTMLElement,' +
' data: evt.data' +
' });' +
'});',
onMessage: function (data) {
onMessage: function (evt) {
test.assertEqual(this, item, "`this` inside onMessage should be item");
test.assert(data.isElt, "node should be an HTML element");
test.assertEqual(data.data, item.data, "data should be item data");
test.assert(evt.data.isElt, "node should be an HTML element");
test.assertEqual(evt.data.data, item.data, "data should be item data");
test.done();
}
});
Expand Down Expand Up @@ -806,17 +807,18 @@ exports.testMenuClick = function (test) {

let topMenu = new loader.cm.Menu({
label: "top menu",
contentScript: 'on("click", function (node, data) {' +
contentScript: 'on("click", function (evt) {' +
' let Ci = Components.interfaces;' +
' postMessage({' +
' isAnchor: node instanceof Ci.nsIDOMHTMLAnchorElement,' +
' data: data' +
' isAnchor:' +
' evt.node instanceof Ci.nsIDOMHTMLAnchorElement,' +
' data: evt.data' +
' });' +
'});',
onMessage: function (data) {
onMessage: function (evt) {
test.assertEqual(this, topMenu, "`this` inside top menu should be menu");
test.assert(data.isAnchor, "Clicked node should be anchor");
test.assertEqual(data.data, item.data,
test.assert(evt.data.isAnchor, "Clicked node should be anchor");
test.assertEqual(evt.data.data, item.data,
"Clicked item data should be correct");
test.done();
},
Expand Down Expand Up @@ -1026,15 +1028,15 @@ exports.testContentCommunication = function (test) {
let item = new loader.cm.Item({
label: "item",
contentScript: 'var potato;' +
'on("context", function (node) {' +
'on("context", function () {' +
' potato = "potato";' +
' return true;' +
'});' +
'on("click", function () {' +
' postMessage(potato);' +
'});',
onMessage: function (potato) {
test.assertEqual(potato, "potato", "That's a lot of potatoes!");
onMessage: function (evt) {
test.assertEqual(evt.data, "potato", "That's a lot of potatoes!");
test.done();
}
});
Expand Down

0 comments on commit f801826

Please sign in to comment.