From 3b9c2beb399ce9001bdeb8ca3d1be51185411e10 Mon Sep 17 00:00:00 2001
From: "Martin@MBP" vjK*tEeSVX7B@Iuc=uSbu-m}Y2XfMMt~Q6sE{Cx-L@5fjAM
z$IAOBFJeXj18)K$C9IOqJm+^R3PWUq7>jrjwlz31NEa0qWf0XKH66t~3^QC1g@$oM
zFU$0eUl(^MZbHnb2xN|T22+;x81@(}O)3=^J;r Right-click in an element to open the context menu:jquery.ui-contextmenu.js
Sample 1
diff --git a/demo/sample.png b/demo/sample.png
new file mode 100644
index 0000000000000000000000000000000000000000..0211cf8b8ce493c916f87ef5005ad32185db7d87
GIT binary patch
literal 17119
zcmZU)18`_Tvo0DtJGO1xwv!#(wry+2wr$(CZQD*>{&ViT=e&BWYH3>2JykP3{jC))
zFDnKMg$V@!001i?F0A-_|M@+=A%K3b`-p_H008JJ=0Za95<)`w@(#8p=2pf40BVp`
z>dtD&x-UHqW3(MkuCA`)t`ck!6N*w&k@yr)rFwZlU`6>50f2;r__^c(L4JCE5fS+Y
zx#UkBk#}FbHxJ!EUnV(eZ, or a definition hash
- position: null, // popup positon
- preventContextMenuForPopup: false, // prevent opening the browser's system context menu on menu entries
- preventSelect: false, // disable text selection of target
- show: { effect: "slideDown", duration: "fast"},
- taphold: false, // open menu on taphold events (requires external plugins)
- uiMenuOptions: {}, // Additional options, used when UI Menu is created
- // Events:
- beforeOpen: $.noop, // menu about to open; return `false` to prevent opening
- blur: $.noop, // menu option lost focus
- close: $.noop, // menu was closed
- create: $.noop, // menu was initialized
- createMenu: $.noop, // menu was initialized (original UI Menu)
- focus: $.noop, // menu option got focus
- open: $.noop, // menu was opened
- select: $.noop // menu option was selected; return `false` to prevent closing
- },
- /** Constructor */
- _create: function () {
- var cssText, eventNames, targetId,
- opts = this.options;
+"use strict";
- this.$headStyle = null;
- this.$menu = null;
- this.menuIsTemp = false;
- this.currentTarget = null;
+var supportSelectstart = "onselectstart" in document.createElement("div"),
+ match, uiVersion;
- if(opts.preventSelect){
- // Create a global style for all potential menu targets
- // If the contextmenu was bound to `document`, we apply the
- // selector relative to the tag instead
- targetId = ($(this.element).is(document) ? $("body") : this.element).uniqueId().attr("id");
- cssText = "#" + targetId + " " + opts.delegate + " { " +
- "-webkit-user-select: none; " +
- "-khtml-user-select: none; " +
- "-moz-user-select: none; " +
- "-ms-user-select: none; " +
- "user-select: none; " +
- "}";
- this.$headStyle = $("
")
- .prop("type", "text/css")
- .appendTo("head");
+$.widget("moogle.contextmenu", {
+ version: "@VERSION",
+ options: {
+ autoTrigger: true, // open menu on browser's `contextmenu` event
+ delegate: null, // selector
+ hide: { effect: "fadeOut", duration: "fast" },
+ ignoreParentSelect: true, // Don't trigger 'select' for sub-menu parents
+ menu: null, // selector or jQuery pointing to
, or a definition hash
+ position: null, // popup positon
+ preventContextMenuForPopup: false, // prevent opening the browser's system
+ // context menu on menu entries
+ preventSelect: false, // disable text selection of target
+ show: { effect: "slideDown", duration: "fast" },
+ taphold: false, // open menu on taphold events (requires external plugins)
+ uiMenuOptions: {}, // Additional options, used when UI Menu is created
+ // Events:
+ beforeOpen: $.noop, // menu about to open; return `false` to prevent opening
+ blur: $.noop, // menu option lost focus
+ close: $.noop, // menu was closed
+ create: $.noop, // menu was initialized
+ createMenu: $.noop, // menu was initialized (original UI Menu)
+ focus: $.noop, // menu option got focus
+ open: $.noop, // menu was opened
+ select: $.noop // menu option was selected; return `false` to prevent closing
+ },
+ /** Constructor */
+ _create: function() {
+ var cssText, eventNames, targetId,
+ opts = this.options;
- try {
- this.$headStyle.html(cssText);
- } catch( e ) {
- // issue #47: fix for IE 6-8
- this.$headStyle[0].styleSheet.cssText = cssText;
- }
+ this.$headStyle = null;
+ this.$menu = null;
+ this.menuIsTemp = false;
+ this.currentTarget = null;
- // TODO: the selectstart is not supported by FF?
- if(supportSelectstart){
- this.element.delegate(opts.delegate, "selectstart" + this.eventNamespace, function(event){
- event.preventDefault();
- });
- }
- }
- this._createUiMenu(opts.menu);
+ if (opts.preventSelect) {
+ // Create a global style for all potential menu targets
+ // If the contextmenu was bound to `document`, we apply the
+ // selector relative to the tag instead
+ targetId = ($(this.element).is(document) ? $("body")
+ : this.element).uniqueId().attr("id");
+ cssText = "#" + targetId + " " + opts.delegate + " { " +
+ "-webkit-user-select: none; " +
+ "-khtml-user-select: none; " +
+ "-moz-user-select: none; " +
+ "-ms-user-select: none; " +
+ "user-select: none; " +
+ "}";
+ this.$headStyle = $("")
+ .prop("type", "text/css")
+ .appendTo("head");
- eventNames = "contextmenu" + this.eventNamespace;
- if(opts.taphold){
- eventNames += " taphold" + this.eventNamespace;
+ try {
+ this.$headStyle.html(cssText);
+ } catch ( e ) {
+ // issue #47: fix for IE 6-8
+ this.$headStyle[0].styleSheet.cssText = cssText;
}
- this.element.delegate(opts.delegate, eventNames, $.proxy(this._openMenu, this));
- },
- /** Destructor, called on $().contextmenu("destroy"). */
- _destroy: function(){
- this.element.undelegate(this.eventNamespace);
+ // TODO: the selectstart is not supported by FF?
+ if (supportSelectstart) {
+ this.element.delegate(opts.delegate, "selectstart" + this.eventNamespace,
+ function(event) {
+ event.preventDefault();
+ });
+ }
+ }
+ this._createUiMenu(opts.menu);
- this._createUiMenu(null);
+ eventNames = "contextmenu" + this.eventNamespace;
+ if (opts.taphold) {
+ eventNames += " taphold" + this.eventNamespace;
+ }
+ this.element.delegate(opts.delegate, eventNames, $.proxy(this._openMenu, this));
+ },
+ /** Destructor, called on $().contextmenu("destroy"). */
+ _destroy: function() {
+ this.element.undelegate(this.eventNamespace);
- if(this.$headStyle){
- this.$headStyle.remove();
- this.$headStyle = null;
- }
- },
- /** (Re)Create jQuery UI Menu. */
- _createUiMenu: function(menuDef){
- var ct;
- // Remove temporary
if any
- if(this.isOpen()){
- ct = this.currentTarget; // #58: 'replaceMenu' in beforeOpen causing select: to lose ui.target
- // close without animation, to force async mode
- this._closeMenu(true);
- this.currentTarget = ct;
- }
+ this._createUiMenu(null);
- if(this.menuIsTemp){
- this.$menu.remove(); // this will also destroy ui.menu
- } else if(this.$menu){
- this.$menu.menu("destroy").hide();
- }
- this.$menu = null;
- this.menuIsTemp = false;
- // If a menu definition array was passed, create a hidden
- // and generate the structure now
- if( ! menuDef ){
- return;
- } else if($.isArray(menuDef)){
- this.$menu = $.moogle.contextmenu.createMenuMarkup(menuDef);
- this.menuIsTemp = true;
- }else if ( typeof menuDef === "string" ){
- this.$menu = $(menuDef);
- }else{
- this.$menu = menuDef;
- }
- // Create - but hide - the jQuery UI Menu widget
- this.$menu
- .hide()
+ if (this.$headStyle) {
+ this.$headStyle.remove();
+ this.$headStyle = null;
+ }
+ },
+ /** (Re)Create jQuery UI Menu. */
+ _createUiMenu: function(menuDef) {
+ var ct;
+ // Remove temporary
if any
+ if (this.isOpen()) {
+ // #58: 'replaceMenu' in beforeOpen causing select: to lose ui.target
+ ct = this.currentTarget;
+ // close without animation, to force async mode
+ this._closeMenu(true);
+ this.currentTarget = ct;
+ }
+
+ if (this.menuIsTemp) {
+ this.$menu.remove(); // this will also destroy ui.menu
+ } else if (this.$menu) {
+ this.$menu.menu("destroy").hide();
+ }
+ this.$menu = null;
+ this.menuIsTemp = false;
+ // If a menu definition array was passed, create a hidden
+ // and generate the structure now
+ if ( !menuDef ) {
+ return;
+ } else if ($.isArray(menuDef)) {
+ this.$menu = $.moogle.contextmenu.createMenuMarkup(menuDef);
+ this.menuIsTemp = true;
+ }else if ( typeof menuDef === "string" ) {
+ this.$menu = $(menuDef);
+ } else {
+ this.$menu = menuDef;
+ }
+ // Create - but hide - the jQuery UI Menu widget
+ this.$menu
+ .hide()
// .addClass("moogle-contextmenu")
- // Create a menu instance that delegates events to our widget
- .menu($.extend(true, {}, this.options.uiMenuOptions, {
- blur: $.proxy(this.options.blur, this),
- create: $.proxy(this.options.createMenu, this),
- focus: $.proxy(this.options.focus, this),
- select: $.proxy(function(event, ui){
- // User selected a menu entry
- var retval,
- isParent = $.moogle.contextmenu.isMenu(ui.item),
- actionHandler = ui.item.data("actionHandler");
- ui.cmd = ui.item.attr("data-command");
- ui.target = $(this.currentTarget);
- // ignore clicks, if they only open a sub-menu
- if( !isParent || !this.options.ignoreParentSelect){
- retval = this._trigger.call(this, "select", event, ui);
- if( actionHandler ){
- retval = actionHandler.call(this, event, ui);
- }
- if( retval !== false ){
- this._closeMenu.call(this);
- }
- event.preventDefault();
+ // Create a menu instance that delegates events to our widget
+ .menu($.extend(true, {}, this.options.uiMenuOptions, {
+ blur: $.proxy(this.options.blur, this),
+ create: $.proxy(this.options.createMenu, this),
+ focus: $.proxy(this.options.focus, this),
+ select: $.proxy(function(event, ui) {
+ // User selected a menu entry
+ var retval,
+ isParent = $.moogle.contextmenu.isMenu(ui.item),
+ actionHandler = ui.item.data("actionHandler");
+ ui.cmd = ui.item.attr("data-command");
+ ui.target = $(this.currentTarget);
+ // ignore clicks, if they only open a sub-menu
+ if ( !isParent || !this.options.ignoreParentSelect) {
+ retval = this._trigger.call(this, "select", event, ui);
+ if ( actionHandler ) {
+ retval = actionHandler.call(this, event, ui);
}
- }, this)
- }));
- },
- /** Open popup (called on 'contextmenu' event). */
- _openMenu: function(event){
- var opts = this.options,
- posOption = opts.position,
- self = this,
- manualTrigger = !!event.isTrigger,
- ui = {menu: this.$menu, target: $(event.target), extraData: event.extraData, originalEvent: event};
+ if ( retval !== false ) {
+ this._closeMenu.call(this);
+ }
+ event.preventDefault();
+ }
+ }, this)
+ }));
+ },
+ /** Open popup (called on 'contextmenu' event). */
+ _openMenu: function(event) {
+ var opts = this.options,
+ posOption = opts.position,
+ self = this,
+ manualTrigger = !!event.isTrigger,
+ ui = { menu: this.$menu, target: $(event.target),
+ extraData: event.extraData, originalEvent: event };
- if( !opts.autoTrigger && !manualTrigger ) {
- // ignore browser's `contextmenu` events
- return;
- }
- this.currentTarget = event.target;
+ if ( !opts.autoTrigger && !manualTrigger ) {
+ // ignore browser's `contextmenu` events
+ return;
+ }
+ this.currentTarget = event.target;
- // Prevent browser from opening the system context menu
- event.preventDefault();
+ // Prevent browser from opening the system context menu
+ event.preventDefault();
- if( this._trigger("beforeOpen", event, ui) === false ){
- this.currentTarget = null;
- return false;
+ if ( this._trigger("beforeOpen", event, ui) === false ) {
+ this.currentTarget = null;
+ return false;
+ }
+ ui.menu = this.$menu; // Might have changed in beforeOpen
+ // Register global event handlers that close the dropdown-menu
+ $(document).bind("keydown" + this.eventNamespace, function(event) {
+ if ( event.which === $.ui.keyCode.ESCAPE ) {
+ self._closeMenu();
}
- ui.menu = this.$menu; // Might have changed in beforeOpen
- // Register global event handlers that close the dropdown-menu
- $(document).bind("keydown" + this.eventNamespace, function(event){
- if( event.which === $.ui.keyCode.ESCAPE ){
- self._closeMenu();
- }
- }).bind("mousedown" + this.eventNamespace + " touchstart" + this.eventNamespace, function(event){
- // Close menu when clicked outside menu
- if( !$(event.target).closest(".ui-menu-item").length ){
- self._closeMenu();
- }
- });
-
- // required for custom positioning (issue #18 and #13).
- if ($.isFunction(posOption)) {
- posOption = posOption(event, ui);
+ }).bind("mousedown" + this.eventNamespace + " touchstart" + this.eventNamespace,
+ function(event) {
+ // Close menu when clicked outside menu
+ if ( !$(event.target).closest(".ui-menu-item").length ) {
+ self._closeMenu();
}
- posOption = $.extend({
- my: "left top",
- at: "left bottom",
- // if called by 'open' method, event does not have pageX/Y
- of: (event.pageX === undefined) ? event.target : event,
- collision: "fit"
- }, posOption);
+ });
+
+ // required for custom positioning (issue #18 and #13).
+ if ($.isFunction(posOption)) {
+ posOption = posOption(event, ui);
+ }
+ posOption = $.extend({
+ my: "left top",
+ at: "left bottom",
+ // if called by 'open' method, event does not have pageX/Y
+ of: (event.pageX === undefined) ? event.target : event,
+ collision: "fit"
+ }, posOption);
- // Finally display the popup
- this.$menu
- .show() // required to fix positioning error
- .css({
- position: "absolute",
- left: 0,
- top: 0
- }).position(posOption)
- .hide(); // hide again, so we can apply nice effects
+ // Finally display the popup
+ this.$menu
+ .show() // required to fix positioning error
+ .css({
+ position: "absolute",
+ left: 0,
+ top: 0
+ }).position(posOption)
+ .hide(); // hide again, so we can apply nice effects
- if( opts.preventContextMenuForPopup ) {
- this.$menu.bind("contextmenu" + this.eventNamespace, function(event){
- event.preventDefault();
- });
- }
- this._show(this.$menu, this.options.show, function(){
- self._trigger.call(self, "open", event, ui);
+ if ( opts.preventContextMenuForPopup ) {
+ this.$menu.bind("contextmenu" + this.eventNamespace, function(event) {
+ event.preventDefault();
});
- },
- /** Close popup. */
- _closeMenu: function(immediately){
- var self = this,
- hideOpts = immediately ? false : this.options.hide;
+ }
+ this._show(this.$menu, this.options.show, function() {
+ self._trigger.call(self, "open", event, ui);
+ });
+ },
+ /** Close popup. */
+ _closeMenu: function(immediately) {
+ var self = this,
+ hideOpts = immediately ? false : this.options.hide;
- // Note: we don't want to unbind the 'contextmenu' event
- $(document)
- .unbind("mousedown" + this.eventNamespace)
- .unbind("touchstart" + this.eventNamespace)
- .unbind("keydown" + this.eventNamespace);
- this.$menu
- .unbind("contextmenu" + this.eventNamespace);
- self.currentTarget = null; // issue #44 after hide animation is too late
+ // Note: we don't want to unbind the 'contextmenu' event
+ $(document)
+ .unbind("mousedown" + this.eventNamespace)
+ .unbind("touchstart" + this.eventNamespace)
+ .unbind("keydown" + this.eventNamespace);
+ this.$menu
+ .unbind("contextmenu" + this.eventNamespace);
+ self.currentTarget = null; // issue #44 after hide animation is too late
- this._hide(this.$menu, hideOpts, function() {
- self._trigger("close");
- });
- },
- /** Handle $().contextmenu("option", key, value) calls. */
- _setOption: function(key, value){
- switch(key){
- case "menu":
- this.replaceMenu(value);
- break;
- }
- $.Widget.prototype._setOption.apply(this, arguments);
- },
- /** Return ui-menu entry (
structure. */
- createMenuMarkup: function(options, $parentUl){
- var i, menu, $ul, $li;
- if( $parentUl == null ){
- $parentUl = $("
").appendTo("body");
- }
- for(i = 0; i < options.length; i++){
- menu = options[i];
- $li = $("").appendTo($parentUl);
+/*
+ * Global functions
+ */
+$.extend($.moogle.contextmenu, {
+ /** Convert a nested array of command objects into a
structure. */
+ createMenuMarkup: function(options, $parentUl) {
+ var i, menu, $ul, $li;
+ if ( $parentUl == null ) {
+ $parentUl = $("
").appendTo("body");
+ }
+ for (i = 0; i < options.length; i++) {
+ menu = options[i];
+ $li = $("").appendTo($parentUl);
- $.moogle.contextmenu.createEntryMarkup(menu, $li);
+ $.moogle.contextmenu.createEntryMarkup(menu, $li);
- if( $.isArray(menu.children) ){
- $ul = $("
").appendTo($li);
- $.moogle.contextmenu.createMenuMarkup(menu.children, $ul);
- }
+ if ( $.isArray(menu.children) ) {
+ $ul = $("
").appendTo($li);
+ $.moogle.contextmenu.createMenuMarkup(menu.children, $ul);
}
- return $parentUl;
- },
- /** Replaces the value of elem's first text node child*/
- replaceFirstTextNodeChild: function(elem, text) {
- elem
- .contents()
- .filter(function(){ return this.nodeType === 3; })
- .first()
- .replaceWith(text);
}
- });
+ return $parentUl;
+ },
+ /** Replaces the value of elem's first text node child*/
+ replaceFirstTextNodeChild: function(elem, text) {
+ elem
+ .contents()
+ .filter(function() { return this.nodeType === 3; })
+ .first()
+ .replaceWith(text);
+ }
+});
- match = $.ui.menu.version.match(/^(\d)\.(\d+)/);
+match = $.ui.menu.version.match(/^(\d)\.(\d+)/);
- uiVersion = {
- major: parseInt(match[1], 10),
- minor: parseInt(match[2], 10)
- };
+uiVersion = {
+ major: parseInt(match[1], 10),
+ minor: parseInt(match[2], 10)
+};
- if ( uiVersion.major < 2 && uiVersion.minor < 11 ) {
- $.extend($.moogle.contextmenu, {
- /** Convert a menu description into a into a
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
\ No newline at end of file
diff --git a/package.json b/package.json
index 8817f49..a61aba4 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,8 @@
"grunt-exec": "~0.4.0",
"grunt-saucelabs": "~8.1.0",
"grunt-contrib-watch": "~0.5.3",
- "grunt-yabs": "^0.4.0"
+ "grunt-yabs": "^0.4.0",
+ "grunt-jscs": "^0.7.1"
},
"scripts": {
"test": "grunt ci --verbose"
diff --git a/test/tests.js b/test/tests.js
index d6af6ba..ad6680d 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -1,5 +1,6 @@
// jQUnit defines:
- // asyncTest,deepEqual,equal,expect,module,notDeepEqual,notEqual,notStrictEqual,ok,QUnit,raises,start,stop,strictEqual,test
+ // asyncTest,deepEqual,equal,expect,module,notDeepEqual,notEqual,notStrictEqual,
+ // ok,QUnit,raises,start,stop,strictEqual,test
/*globals asyncTest,equal,expect,module,ok,QUnit,start,test */
@@ -36,7 +37,6 @@ function TestHelpers() {
},
entryEvent: function( menu, item, type ) {
lastItem = item;
-// window.console.log(type + ": ", menu.children( ":eq(" + item + ")" ).find( "a:first" ).length);
if ( uiVersion.major < 2 && uiVersion.minor < 11 ) {
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( type );
} else {
@@ -45,7 +45,6 @@ function TestHelpers() {
},
click: function( menu, item ) {
lastItem = item;
-// window.console.log("clck: ", menu.children( ":eq(" + item + ")" ).find( "a:first" ).length);
if ( uiVersion.major < 2 && uiVersion.minor < 11 ) {
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( "click" );
} else {
@@ -58,11 +57,9 @@ function TestHelpers() {
};
}
-
// ****************************************************************************
-
-jQuery(document).ready(function(){
+jQuery(document).ready(function() {
/*******************************************************************************
* QUnit setup
@@ -70,7 +67,6 @@ jQuery(document).ready(function(){
QUnit.config.requireExpects = true;
-
var th = new TestHelpers(),
log = th.log,
logOutput = th.logOutput,
@@ -78,32 +74,32 @@ var th = new TestHelpers(),
entryEvent = th.entryEvent,
entry = th.entry,
lifecycle = {
- setup: function () {
+ setup: function() {
th.clearLog();
// Always create a fresh copy of the menu
definition
$("#sampleMenuTemplate").clone().attr("id", "sampleMenu").appendTo("body");
},
- teardown: function () {
+ teardown: function() {
$(":moogle-contextmenu").contextmenu("destroy");
$("#sampleMenu").remove();
}
},
SAMPLE_MENU = [
- {title: "Cut", cmd: "cut", uiIcon: "ui-icon-scissors"},
- {title: "Copy", cmd: "copy", uiIcon: "ui-icon-copy"},
- {title: "Paste", cmd: "paste", uiIcon: "ui-icon-clipboard", disabled: true },
- {title: "----"},
- {title: "More", children: [
- {title: "Sub Item 1", cmd: "sub1"},
- {title: "Sub Item 2", cmd: "sub2" }
- ]}
+ { title: "Cut", cmd: "cut", uiIcon: "ui-icon-scissors" },
+ { title: "Copy", cmd: "copy", uiIcon: "ui-icon-copy" },
+ { title: "Paste", cmd: "paste", uiIcon: "ui-icon-clipboard", disabled: true },
+ { title: "----" },
+ { title: "More", children: [
+ { title: "Sub Item 1", cmd: "sub1" },
+ { title: "Sub Item 2", cmd: "sub2" }
+ ] }
],
$ = jQuery,
sauceLabsLog = [];
// SauceLabs integration
-QUnit.testStart(function (testDetails) {
- QUnit.log(function(details){
+QUnit.testStart(function(testDetails) {
+ QUnit.log(function(details) {
if (!details.result) {
details.name = testDetails.name;
sauceLabsLog.push(details);
@@ -111,7 +107,7 @@ QUnit.testStart(function (testDetails) {
});
});
-QUnit.done(function (testResults) {
+QUnit.done(function(testResults) {
var tests = [],
i, len, details;
for (i = 0, len = sauceLabsLog.length; i < len; i++) {
@@ -126,27 +122,26 @@ QUnit.done(function (testResults) {
}
testResults.tests = tests;
- /*jshint camelcase:false*/
- window.global_test_results = testResults;
- /*jshint camelcase:true*/
+ /*jshint camelcase:false*/ // jscs: disable
+ window.global_test_results = testResults; // used by saucelabs
+ /*jshint camelcase:true*/ // jscs: enable
});
//---------------------------------------------------------------------------
module("prototype", lifecycle);
-test("globals", function(){
+test("globals", function() {
expect(2);
ok( !!$.moogle.contextmenu, "exists in ui namnespace");
ok( !!$.moogle.contextmenu.version, "has version number");
});
-
// ---------------------------------------------------------------------------
module("create", lifecycle);
-function _createTest(menu){
+function _createTest(menu) {
var $ctx;
expect(5);
@@ -156,10 +151,10 @@ function _createTest(menu){
delegate: ".hasmenu",
menu: menu,
preventSelect: true,
- create: function(){
+ create: function() {
log("create");
},
- createMenu: function(){
+ createMenu: function() {
log("createMenu");
}
});
@@ -172,29 +167,27 @@ function _createTest(menu){
$ctx.contextmenu("destroy");
equal( $(":moogle-contextmenu").length, 0, "widget destroyed");
-// ok( ! $("#sampleMenu").hasClass( "moogle-contextmenu" ), "Class removed from menu definition");
+// ok( !$("#sampleMenu").hasClass("moogle-contextmenu"),
+// "Class removed from menu definition");
equal( $("head style.moogle-contextmenu-style").length, 0, "global stylesheet removed");
equal(logOutput(), "constructor,createMenu,create,afterConstructor",
"Event sequence OK." );
}
-
-test("create from UL", function(){
+test("create from UL", function() {
_createTest("ul#sampleMenu");
});
-
-test("create from array", function(){
+test("create from array", function() {
_createTest(SAMPLE_MENU);
});
-
//---------------------------------------------------------------------------
module("open", lifecycle);
-function _openTest(menu){
+function _openTest(menu) {
var $ctx, $popup;
expect(18);
@@ -202,7 +195,7 @@ function _openTest(menu){
$("#container").contextmenu({
delegate: ".hasmenu",
menu: menu,
- beforeOpen: function(event, ui){
+ beforeOpen: function(event, ui) {
log("beforeOpen");
equal( event.type, "contextmenubeforeopen",
@@ -211,7 +204,7 @@ function _openTest(menu){
"beforeOpen: ui.target is set" );
ok( $popup.is(":hidden"),
"beforeOpen: Menu is hidden" );
- ok( ! entry($popup, 0).hasClass("ui-state-disabled"),
+ ok( !entry($popup, 0).hasClass("ui-state-disabled"),
"beforeOpen: Entry 0 is enabled" );
ok( entry($popup, 2).hasClass("ui-state-disabled"),
"beforeOpen: Entry 2 is disabled" );
@@ -221,7 +214,7 @@ function _openTest(menu){
$("#container").contextmenu("enableEntry", "cut", false);
$("#container").contextmenu("showEntry", "copy", false);
},
- open: function(event){
+ open: function(event) {
log("open");
ok( $popup.is(":visible"),
@@ -261,22 +254,19 @@ function _openTest(menu){
log("after open()");
}
-
-asyncTest("UL menu", function(){
+asyncTest("UL menu", function() {
_openTest("ul#sampleMenu");
});
-
-asyncTest("Array menu", function(){
+asyncTest("Array menu", function() {
_openTest(SAMPLE_MENU);
});
-
//---------------------------------------------------------------------------
module("click event sequence", lifecycle);
-function _clickTest(menu){
+function _clickTest(menu) {
var $ctx, $popup;
expect(3);
@@ -286,44 +276,44 @@ function _clickTest(menu){
menu: menu,
// show: false,
// hide: false,
- beforeOpen: function(event, ui){
+ beforeOpen: function(event, ui) {
log("beforeOpen(" + ui.target.text() + ")");
},
- create: function(event, ui){
+ create: function(event, ui) {
log("create");
},
- createMenu: function(event, ui){
+ createMenu: function(event, ui) {
log("createMenu");
},
/*TODO: Seems that focus gets called twice in Safary, but nod PhantomJS */
-// focus: function(event, ui){
+// focus: function(event, ui) {
// var t = ui.item ? $(ui.item).find("a:first").attr("href") : ui.item;
// log("focus(" + t + ")");
//// equal( ui.cmd, "cut", "focus: ui.cmd is set" );
//// ok( !ui.target || ui.target.text() === "AAA", "focus: ui.target is set" );
// },
// /* blur seems always to have ui.item === null. Also called twice in Safari? */
-// blur: function(event, ui){
+// blur: function(event, ui) {
// var t = ui.item ? $(ui.item).find("a:first").attr("href") : ui.item;
// log("blur(" + t + ")");
//// equal( ui.cmd, "cut", "blur: ui.cmd is set" );
//// equal( ui.target && ui.target.text(), "AAA", "blur: ui.target is set" );
// },
- select: function(event, ui){
+ select: function(event, ui) {
// window.console.log("select");
var t = ui.item ? $(ui.item).attr("data-command") : ui.item;
log("select(" + t + ")");
equal( ui.cmd, "cut", "select: ui.cmd is set" );
equal( ui.target.text(), "AAA", "select: ui.target is set" );
},
- open: function(event){
+ open: function(event) {
log("open");
- setTimeout(function(){
+ setTimeout(function() {
entryEvent($popup, 0, "mouseenter");
click($popup, 0);
}, 10);
},
- close: function(event){
+ close: function(event) {
log("close");
}
});
@@ -335,42 +325,39 @@ function _clickTest(menu){
$ctx.contextmenu("open", $("span.hasmenu:first"));
log("after open()");
- setTimeout(function(){
+ setTimeout(function() {
// TODO: why is focus() called twice?
- equal(logOutput(), "createMenu,create,open(),beforeOpen(AAA),after open(),open,select(cut),close",
- "Event sequence OK.");
+ equal(logOutput(),
+ "createMenu,create,open(),beforeOpen(AAA),after open(),open,select(cut),close",
+ "Event sequence OK.");
start();
}, 1000);
}
-
-asyncTest("Array menu", function(){
+asyncTest("Array menu", function() {
_clickTest(SAMPLE_MENU);
});
-
-asyncTest("UL menu", function(){
+asyncTest("UL menu", function() {
_clickTest("ul#sampleMenu");
});
-
// ****************************************************************************
-
module("'action' option", lifecycle);
-asyncTest("Array menu", function(){
+asyncTest("Array menu", function() {
var $ctx, $popup,
menu = [
- {title: "Cut", cmd: "cut", uiIcon: "ui-icon-scissors",
+ { title: "Cut", cmd: "cut", uiIcon: "ui-icon-scissors",
action: function(event, ui) {
log("cut action");
equal( ui.cmd, "cut", "action: ui.cmd is set" );
equal( ui.target.text(), "AAA", "action: ui.target is set" );
}
},
- {title: "Copy", cmd: "copy", uiIcon: "ui-icon-copy"},
- {title: "Paste", cmd: "paste", uiIcon: "ui-icon-clipboard", disabled: true }
+ { title: "Copy", cmd: "copy", uiIcon: "ui-icon-copy" },
+ { title: "Paste", cmd: "paste", uiIcon: "ui-icon-clipboard", disabled: true }
];
expect(5);
@@ -378,19 +365,19 @@ asyncTest("Array menu", function(){
$("#container").contextmenu({
delegate: ".hasmenu",
menu: menu,
- open: function(event){
+ open: function(event) {
log("open");
- setTimeout(function(){
+ setTimeout(function() {
click($popup, 0);
}, 10);
},
- select: function(event, ui){
+ select: function(event, ui) {
var t = ui.item ? $(ui.item).attr("data-command") : ui.item;
log("select(" + t + ")");
equal( ui.cmd, "cut", "select: ui.cmd is set" );
equal( ui.target.text(), "AAA", "select: ui.target is set" );
},
- close: function(event){
+ close: function(event) {
log("close");
}
});
@@ -402,12 +389,11 @@ asyncTest("Array menu", function(){
$ctx.contextmenu("open", $("span.hasmenu:first"));
log("after open()");
- setTimeout(function(){
+ setTimeout(function() {
equal(logOutput(), "open(),after open(),open,select(cut),cut action,close",
"Event sequence OK.");
start();
}, 500);
});
-
});
From 3bcf929e2a54db4c81442445b247cd2606b85062 Mon Sep 17 00:00:00 2001
From: a-sassermann
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
\ No newline at end of file
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b,c,d="onselectstart"in document.createElement("div");a.widget("moogle.contextmenu",{version:"@VERSION",options:{autoTrigger:!0,delegate:null,hide:{effect:"fadeOut",duration:"fast"},ignoreParentSelect:!0,menu:null,position:null,preventContextMenuForPopup:!1,preventSelect:!1,show:{effect:"slideDown",duration:"fast"},taphold:!1,uiMenuOptions:{},beforeOpen:a.noop,blur:a.noop,close:a.noop,create:a.noop,createMenu:a.noop,focus:a.noop,open:a.noop,select:a.noop},_create:function(){var b,c,e,f=this.options;if(this.$headStyle=null,this.$menu=null,this.menuIsTemp=!1,this.currentTarget=null,f.preventSelect){e=(a(this.element).is(document)?a("body"):this.element).uniqueId().attr("id"),b="#"+e+" "+f.delegate+" { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }",this.$headStyle=a("").prop("type","text/css").appendTo("head");try{this.$headStyle.html(b)}catch(g){this.$headStyle[0].styleSheet.cssText=b}d&&this.element.delegate(f.delegate,"selectstart"+this.eventNamespace,function(a){a.preventDefault()})}this._createUiMenu(f.menu),c="contextmenu"+this.eventNamespace,f.taphold&&(c+=" taphold"+this.eventNamespace),this.element.delegate(f.delegate,c,a.proxy(this._openMenu,this))},_destroy:function(){this.element.undelegate(this.eventNamespace),this._createUiMenu(null),this.$headStyle&&(this.$headStyle.remove(),this.$headStyle=null)},_createUiMenu:function(b){var c;this.isOpen()&&(c=this.currentTarget,this._closeMenu(!0),this.currentTarget=c),this.menuIsTemp?this.$menu.remove():this.$menu&&this.$menu.menu("destroy").hide(),this.$menu=null,this.menuIsTemp=!1,b&&(a.isArray(b)?(this.$menu=a.moogle.contextmenu.createMenuMarkup(b),this.menuIsTemp=!0):this.$menu="string"==typeof b?a(b):b,this.$menu.hide().menu(a.extend(!0,{},this.options.uiMenuOptions,{blur:a.proxy(this.options.blur,this),create:a.proxy(this.options.createMenu,this),focus:a.proxy(this.options.focus,this),select:a.proxy(function(b,c){var d,e=a.moogle.contextmenu.isMenu(c.item),f=c.item.data("actionHandler");c.cmd=c.item.attr("data-command"),c.target=a(this.currentTarget),e&&this.options.ignoreParentSelect||(d=this._trigger.call(this,"select",b,c),f&&(d=f.call(this,b,c)),d!==!1&&this._closeMenu.call(this),b.preventDefault())},this)})))},_openMenu:function(b){var c=this.options,d=c.position,e=this,f=!!b.isTrigger,g={menu:this.$menu,target:a(b.target),extraData:b.extraData,originalEvent:b};if(c.autoTrigger||f){if(this.currentTarget=b.target,b.preventDefault(),this._trigger("beforeOpen",b,g)===!1)return this.currentTarget=null,!1;g.menu=this.$menu,a(document).bind("keydown"+this.eventNamespace,function(b){b.which===a.ui.keyCode.ESCAPE&&e._closeMenu()}).bind("mousedown"+this.eventNamespace+" touchstart"+this.eventNamespace,function(b){a(b.target).closest(".ui-menu-item").length||e._closeMenu()}),a.isFunction(d)&&(d=d(b,g)),d=a.extend({my:"left top",at:"left bottom",of:void 0===b.pageX?b.target:b,collision:"fit"},d),this.$menu.show().css({position:"absolute",left:0,top:0}).position(d).hide(),c.preventContextMenuForPopup&&this.$menu.bind("contextmenu"+this.eventNamespace,function(a){a.preventDefault()}),this._show(this.$menu,this.options.show,function(){e._trigger.call(e,"open",b,g)})}},_closeMenu:function(b){var c=this,d=b?!1:this.options.hide;a(document).unbind("mousedown"+this.eventNamespace).unbind("touchstart"+this.eventNamespace).unbind("keydown"+this.eventNamespace),this.$menu.unbind("contextmenu"+this.eventNamespace),c.currentTarget=null,this._hide(this.$menu,d,function(){c._trigger("close")})},_setOption:function(b,c){switch(b){case"menu":this.replaceMenu(c)}a.Widget.prototype._setOption.apply(this,arguments)},_getMenuEntry:function(a){return this.$menu.find("li[data-command="+a+"]")},close:function(){this.isOpen()&&this._closeMenu()},enableEntry:function(a,b){this._getMenuEntry(a).toggleClass("ui-state-disabled",b===!1)},getMenu:function(){return this.$menu},isOpen:function(){return!!this.$menu&&!!this.currentTarget},open:function(a,b){b=b||{};var c=jQuery.Event("contextmenu",{target:a.get(0),extraData:b});return this.element.trigger(c)},replaceMenu:function(a){this._createUiMenu(a)},setEntry:function(b,c){var d=this._getMenuEntry(b);"string"==typeof c?a.moogle.contextmenu.updateTitle(d,c):(d.empty(),c.cmd=c.cmd||b,a.moogle.contextmenu.createEntryMarkup(c,d))},showEntry:function(a,b){this._getMenuEntry(a).toggle(b!==!1)}}),a.extend(a.moogle.contextmenu,{createMenuMarkup:function(b,c){var d,e,f,g;for(null==c&&(c=a("
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(c.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
From 8d472cea90b70f46ed19c9db0fdcfe6981239688 Mon Sep 17 00:00:00 2001
From: a-sassermann
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(c.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b,c,d="onselectstart"in document.createElement("div");a.widget("moogle.contextmenu",{version:"@VERSION",options:{autoTrigger:!0,delegate:null,hide:{effect:"fadeOut",duration:"fast"},ignoreParentSelect:!0,menu:null,position:null,preventContextMenuForPopup:!1,preventSelect:!1,show:{effect:"slideDown",duration:"fast"},taphold:!1,uiMenuOptions:{},beforeOpen:a.noop,blur:a.noop,close:a.noop,create:a.noop,createMenu:a.noop,focus:a.noop,open:a.noop,select:a.noop},_create:function(){var b,c,e,f=this.options;if(this.$headStyle=null,this.$menu=null,this.menuIsTemp=!1,this.currentTarget=null,f.preventSelect){e=(a(this.element).is(document)?a("body"):this.element).uniqueId().attr("id"),b="#"+e+" "+f.delegate+" { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }",this.$headStyle=a("").prop("type","text/css").appendTo("head");try{this.$headStyle.html(b)}catch(g){this.$headStyle[0].styleSheet.cssText=b}d&&this.element.delegate(f.delegate,"selectstart"+this.eventNamespace,function(a){a.preventDefault()})}this._createUiMenu(f.menu),c="contextmenu"+this.eventNamespace,f.taphold&&(c+=" taphold"+this.eventNamespace),this.element.delegate(f.delegate,c,a.proxy(this._openMenu,this))},_destroy:function(){this.element.undelegate(this.eventNamespace),this._createUiMenu(null),this.$headStyle&&(this.$headStyle.remove(),this.$headStyle=null)},_createUiMenu:function(b){var c;this.isOpen()&&(c=this.currentTarget,this._closeMenu(!0),this.currentTarget=c),this.menuIsTemp?this.$menu.remove():this.$menu&&this.$menu.menu("destroy").hide(),this.$menu=null,this.menuIsTemp=!1,b&&(a.isArray(b)?(this.$menu=a.moogle.contextmenu.createMenuMarkup(b),this.menuIsTemp=!0):this.$menu="string"==typeof b?a(b):b,this.$menu.hide().menu(a.extend(!0,{},this.options.uiMenuOptions,{blur:a.proxy(this.options.blur,this),create:a.proxy(this.options.createMenu,this),focus:a.proxy(this.options.focus,this),select:a.proxy(function(b,c){var d,e=a.moogle.contextmenu.isMenu(c.item),f=c.item.data("actionHandler");c.cmd=c.item.attr("data-command"),c.target=a(this.currentTarget),e&&this.options.ignoreParentSelect||(d=this._trigger.call(this,"select",b,c),f&&(d=f.call(this,b,c)),d!==!1&&this._closeMenu.call(this),b.preventDefault())},this)})))},_openMenu:function(b){var c=this.options,d=c.position,e=this,f=!!b.isTrigger,g={menu:this.$menu,target:a(b.target),extraData:b.extraData,originalEvent:b};if(c.autoTrigger||f){if(this.currentTarget=b.target,b.preventDefault(),this._trigger("beforeOpen",b,g)===!1)return this.currentTarget=null,!1;g.menu=this.$menu,a(document).bind("keydown"+this.eventNamespace,function(b){b.which===a.ui.keyCode.ESCAPE&&e._closeMenu()}).bind("mousedown"+this.eventNamespace+" touchstart"+this.eventNamespace,function(b){a(b.target).closest(".ui-menu-item").length||e._closeMenu()}),a.isFunction(d)&&(d=d(b,g)),d=a.extend({my:"left top",at:"left bottom",of:void 0===b.pageX?b.target:b,collision:"fit"},d),this.$menu.show().css({position:"absolute",left:0,top:0}).position(d).hide(),c.preventContextMenuForPopup&&this.$menu.bind("contextmenu"+this.eventNamespace,function(a){a.preventDefault()}),this._show(this.$menu,this.options.show,function(){e._trigger.call(e,"open",b,g)})}},_closeMenu:function(b){var c=this,d=b?!1:this.options.hide;a(document).unbind("mousedown"+this.eventNamespace).unbind("touchstart"+this.eventNamespace).unbind("keydown"+this.eventNamespace),this.$menu.unbind("contextmenu"+this.eventNamespace),c.currentTarget=null,this._hide(this.$menu,d,function(){c._trigger("close")})},_setOption:function(b,c){switch(b){case"menu":this.replaceMenu(c)}a.Widget.prototype._setOption.apply(this,arguments)},_getMenuEntry:function(a){return this.$menu.find("li[data-command="+a+"]")},close:function(){this.isOpen()&&this._closeMenu()},enableEntry:function(a,b){this._getMenuEntry(a).toggleClass("ui-state-disabled",b===!1)},getMenu:function(){return this.$menu},isOpen:function(){return!!this.$menu&&!!this.currentTarget},open:function(a,b){b=b||{};var c=jQuery.Event("contextmenu",{target:a.get(0),extraData:b});return this.element.trigger(c)},replaceMenu:function(a){this._createUiMenu(a)},setEntry:function(b,c){var d=this._getMenuEntry(b);"string"==typeof c?a.moogle.contextmenu.updateTitle(d,c):(d.empty(),c.cmd=c.cmd||b,a.moogle.contextmenu.createEntryMarkup(c,d))},showEntry:function(a,b){this._getMenuEntry(a).toggle(b!==!1)}}),a.extend(a.moogle.contextmenu,{createMenuMarkup:function(b,c){var d,e,f,g;for(null==c&&(c=a("
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
From e4f7964696000e9ee50553dee244875383af2fee Mon Sep 17 00:00:00 2001
From: a-sassermann
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b,c,d="onselectstart"in document.createElement("div");a.widget("moogle.contextmenu",{version:"@VERSION",options:{autoTrigger:!0,delegate:null,hide:{effect:"fadeOut",duration:"fast"},ignoreParentSelect:!0,menu:null,position:null,preventContextMenuForPopup:!1,preventSelect:!1,show:{effect:"slideDown",duration:"fast"},taphold:!1,uiMenuOptions:{},beforeOpen:a.noop,blur:a.noop,close:a.noop,create:a.noop,createMenu:a.noop,focus:a.noop,open:a.noop,select:a.noop},_create:function(){var b,c,e,f=this.options;if(this.$headStyle=null,this.$menu=null,this.menuIsTemp=!1,this.currentTarget=null,f.preventSelect){e=(a(this.element).is(document)?a("body"):this.element).uniqueId().attr("id"),b="#"+e+" "+f.delegate+" { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }",this.$headStyle=a("").prop("type","text/css").appendTo("head");try{this.$headStyle.html(b)}catch(g){this.$headStyle[0].styleSheet.cssText=b}d&&this.element.delegate(f.delegate,"selectstart"+this.eventNamespace,function(a){a.preventDefault()})}this._createUiMenu(f.menu),c="contextmenu"+this.eventNamespace,f.taphold&&(c+=" taphold"+this.eventNamespace),this.element.delegate(f.delegate,c,a.proxy(this._openMenu,this))},_destroy:function(){this.element.undelegate(this.eventNamespace),this._createUiMenu(null),this.$headStyle&&(this.$headStyle.remove(),this.$headStyle=null)},_createUiMenu:function(b){var c;this.isOpen()&&(c=this.currentTarget,this._closeMenu(!0),this.currentTarget=c),this.menuIsTemp?this.$menu.remove():this.$menu&&this.$menu.menu("destroy").hide(),this.$menu=null,this.menuIsTemp=!1,b&&(a.isArray(b)?(this.$menu=a.moogle.contextmenu.createMenuMarkup(b),this.menuIsTemp=!0):this.$menu="string"==typeof b?a(b):b,this.$menu.hide().menu(a.extend(!0,{},this.options.uiMenuOptions,{blur:a.proxy(this.options.blur,this),create:a.proxy(this.options.createMenu,this),focus:a.proxy(this.options.focus,this),select:a.proxy(function(b,c){var d,e=a.moogle.contextmenu.isMenu(c.item),f=c.item.data("actionHandler");c.cmd=c.item.attr("data-command"),c.target=a(this.currentTarget),e&&this.options.ignoreParentSelect||(d=this._trigger.call(this,"select",b,c),f&&(d=f.call(this,b,c)),d!==!1&&this._closeMenu.call(this),b.preventDefault())},this)})))},_openMenu:function(b){var c=this.options,d=c.position,e=this,f=!!b.isTrigger,g={menu:this.$menu,target:a(b.target),extraData:b.extraData,originalEvent:b};if(c.autoTrigger||f){if(this.currentTarget=b.target,b.preventDefault(),this._trigger("beforeOpen",b,g)===!1)return this.currentTarget=null,!1;g.menu=this.$menu,a(document).bind("keydown"+this.eventNamespace,function(b){b.which===a.ui.keyCode.ESCAPE&&e._closeMenu()}).bind("mousedown"+this.eventNamespace+" touchstart"+this.eventNamespace,function(b){a(b.target).closest(".ui-menu-item").length||e._closeMenu()}),a.isFunction(d)&&(d=d(b,g)),d=a.extend({my:"left top",at:"left bottom",of:void 0===b.pageX?b.target:b,collision:"fit"},d),this.$menu.show().css({position:"absolute",left:0,top:0}).position(d).hide(),c.preventContextMenuForPopup&&this.$menu.bind("contextmenu"+this.eventNamespace,function(a){a.preventDefault()}),this._show(this.$menu,this.options.show,function(){e._trigger.call(e,"open",b,g)})}},_closeMenu:function(b){var c=this,d=b?!1:this.options.hide;a(document).unbind("mousedown"+this.eventNamespace).unbind("touchstart"+this.eventNamespace).unbind("keydown"+this.eventNamespace),this.$menu.unbind("contextmenu"+this.eventNamespace),c.currentTarget=null,this._hide(this.$menu,d,function(){c._trigger("close")})},_setOption:function(b,c){switch(b){case"menu":this.replaceMenu(c)}a.Widget.prototype._setOption.apply(this,arguments)},_getMenuEntry:function(a){return this.$menu.find("li[data-command="+a+"]")},close:function(){this.isOpen()&&this._closeMenu()},enableEntry:function(a,b){this._getMenuEntry(a).toggleClass("ui-state-disabled",b===!1)},getMenu:function(){return this.$menu},isOpen:function(){return!!this.$menu&&!!this.currentTarget},open:function(a,b){b=b||{};var c=jQuery.Event("contextmenu",{target:a.get(0),extraData:b});return this.element.trigger(c)},replaceMenu:function(a){this._createUiMenu(a)},setEntry:function(b,c){var d=this._getMenuEntry(b);"string"==typeof c?a.moogle.contextmenu.updateTitle(d,c):(d.empty(),c.cmd=c.cmd||b,a.moogle.contextmenu.createEntryMarkup(c,d))},showEntry:function(a,b){this._getMenuEntry(a).toggle(b!==!1)}}),a.extend(a.moogle.contextmenu,{createMenuMarkup:function(b,c){var d,e,f,g;for(null==c&&(c=a("
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(c.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
From f5790883bf90a7216ecb0e33c49ab46e1496461b Mon Sep 17 00:00:00 2001
From: a-sassermann
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&d.data(c.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b,c,d="onselectstart"in document.createElement("div");a.widget("moogle.contextmenu",{version:"@VERSION",options:{autoTrigger:!0,delegate:null,hide:{effect:"fadeOut",duration:"fast"},ignoreParentSelect:!0,menu:null,position:null,preventContextMenuForPopup:!1,preventSelect:!1,show:{effect:"slideDown",duration:"fast"},taphold:!1,uiMenuOptions:{},beforeOpen:a.noop,blur:a.noop,close:a.noop,create:a.noop,createMenu:a.noop,focus:a.noop,open:a.noop,select:a.noop},_create:function(){var b,c,e,f=this.options;if(this.$headStyle=null,this.$menu=null,this.menuIsTemp=!1,this.currentTarget=null,f.preventSelect){e=(a(this.element).is(document)?a("body"):this.element).uniqueId().attr("id"),b="#"+e+" "+f.delegate+" { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }",this.$headStyle=a("").prop("type","text/css").appendTo("head");try{this.$headStyle.html(b)}catch(g){this.$headStyle[0].styleSheet.cssText=b}d&&this.element.delegate(f.delegate,"selectstart"+this.eventNamespace,function(a){a.preventDefault()})}this._createUiMenu(f.menu),c="contextmenu"+this.eventNamespace,f.taphold&&(c+=" taphold"+this.eventNamespace),this.element.delegate(f.delegate,c,a.proxy(this._openMenu,this))},_destroy:function(){this.element.undelegate(this.eventNamespace),this._createUiMenu(null),this.$headStyle&&(this.$headStyle.remove(),this.$headStyle=null)},_createUiMenu:function(b){var c;this.isOpen()&&(c=this.currentTarget,this._closeMenu(!0),this.currentTarget=c),this.menuIsTemp?this.$menu.remove():this.$menu&&this.$menu.menu("destroy").hide(),this.$menu=null,this.menuIsTemp=!1,b&&(a.isArray(b)?(this.$menu=a.moogle.contextmenu.createMenuMarkup(b),this.menuIsTemp=!0):this.$menu="string"==typeof b?a(b):b,this.$menu.hide().menu(a.extend(!0,{},this.options.uiMenuOptions,{blur:a.proxy(this.options.blur,this),create:a.proxy(this.options.createMenu,this),focus:a.proxy(this.options.focus,this),select:a.proxy(function(b,c){var d,e=a.moogle.contextmenu.isMenu(c.item),f=c.item.data("actionHandler");c.cmd=c.item.attr("data-command"),c.target=a(this.currentTarget),e&&this.options.ignoreParentSelect||(d=this._trigger.call(this,"select",b,c),f&&(d=f.call(this,b,c)),d!==!1&&this._closeMenu.call(this),b.preventDefault())},this)})))},_openMenu:function(b){var c=this.options,d=c.position,e=this,f=!!b.isTrigger,g={menu:this.$menu,target:a(b.target),extraData:b.extraData,originalEvent:b};if(c.autoTrigger||f){if(this.currentTarget=b.target,b.preventDefault(),this._trigger("beforeOpen",b,g)===!1)return this.currentTarget=null,!1;g.menu=this.$menu,a(document).bind("keydown"+this.eventNamespace,function(b){b.which===a.ui.keyCode.ESCAPE&&e._closeMenu()}).bind("mousedown"+this.eventNamespace+" touchstart"+this.eventNamespace,function(b){a(b.target).closest(".ui-menu-item").length||e._closeMenu()}),a.isFunction(d)&&(d=d(b,g)),d=a.extend({my:"left top",at:"left bottom",of:void 0===b.pageX?b.target:b,collision:"fit"},d),this.$menu.show().css({position:"absolute",left:0,top:0}).position(d).hide(),c.preventContextMenuForPopup&&this.$menu.bind("contextmenu"+this.eventNamespace,function(a){a.preventDefault()}),this._show(this.$menu,this.options.show,function(){e._trigger.call(e,"open",b,g)})}},_closeMenu:function(b){var c=this,d=b?!1:this.options.hide;a(document).unbind("mousedown"+this.eventNamespace).unbind("touchstart"+this.eventNamespace).unbind("keydown"+this.eventNamespace),this.$menu.unbind("contextmenu"+this.eventNamespace),c.currentTarget=null,this._hide(this.$menu,d,function(){c._trigger("close")})},_setOption:function(b,c){switch(b){case"menu":this.replaceMenu(c)}a.Widget.prototype._setOption.apply(this,arguments)},_getMenuEntry:function(a){return this.$menu.find("li[data-command="+a+"]")},close:function(){this.isOpen()&&this._closeMenu()},enableEntry:function(a,b){this._getMenuEntry(a).toggleClass("ui-state-disabled",b===!1)},getMenu:function(){return this.$menu},isOpen:function(){return!!this.$menu&&!!this.currentTarget},open:function(a,b){b=b||{};var c=jQuery.Event("contextmenu",{target:a.get(0),extraData:b});return this.element.trigger(c)},replaceMenu:function(a){this._createUiMenu(a)},setEntry:function(b,c){var d=this._getMenuEntry(b);"string"==typeof c?a.moogle.contextmenu.updateTitle(d,c):(d.empty(),c.cmd=c.cmd||b,a.moogle.contextmenu.createEntryMarkup(c,d))},showEntry:function(a,b){this._getMenuEntry(a).toggle(b!==!1)}}),a.extend(a.moogle.contextmenu,{createMenuMarkup:function(b,c){var d,e,f,g;for(null==c&&(c=a("
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
From da26cea54d5fbb5bfaf7375fb2dbe60231207ead Mon Sep 17 00:00:00 2001
From: "Martin@MBP"
").appendTo($entryLi);
+ $.moogle.contextmenu.createMenuMarkup(entry.children, $ul);
+ }
+ this.getMenu().menu("refresh");
}
},
/** Show or hide the menu command. */
@@ -341,7 +347,7 @@ $.extend($.moogle.contextmenu, {
}
return $parentUl;
},
- /** Replaces the value of elem's first text node child*/
+ /** Replaces the value of elem's first text node child */
replaceFirstTextNodeChild: function(elem, text) {
elem
.contents()
From 1ba0b9e4a2bc97592d79836978294575ab6e11e7 Mon Sep 17 00:00:00 2001
From: "Martin@MBP"
Triage jquery.ui-contextmenu.js
+
+
+
+
+
+
From 7f52a82b97f7e83cba9fa5940e36fc402370a643 Mon Sep 17 00:00:00 2001
From: "Martin@MBP" jquery.ui-contextmenu Test Suite for jQuery UI >= 1.11.0
+ jquery.ui-contextmenu Test Suite for older jQuery UI 1.10
@@ -27,14 +30,14 @@ Sample Markup
diff --git a/test/index.html b/test/index.html
index 24a6122..88d7822 100644
--- a/test/index.html
+++ b/test/index.html
@@ -1,20 +1,18 @@
+
jquery.ui-contextmenu Test Suite
+ jquery.ui-contextmenu Test Suite for jQuery UI 1.11+
@@ -30,14 +28,14 @@ Sample Markup
diff --git a/test/issue-80-async.html b/test/issue-80-async.html
index baf435d..d24ac69 100644
--- a/test/issue-80-async.html
+++ b/test/issue-80-async.html
@@ -109,7 +109,7 @@
// or return a promise to delay opening until an async response becomes
// available
ui.result = dfd.promise();
- console.log("beforeOpen", event, ui, event.originalEvent.type);
+ // console.log("beforeOpen", event, ui, event.originalEvent.type);
return;
},
focus: function(event, ui) {
diff --git a/test/tests.js b/test/tests.js
index ad6680d..d4434c8 100644
--- a/test/tests.js
+++ b/test/tests.js
@@ -16,6 +16,13 @@ function TestHelpers() {
uiVersion = {
major: parseInt(match[1], 10),
minor: parseInt(match[2], 10)
+ },
+ uiVersionBefore11 = ( uiVersion.major < 2 && uiVersion.minor < 11 ),
+ findEntry = function( menu, indexOrCommand ) {
+ if ( typeof indexOrCommand === "number" ) {
+ return menu.children( ":eq(" + indexOrCommand + ")" );
+ }
+ return menu.find("li[data-command=" + indexOrCommand + "]");
};
return {
@@ -37,22 +44,32 @@ function TestHelpers() {
},
entryEvent: function( menu, item, type ) {
lastItem = item;
- if ( uiVersion.major < 2 && uiVersion.minor < 11 ) {
- menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( type );
+ if ( uiVersionBefore11 ) {
+ findEntry(menu, item).find( "a:first" ).trigger( type );
} else {
- menu.children( ":eq(" + item + ")" ).trigger( type );
+ findEntry(menu, item).trigger( type );
}
},
click: function( menu, item ) {
lastItem = item;
- if ( uiVersion.major < 2 && uiVersion.minor < 11 ) {
- menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( "click" );
+ if ( uiVersionBefore11 ) {
+ findEntry(menu, item).find( "a:first" ).trigger( "click" );
} else {
- menu.children( ":eq(" + item + ")" ).trigger( "click" );
+ findEntry(menu, item).trigger( "click" );
}
},
- entry: function( menu, item ) {
- return menu.children( ":eq(" + item + ")" );
+ entry: findEntry,
+ entryTitle: function( menu, item ) {
+ // return the plain text (without sub-elements)
+ if ( uiVersionBefore11 ) {
+ return findEntry(menu, item).find( "a:first" ).contents().filter(function() {
+ return this.nodeType === 3;
+ })[0].nodeValue;
+ } else {
+ return findEntry(menu, item).contents().filter(function() {
+ return this.nodeType === 3;
+ })[0].nodeValue;
+ }
}
};
}
@@ -72,6 +89,7 @@ var th = new TestHelpers(),
logOutput = th.logOutput,
click = th.click,
entryEvent = th.entryEvent,
+ entryTitle = th.entryTitle,
entry = th.entry,
lifecycle = {
setup: function() {
@@ -394,6 +412,96 @@ asyncTest("Array menu", function() {
"Event sequence OK.");
start();
}, 500);
+});
+
+// ****************************************************************************
+
+module("'beforeOpen' event", lifecycle);
+
+asyncTest("modify on open", function() {
+ var $ctx, $popup,
+ menu = [
+ { title: "Cut", cmd: "cut", uiIcon: "ui-icon-scissors" },
+ { title: "Copy", cmd: "copy", uiIcon: "ui-icon-copy" },
+ { title: "Paste", cmd: "paste", uiIcon: "ui-icon-clipboard", disabled: true }
+ ];
+
+ expect(9);
+
+ $("#container").contextmenu({
+ delegate: ".hasmenu",
+ menu: menu,
+ beforeOpen: function(event, ui) {
+ log("beforeOpen");
+ $ctx
+ .contextmenu("setEntry", "cut", "Cut - changed")
+ .contextmenu("setEntry", "copy", { title: "Copy - changed", cmd: "copy2" })
+ .contextmenu("setEntry", "paste", {
+ title: "Paste - changed", cmd: "paste",
+ children: [
+ { title: "Sub 1", cmd: "sub_1" },
+ { title: "Sub 2", cmd: "sub_2", disabled: true }
+ ]
+ } );
+ },
+ open: function(event) {
+ log("open");
+ equal(entryTitle($popup, "cut"), "Cut - changed",
+ "setEntry(string)");
+ equal(entry($popup, "copy").length, 0,
+ "setEntry(object) change command id");
+ equal(entryTitle($popup, "copy2"), "Copy - changed",
+ "setEntry(object) set title");
+ equal(entryTitle($popup, "paste"), "Paste - changed",
+ "setEntry(object) set nested title");
+ equal(entryTitle($popup, "sub_1"), "Sub 1",
+ "setEntry(object) created nested entry");
+ ok(entry($popup, "sub_2").hasClass("ui-state-disabled"),
+ "setEntry(object) created nested disabled entry");
+ // ok( entry($popup, 2).hasClass("ui-state-disabled"),
+ // "open: Entry is disabled" );
+
+ // ok( $ctx.contextmenu("isOpen"),
+ // "isOpen() true in open event");
+
+ // ok( entry($popup, 0).is(":visible"),
+ // "beforeOpen: Entry 0 is visible" );
+ // ok( entry($popup, 0).hasClass("ui-state-disabled"),
+ // "beforeOpen: Entry 0 is disabled: enableEntry(false) worked" );
+
+ // ok( entry($popup, 1).is(":hidden"),
+ // "beforeOpen: Entry 1 is hidden: showEntry(false) worked" );
+ // ok( !entry($popup, 1).hasClass("ui-state-disabled"),
+ // "beforeOpen: Entry 1 is enabled" );
+
+ setTimeout(function() {
+ click($popup, "cut");
+ }, 10);
+ },
+ select: function(event, ui) {
+ var t = ui.item ? $(ui.item).attr("data-command") : ui.item;
+ log("select(" + t + ")");
+ equal( ui.cmd, "cut", "select: ui.cmd is set" );
+ equal( ui.target.text(), "AAA", "select: ui.target is set" );
+ },
+ close: function(event) {
+ log("close");
+ }
});
+ $ctx = $(":moogle-contextmenu");
+ $popup = $ctx.contextmenu("getMenu");
+
+ log("open()");
+ $ctx.contextmenu("open", $("span.hasmenu:first"));
+ log("after open()");
+
+ setTimeout(function() {
+ equal(logOutput(), "open(),beforeOpen,after open(),open,select(cut),close",
+ "Event sequence OK.");
+ start();
+ }, 500);
+
+});
+
});
diff --git a/test/tests2.js b/test/tests2.js
deleted file mode 100644
index 57d1b1e..0000000
--- a/test/tests2.js
+++ /dev/null
@@ -1,234 +0,0 @@
- // jQUnit defines:
- // asyncTest,deepEqual,equal,expect,module,notDeepEqual,notEqual,notStrictEqual,ok,QUnit,raises,start,stop,strictEqual,test
-
- /*globals asyncTest,equal,expect,module,ok,QUnit,start,test */
-
-/**
- * Tools inspired by https://github.com/jquery/jquery-ui/blob/master/tests/unit/menu/
- */
-function TestHelpers() {
-
- var lastItem = "",
- log = [],
- $ = jQuery;
-
- return {
- log: function( message, clear ) {
- if ( clear ) {
- log.length = 0;
- }
- if ( message === undefined ) {
- message = lastItem;
- }
-// window.console.log(message);
- log.push( $.trim( message ) );
- },
- logOutput: function() {
- return log.join( "," );
- },
- clearLog: function() {
- log.length = 0;
- },
- click: function( menu, item ) {
- lastItem = item;
- window.console.log("click: ", menu.children( ":eq(" + item + ")" ).find( "a:first" ).length);
- menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( "click" );
- },
- entry: function( menu, item ) {
- return menu.children( ":eq(" + item + ")" );
- }
- };
-}
-
-// ****************************************************************************
-
-jQuery(document).ready(function(){
-
-/*******************************************************************************
- * QUnit setup
- */
-QUnit.log(function(data) {
- if (window.console && window.console.log) {
-// window.console.log(data.result + " :: " + data.message);
- }
-});
-QUnit.config.requireExpects = true;
-
-var th = new TestHelpers(),
- log = th.log,
- logOutput = th.logOutput,
- click = th.click,
- entry = th.entry,
- lifecycle = {
- setup: function () {
- th.clearLog();
- // Always create a fresh copy of the menu definition
- $("#sampleMenuTemplate").clone().attr("id", "sampleMenu").appendTo("body");
- },
- teardown: function () {
- $(":moogle-contextmenu").contextmenu("destroy");
- $("#sampleMenu").remove();
- }
- },
- SAMPLE_MENU = [
- {title: "Cut", cmd: "cut", uiIcon: "ui-icon-scissors"},
- {title: "Copy", cmd: "copy", uiIcon: "ui-icon-copy"},
- {title: "Paste", cmd: "paste", uiIcon: "ui-icon-clipboard", disabled: true },
- {title: "----"},
- {title: "More", children: [
- {title: "Sub Item 1", cmd: "sub1"},
- {title: "Sub Item 2", cmd: "sub2"}
- ]}
- ],
- $ = jQuery;
-
-
-
-
-// ---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-
-module("open", lifecycle);
-
-function _openTest(menu){
- var $ctx, $popup;
-
- window.console.log("TEST 1 --------------------------------------");
-
- expect(11);
-
- $("#container").contextmenu({
- delegate: ".hasmenu",
- menu: menu,
- beforeOpen: function(event, ui){
- log("beforeOpen");
-
- equal( event.type, "contextmenubeforeopen",
- "beforeOpen: Got contextmenubeforeopen event" );
- equal( ui.target.text(), "AAA",
- "beforeOpen: ui.target is set" );
- ok( $popup.is(":hidden"), "beforeOpen: Menu is hidden" );
- ok( ! entry($popup, 0).hasClass("ui-state-disabled"),
- "beforeOpen: Entry 0 is enabled" );
- ok( entry($popup, 2).hasClass("ui-state-disabled"),
- "beforeOpen: Entry 2 is disabled" );
-
- $("#container").contextmenu("enableEntry", "cut", false);
-
- ok( entry($popup, 0).hasClass("ui-state-disabled"),
- "beforeOpen: Entry 0 is disabled" );
- },
- open: function(event){
- log("open");
-
- ok( $popup.is(":visible"), "open: Menu is visible" );
- ok( entry($popup, 2).hasClass("ui-state-disabled"), "open: Entry is disabled" );
- }
- });
-
- $ctx = $(":moogle-contextmenu");
- $popup = $ctx.contextmenu("getMenu");
-
- equal( $ctx.length, 1, "widget created");
- ok($popup.is(":hidden"), "Menu is hidden");
- log("open()");
- $ctx.contextmenu("open", $("span.hasmenu:first"));
- log("after open()");
- setTimeout(function(){
- equal(logOutput(), "open(),beforeOpen,after open(),open",
- "Event sequence OK.");
- window.console.log("TEST 1 END ----------------------------------");
- start();
- }, 500);
-}
-
-
-asyncTest("UL menu", function(){
- _openTest("ul#sampleMenu");
-});
-
-
-asyncTest("Array menu", function(){
- _openTest(SAMPLE_MENU);
-});
-
-
-//---------------------------------------------------------------------------
-
-module("click event sequence", lifecycle);
-
-function _clickTest(menu){
- var $ctx, $popup;
-
- window.console.log("TEST 2 --------------------------------------");
-
- expect(3);
-
- $("#container").contextmenu({
- delegate: ".hasmenu",
- menu: menu,
- beforeOpen: function(event, ui){
- log("beforeOpen(" + ui.target.text() + ")");
- },
- create: function(event, ui){
- log("create");
- },
- createMenu: function(event, ui){
- log("createMenu");
- },
-// focus: function(event, ui){
-// log("focus");
-// },
-// blur: function(event, ui){
-// log("blur");
-// },
- select: function(event, ui){
- window.console.log("select");
- var t = ui.item ? $(ui.item).find("a:first").attr("href") : ui.item;
- log("select(" + t + ")");
- equal( ui.cmd, "cut", "select: ui.cmd is set" );
- equal( ui.target.text(), "AAA", "select: ui.target is set" );
- },
- open: function(event){
- log("open");
- setTimeout(function(){
- var ctm = $ctx.data("moogle-contextmenu"),
- mnu = ctm.$menu.data("ui-menu");
- click($popup, 0);
- console.log($popup, $ctx);
- }, 10);
- },
- close: function(event){
- log("close");
- }
- });
-
- $ctx = $(":moogle-contextmenu");
- $popup = $ctx.contextmenu("getMenu");
-
- log("open()");
- $ctx.contextmenu("open", $("span.hasmenu:first"));
- log("after open()");
-
- setTimeout(function(){
- // TODO: why is focus() called twice?
- equal(logOutput(), "createMenu,create,open(),beforeOpen(AAA),after open(),open,select(#cut),close",
- "Event sequence OK.");
- window.console.log("TEST 2 END ----------------------------------");
- start();
- }, 500);
-}
-
-
-asyncTest("Array menu", function(){
- _clickTest(SAMPLE_MENU);
-});
-
-
-asyncTest("UL menu", function(){
- _clickTest("ul#sampleMenu");
-});
-
-
-});
From 1e593aee88382a0e1370ed0d0ce1ad80bf211b0a Mon Sep 17 00:00:00 2001
From: "Martin@MBP"
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
+/*! jQuery UI context menu plugin - v1.8.0 - 2014-11-23 | https://github.com/mar10/jquery-ui-contextmenu | Copyright (c) 2014 Martin Wendt; Licensed MIT */
+!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";var b,c,d="onselectstart"in document.createElement("div");a.widget("moogle.contextmenu",{version:"@VERSION",options:{autoTrigger:!0,delegate:null,hide:{effect:"fadeOut",duration:"fast"},ignoreParentSelect:!0,menu:null,position:null,preventContextMenuForPopup:!1,preventSelect:!1,show:{effect:"slideDown",duration:"fast"},taphold:!1,uiMenuOptions:{},beforeOpen:a.noop,blur:a.noop,close:a.noop,create:a.noop,createMenu:a.noop,focus:a.noop,open:a.noop,select:a.noop},_create:function(){var b,c,e,f=this.options;if(this.$headStyle=null,this.$menu=null,this.menuIsTemp=!1,this.currentTarget=null,f.preventSelect){e=(a(this.element).is(document)?a("body"):this.element).uniqueId().attr("id"),b="#"+e+" "+f.delegate+" { -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }",this.$headStyle=a("
").prop("type","text/css").appendTo("head");try{this.$headStyle.html(b)}catch(g){this.$headStyle[0].styleSheet.cssText=b}d&&this.element.delegate(f.delegate,"selectstart"+this.eventNamespace,function(a){a.preventDefault()})}this._createUiMenu(f.menu),c="contextmenu"+this.eventNamespace,f.taphold&&(c+=" taphold"+this.eventNamespace),this.element.delegate(f.delegate,c,a.proxy(this._openMenu,this))},_destroy:function(){this.element.undelegate(this.eventNamespace),this._createUiMenu(null),this.$headStyle&&(this.$headStyle.remove(),this.$headStyle=null)},_createUiMenu:function(b){var c;this.isOpen()&&(c=this.currentTarget,this._closeMenu(!0),this.currentTarget=c),this.menuIsTemp?this.$menu.remove():this.$menu&&this.$menu.menu("destroy").hide(),this.$menu=null,this.menuIsTemp=!1,b&&(a.isArray(b)?(this.$menu=a.moogle.contextmenu.createMenuMarkup(b),this.menuIsTemp=!0):this.$menu="string"==typeof b?a(b):b,this.$menu.hide().menu(a.extend(!0,{},this.options.uiMenuOptions,{blur:a.proxy(this.options.blur,this),create:a.proxy(this.options.createMenu,this),focus:a.proxy(this.options.focus,this),select:a.proxy(function(b,c){var d,e=a.moogle.contextmenu.isMenu(c.item),f=c.item.data("actionHandler");c.cmd=c.item.attr("data-command"),c.target=a(this.currentTarget),e&&this.options.ignoreParentSelect||(d=this._trigger.call(this,"select",b,c),f&&(d=f.call(this,b,c)),d!==!1&&this._closeMenu.call(this),b.preventDefault())},this)})))},_openMenu:function(b,c){var d,e,f=this.options,g=f.position,h=this,i=!!b.isTrigger,j={menu:this.$menu,target:a(b.target),extraData:b.extraData,originalEvent:b,result:null};if(f.autoTrigger||i){if(b.preventDefault(),this.currentTarget=b.target,!c){if(d=this._trigger("beforeOpen",b,j),e=j.result&&a.isFunction(j.result.promise)?j.result:null,j.result=null,d===!1)return this.currentTarget=null,!1;if(e)return e.done(function(){h._openMenu(b,!0)}),this.currentTarget=null,!1;j.menu=this.$menu}a(document).bind("keydown"+this.eventNamespace,function(b){b.which===a.ui.keyCode.ESCAPE&&h._closeMenu()}).bind("mousedown"+this.eventNamespace+" touchstart"+this.eventNamespace,function(b){a(b.target).closest(".ui-menu-item").length||h._closeMenu()}),a.isFunction(g)&&(g=g(b,j)),g=a.extend({my:"left top",at:"left bottom",of:void 0===b.pageX?b.target:b,collision:"fit"},g),this.$menu.show().css({position:"absolute",left:0,top:0}).position(g).hide(),f.preventContextMenuForPopup&&this.$menu.bind("contextmenu"+this.eventNamespace,function(a){a.preventDefault()}),this._show(this.$menu,this.options.show,function(){h._trigger.call(h,"open",b,j)})}},_closeMenu:function(b){var c=this,d=b?!1:this.options.hide;a(document).unbind("mousedown"+this.eventNamespace).unbind("touchstart"+this.eventNamespace).unbind("keydown"+this.eventNamespace),this.$menu.unbind("contextmenu"+this.eventNamespace),c.currentTarget=null,this._hide(this.$menu,d,function(){c._trigger("close")})},_setOption:function(b,c){switch(b){case"menu":this.replaceMenu(c)}a.Widget.prototype._setOption.apply(this,arguments)},_getMenuEntry:function(a){return this.$menu.find("li[data-command="+a+"]")},close:function(){this.isOpen()&&this._closeMenu()},enableEntry:function(a,b){this._getMenuEntry(a).toggleClass("ui-state-disabled",b===!1)},getMenu:function(){return this.$menu},isOpen:function(){return!!this.$menu&&!!this.currentTarget},open:function(a,b){b=b||{};var c=jQuery.Event("contextmenu",{target:a.get(0),extraData:b});return this.element.trigger(c)},replaceMenu:function(a){this._createUiMenu(a)},setEntry:function(b,c){var d,e=this._getMenuEntry(b);"string"==typeof c?a.moogle.contextmenu.updateTitle(e,c):(e.empty(),c.cmd=c.cmd||b,a.moogle.contextmenu.createEntryMarkup(c,e),a.isArray(c.children)&&(d=a("
").appendTo(e),a.moogle.contextmenu.createMenuMarkup(c.children,d)),this.getMenu().menu("refresh"))},showEntry:function(a,b){this._getMenuEntry(a).toggle(b!==!1)}}),a.extend(a.moogle.contextmenu,{createMenuMarkup:function(b,c){var d,e,f,g;for(null==c&&(c=a("
").appendTo("body")),d=0;d
").appendTo(g),a.moogle.contextmenu.createMenuMarkup(e.children,f));return c},replaceFirstTextNodeChild:function(a,b){a.contents().filter(function(){return 3===this.nodeType}).first().replaceWith(b)}}),b=a.ui.menu.version.match(/^(\d)\.(\d+)/),c={major:parseInt(b[1],10),minor:parseInt(b[2],10)},c.major<2&&c.minor<11?a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){var d=null;/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd),d=a("",{html:""+b.title,href:"#"}).appendTo(c),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&d.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.has(">a[aria-haspopup='true']").length>0},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(a("a",b),c)}}):a.extend(a.moogle.contextmenu,{createEntryMarkup:function(b,c){/[^\-\u2014\u2013\s]/.test(b.title)?(c.attr("data-command",b.cmd).html(""+b.title),a.isFunction(b.action)&&c.data("actionHandler",b.action),b.uiIcon&&c.append(a("").addClass(b.uiIcon)),b.disabled&&c.addClass("ui-state-disabled"),a.isPlainObject(b.data)&&c.data(b.data)):c.text(b.title)},isMenu:function(a){return a.is("[aria-haspopup='true']")},updateTitle:function(b,c){a.moogle.contextmenu.replaceFirstTextNodeChild(b,c)}})});
\ No newline at end of file
diff --git a/package.json b/package.json
index a61aba4..a39eda2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ui-contextmenu",
- "version": "1.7.1-0",
+ "version": "1.8.0",
"title": "jQuery UI context menu plugin",
"description": "Turn a jQuery UI Menu widget into a contextmenu.",
"keywords": [
@@ -52,4 +52,4 @@
"scripts": {
"test": "grunt ci --verbose"
}
-}
+}
\ No newline at end of file
diff --git a/test/issue-80-async.html b/test/issue-80-async.html
index d24ac69..7bee877 100644
--- a/test/issue-80-async.html
+++ b/test/issue-80-async.html
@@ -96,7 +96,7 @@
setTimeout(function(){
$(document)
.contextmenu("setEntry", "test", {
- title: "test dynamic", cmd: "test",
+ title: "test dynamic", cmd: "test",
children: [
{title: "dyn sub 1", cmd: "test_1"},
{title: "dyn sub 2", cmd: "test_2"}
diff --git a/ui-contextmenu.jquery.json b/ui-contextmenu.jquery.json
index ad1dcf2..4fc03c5 100644
--- a/ui-contextmenu.jquery.json
+++ b/ui-contextmenu.jquery.json
@@ -1,6 +1,6 @@
{
"name": "ui-contextmenu",
- "version": "1.7.1-0",
+ "version": "1.8.0",
"title": "jQuery UI context menu plugin",
"description": "Turn a jQuery UI Menu widget into a contextmenu.",
"keywords": [