Skip to content

Commit

Permalink
adding patch for firefox nightlies (FF8) and adding handling for FF-s…
Browse files Browse the repository at this point in the history
…pecific implementation of contextmenu which uses menuitems
  • Loading branch information
addyosmani committed Aug 20, 2011
1 parent 74b4afd commit 90ece45
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 20 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
# jQuery contextMenu Plugin #
# jQuery contextMenu plugin & polyfill #

$.contextMenu is a management facility for - you guessed it - context menus.
It was designed for an application where there are hundreds of elements that may show a context menu - so intialization speed and memory usage are kept fairly small. It also allows to register context menus without providing actual markup, as $.contextMenu generates DOMElements as needed.

##Reasons for this fork:

1) The official release of $.contextMenu is missing a test to check for native support of contextmenu in the browser.

2) The Firefox nightlies implement contextmenu using the 'menuitem' tags for menu-structure. The specs however state that 'command' tags should be used for this purpose. Whilst the contextMenu plugin handles correct support for 'command' items, it doesn't for 'menuitem'. My fork handles this.

[contextmenu specs](http://www.w3.org/TR/html5/interactive-elements.html#context-menus)


##Original summary

$.contextMenu is a management facility for - you guessed it - context menus. It was designed for an application where there are hundreds of elements that may show a context menu - so intialization speed and memory usage are kept fairly small. It also allows to register context menus without providing actual markup, as $.contextMenu generates DOMElements as needed.

[features](http://medialize.github.com/jQuery-contextMenu/index.html) -
[demo](http://medialize.github.com/jQuery-contextMenu/demo.html) -
Expand Down
83 changes: 66 additions & 17 deletions jquery.contextMenu.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
/*
* jQuery contextMenu - Plugin for simple contextMenu handling
*
* Authors: Rodney Rehm
*
* Authors: Rodney Rehm, Addy Osmani (patches for FF)
* Web: http://medialize.github.com/jQuery-contextMenu/
*
* Reasons for this fork:
*
* 1) The official release of contextMenu is missing a test to check
* for native support of contextmenu in the browser.
*
* 2) The Firefox nightlies implement contextmenu using the 'menuitem' tags
* for menu-structure. The specs however state that 'command' tags should
* be used for this purpose. Whilst the contextMenu plugin handles correct
* support for 'command' items, it doesn't for 'menuitem'. My fork handles
* this.
*
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
Expand All @@ -15,7 +26,7 @@
// ARIA stuff: menuitem, menuitemcheckbox und menuitemradio

/*
Mozilla extension experiment…
Mozilla support (firefox nightlies):
https://bugzilla.mozilla.org/show_bug.cgi?id=617528
-> http://people.mozilla.com/~prouget/bugs/context-menu-test/nativemenu.xpi
Expand Down Expand Up @@ -53,7 +64,7 @@ var // currently active contextMenu trigger
// position to the lower middle of the trigger element
if ($.ui && $.ui.position) {
// .position() is provided as a jQuery UI utility
// and it won't work on hidden elements
// …and it won't work on hidden elements
$menu.css('display', 'block').position({
my: "center top",
at: "center bottom",
Expand Down Expand Up @@ -106,7 +117,7 @@ var // currently active contextMenu trigger
positionSubmenu: function($menu) {
if ($.ui && $.ui.position) {
// .position() is provided as a jQuery UI utility
// and it won't work on hidden elements
// …and it won't work on hidden elements
$menu.css('display', 'block').position({
my: "left top",
at: "right top",
Expand Down Expand Up @@ -163,7 +174,7 @@ var // currently active contextMenu trigger
// event handlers
handle = {
// abort anything
abortevent: function(e){
abortevent: function(e){
e.preventDefault();
e.stopImmediatePropagation();
},
Expand Down Expand Up @@ -286,7 +297,7 @@ var // currently active contextMenu trigger
var $this = $(this),
root = $this.data('contextMenuRoot');

e.preventDefault();
e.preventDefault();
e.stopImmediatePropagation();
$this.remove();
op.hide.call(root.$trigger, root);
Expand Down Expand Up @@ -599,7 +610,7 @@ var // currently active contextMenu trigger
op = {
show: function(opt, x, y) {
var $this = $(this),
offset,
offset,
css = {};

// hide any open menus
Expand Down Expand Up @@ -642,7 +653,7 @@ var // currently active contextMenu trigger
// mouse position handler
$(document).bind('mousemove.contextMenuAutoHide', function(e) {
if (opt.$layer && !opt.hovering && (!(e.pageX >= pos.left && e.pageX <= pos.right) || !(e.pageY >= pos.top && e.pageY <= pos.bottom))) {
// if mouse in menu…
// if mouse in menu…
opt.$layer.trigger('mousedown');
}
});
Expand Down Expand Up @@ -698,7 +709,7 @@ var // currently active contextMenu trigger
// create contextMenu items
$.each(opt.items, function(key, item){
var $t = $('<li class="context-menu-item ' + (item.className || "") +'"></li>'),
$label = null,
$label = null,
$input = null;

item.$node = $t.data({
Expand Down Expand Up @@ -1001,15 +1012,16 @@ $.contextMenu = function(operation, options) {
break;

case 'html5':
// TODO: detect if html5 contextmenu is supported
if(!('HTMLMenuItemElement' in window) || !('HTMLCommandElement' in window)){
$('menu[type="context"]').each(function(){
if (this.id) {
$.contextMenu({
selector: '[contextmenu=' + this.id +']',
selector: '[contextmenu=' + this.id +']',
items: $.contextMenu.fromMenu(this)
});
}
}).css('display', 'none');
}
break;

default:
Expand Down Expand Up @@ -1104,7 +1116,7 @@ function menuChildren(items, $children, counter) {

/*
* <menu> accepts flow-content as children. that means <embed>, <canvas> and such are valid menu items.
* Not being the sadistic kind, $.contextMenu only accepts:
* Not being the sadistic kind, $.contextMenu only accepts:
* <command>, <hr>, <span>, <p> <input [text, radio, checkbox]>, <textarea>, <select> and of course <menu>.
* Everything else will be imported as an html node, which is not interfaced with contextMenu.
*/
Expand All @@ -1120,19 +1132,20 @@ function menuChildren(items, $children, counter) {
// http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#using-the-a-element-to-define-a-command
case 'a':
item = {
name: $node.text(),
name: $node.text(),
callback: (function(){ return function(){ $node.click(); }; })()
};
break;

// http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#using-the-command-element-to-define-a-command

case 'command':
switch (node.type) {
case undefined:
case 'command':
item = {
name: $node.attr('label'),
disabled: node.disabled,
name: $node.attr('label'),
disabled: node.disabled,
callback: (function(){ return function(){ node.click(); }; })()
};
break;
Expand Down Expand Up @@ -1161,6 +1174,42 @@ function menuChildren(items, $children, counter) {
item = undefined;
}
break;

case 'menuitem':
switch (node.type) {
case undefined:
case 'menuitem':
item = {
name: $node.attr('label'),
disabled: node.disabled,
callback: (function(){ return function(){ node.click(); }; })()
};
break;

case 'checkbox':
item = {
type: 'text',
disabled: node.disabled,
name: $node.attr('label'),
selected: node.checked
};
break;

case 'radio':
item = {
type: 'text',
disabled: node.disabled,
name: $node.attr('label'),
radio: node.radiogroup ,
value: node.id,
selected: node.checked
};
break;

default:
item = undefined;
}
break;

case 'hr':
item = '-------';
Expand Down Expand Up @@ -1248,4 +1297,4 @@ $.contextMenu.fromMenu = function(element) {
// make defaults accessible
$.contextMenu.defaults = defaults;

})(jQuery);
})(jQuery);

0 comments on commit 90ece45

Please sign in to comment.