Skip to content

Commit 8f3f32e

Browse files
committed
Differences between jQuery UI < 1.11 and jQuery UI >= 11 are handled.
1 parent 01a9369 commit 8f3f32e

6 files changed

+167
-60
lines changed

Gruntfile.coffee

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ module.exports = (grunt) ->
4040
jshintrc: ".jshintrc"
4141

4242
qunit:
43-
all: ["test/index.html"]
43+
all: ["test/index.html", "test/index-jquery-ui-1-11.html"]
4444

4545
"saucelabs-qunit":
4646
all:
4747
options:
48-
urls: ["http://localhost:9999/test/index.html"]
48+
urls: [
49+
"http://localhost:9999/test/index.html",
50+
"http://localhost:9999/test/index-jquery-ui-1-11.html"
51+
]
4952

5053
# username: process.env.SAUCE_USERNAME,
5154
# key: process.env.SAUCE_ACCESS_KEY,

jquery.ui-contextmenu.js

Lines changed: 103 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
*/
1010
;(function($, window, document, undefined) {
1111
"use strict";
12-
var supportSelectstart = "onselectstart" in document.createElement("div");
12+
var supportSelectstart = "onselectstart" in document.createElement("div"),
13+
match, uiVersion;
1314

1415
$.widget("moogle.contextmenu", {
1516
version: "1.4.0-1",
@@ -135,7 +136,7 @@
135136
select: $.proxy(function(event, ui){
136137
// User selected a menu entry
137138
var retval,
138-
isParent = (ui.item.has(">a[aria-haspopup='true']").length > 0),
139+
isParent = $.moogle.contextmenu.isMenu(ui.item),
139140
actionHandler = ui.item.data("actionHandler");
140141
ui.cmd = ui.item.attr("data-command");
141142
ui.target = $(this.currentTarget);
@@ -245,10 +246,9 @@
245246
}
246247
$.Widget.prototype._setOption.apply(this, arguments);
247248
},
248-
/** Return ui-menu entry (<A> or <LI> tag). */
249-
_getMenuEntry: function(cmd, wantLi){
250-
var $entry = this.$menu.find("li[data-command=" + cmd + "] a");
251-
return wantLi ? $entry.closest("li") : $entry;
249+
/** Return ui-menu entry (<LI> tag). */
250+
_getMenuEntry: function(cmd){
251+
return this.$menu.find("li[data-command=" + cmd + "]");
252252
},
253253
/** Close context menu. */
254254
close: function(){
@@ -258,7 +258,7 @@
258258
},
259259
/** Enable or disable the menu command. */
260260
enableEntry: function(cmd, flag){
261-
this._getMenuEntry(cmd, true).toggleClass("ui-state-disabled", (flag === false));
261+
this._getMenuEntry(cmd).toggleClass("ui-state-disabled", (flag === false));
262262
},
263263
/** Return Menu element (UL). */
264264
getMenu: function(){
@@ -284,67 +284,26 @@
284284
},
285285
/** Redefine menu entry (title or all of it). */
286286
setEntry: function(cmd, titleOrData){
287-
var $parent,
288-
$entry = this._getMenuEntry(cmd, false);
287+
var $entry = this._getMenuEntry(cmd);
289288

290289
if(typeof titleOrData === "string"){
291-
if( $entry.children("span").length){
292-
// Replace <a> text without removing <span> child
293-
$entry
294-
.contents()
295-
.filter(function(){ return this.nodeType === 3; })
296-
.first()
297-
.replaceWith(titleOrData);
298-
}else{
299-
// <a> tag only contains text (above code doesn't work here)
300-
$entry.text(titleOrData);
301-
}
290+
$.moogle.contextmenu.updateTitle($entry, titleOrData);
302291
}else{
303-
$parent = $entry.closest("li").empty();
292+
$entry.empty();
304293
titleOrData.cmd = titleOrData.cmd || cmd;
305-
$.moogle.contextmenu.createEntryMarkup(titleOrData, $parent);
294+
$.moogle.contextmenu.createEntryMarkup(titleOrData, $entry);
306295
}
307296
},
308297
/** Show or hide the menu command. */
309298
showEntry: function(cmd, flag){
310-
this._getMenuEntry(cmd, true).toggle(flag !== false);
299+
this._getMenuEntry(cmd).toggle(flag !== false);
311300
}
312301
});
313302

314303
/*
315304
* Global functions
316305
*/
317306
$.extend($.moogle.contextmenu, {
318-
/** Convert a menu description into a into a <li> content. */
319-
createEntryMarkup: function(entry, $parentLi){
320-
var $a = null;
321-
322-
// if(entry.title.match(/^---/)){
323-
if( !/[^\-\u2014\u2013\s]/.test( entry.title ) ){
324-
// hyphen, em dash, en dash: separator as defined by UI Menu 1.10
325-
$parentLi.text(entry.title);
326-
}else{
327-
$parentLi.attr("data-command", entry.cmd);
328-
$a = $("<a/>", {
329-
// text: "" + entry.title,
330-
html: "" + entry.title, // allow to pass HTML markup
331-
href: "#"
332-
}).appendTo($parentLi);
333-
if( $.isFunction(entry.action) ){
334-
$parentLi.data("actionHandler", entry.action);
335-
}
336-
if(entry.uiIcon){
337-
$a.append($("<span class='ui-icon' />").addClass(entry.uiIcon));
338-
}
339-
if(entry.disabled){
340-
$parentLi.addClass("ui-state-disabled");
341-
}
342-
if($.isPlainObject(entry.data)){
343-
$a.data(entry.data);
344-
}
345-
}
346-
return $a;
347-
},
348307
/** Convert a nested array of command objects into a <ul> structure. */
349308
createMenuMarkup: function(options, $parentUl){
350309
var i, menu, $ul, $li;
@@ -363,7 +322,98 @@ $.extend($.moogle.contextmenu, {
363322
}
364323
}
365324
return $parentUl;
325+
},
326+
/** Replaces the value of elem's first text node child*/
327+
replaceFirstTextNodeChild: function(elem, text) {
328+
elem
329+
.contents()
330+
.filter(function(){ return this.nodeType === 3; })
331+
.first()
332+
.replaceWith(text);
366333
}
367334
});
368335

336+
match = $.ui.menu.version.match(/^(\d)\.(\d+).*$/);
337+
338+
uiVersion = {
339+
major: parseInt(match[1], 10),
340+
minor: parseInt(match[2], 10)
341+
};
342+
343+
if ( uiVersion.major < 3 && uiVersion.minor < 11 ) {
344+
$.extend($.moogle.contextmenu, {
345+
/** Convert a menu description into a into a <li> content. */
346+
createEntryMarkup: function(entry, $parentLi){
347+
var $a = null;
348+
349+
// if(entry.title.match(/^---/)){
350+
if( !/[^\-\u2014\u2013\s]/.test( entry.title ) ){
351+
// hyphen, em dash, en dash: separator as defined by UI Menu 1.10
352+
$parentLi.text(entry.title);
353+
}else{
354+
$parentLi.attr("data-command", entry.cmd);
355+
$a = $("<a/>", {
356+
html: "" + entry.title, // allow to pass HTML markup
357+
href: "#"
358+
}).appendTo($parentLi);
359+
if( $.isFunction(entry.action) ){
360+
$parentLi.data("actionHandler", entry.action);
361+
}
362+
if(entry.uiIcon){
363+
$a.append($("<span class='ui-icon' />").addClass(entry.uiIcon));
364+
}
365+
if(entry.disabled){
366+
$parentLi.addClass("ui-state-disabled");
367+
}
368+
if($.isPlainObject(entry.data)){
369+
$a.data(entry.data);
370+
}
371+
}
372+
},
373+
/** Returns true if the menu item has child menu items */
374+
isMenu: function(item) {
375+
return item.has(">a[aria-haspopup='true']").length > 0;
376+
},
377+
/** Updates the menu item's title */
378+
updateTitle: function(item, title) {
379+
$.moogle.contextmenu.replaceFirstTextNodeChild($("a", item), title);
380+
}
381+
});
382+
} else {
383+
$.extend($.moogle.contextmenu, {
384+
/** Convert a menu description into a into a <li> content. */
385+
createEntryMarkup: function(entry, $parentLi){
386+
if( !/[^\-\u2014\u2013\s]/.test( entry.title ) ){
387+
$parentLi.text(entry.title);
388+
} else {
389+
$parentLi
390+
.attr("data-command", entry.cmd)
391+
.html("" + entry.title);
392+
if( $.isFunction(entry.action) ) {
393+
$parentLi.data("actionHandler", entry.action);
394+
}
395+
if( entry.uiIcon ) {
396+
$parentLi
397+
.append($("<span class='ui-icon' />")
398+
.addClass(entry.uiIcon));
399+
}
400+
if( entry.disabled ) {
401+
$parentLi.addClass("ui-state-disabled");
402+
}
403+
if( $.isPlainObject(entry.data) ) {
404+
$parentLi.data(entry.data);
405+
}
406+
}
407+
},
408+
/** Returns true if the menu item has child menu items */
409+
isMenu: function(item) {
410+
return item.is("[aria-haspopup='true']");
411+
},
412+
/** Updates the menu item's title */
413+
updateTitle: function(item, title) {
414+
$.moogle.contextmenu.replaceFirstTextNodeChild(item, title);
415+
}
416+
});
417+
}
418+
369419
}(jQuery, window, document));

test/index-jquery-ui-1-11.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>jquery.ui-contextmenu Test Suite</title>
6+
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.10.0.css">
7+
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
8+
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
9+
<script src="http://code.jquery.com/qunit/qunit-1.10.0.js"></script>
10+
<script src="../jquery.ui-contextmenu.js"></script>
11+
<script src="tests.js"></script>
12+
</head>
13+
<body>
14+
<h1 id="qunit-header">jquery.ui-contextmenu Test Suite for jQuery UI >= 1.11.0</h1>
15+
<h2 id="qunit-banner"></h2>
16+
<div id="qunit-testrunner-toolbar"></div>
17+
<h2 id="qunit-userAgent"></h2>
18+
<ol id="qunit-tests"></ol>
19+
<hr>
20+
<h3>Sample Markup</h3>
21+
<div id="container">
22+
<span class="hasmenu">AAA</span>
23+
<span class="hasmenu">BBB</span>
24+
<span class="hasmenu">CCC</span>
25+
</div>
26+
27+
<!-- This element will be copied as #sampleMenu for every test: -->
28+
29+
<ul id="sampleMenuTemplate" style="display: none;">
30+
<li data-command="cut"><span class="ui-icon ui-icon-scissors"></span>Cut
31+
<li data-command="copy"><span class="ui-icon ui-icon-copy"></span>Copy
32+
<li data-command="paste" class="ui-state-disabled ui-icon-clipboard">Paste
33+
<li>----
34+
<li>More
35+
<ul>
36+
<li data-command="sub1">Sub Item 1
37+
<li data-command="sub2">Sub Item 2
38+
</ul>
39+
</ul>
40+
</body>
41+
</html>

test/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="utf-8">
55
<title>jquery.ui-contextmenu Test Suite</title>
66
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.10.0.css">
7-
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
7+
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
88
<!--
99
<script src="jquery-ui.js"></script>
1010
-->

test/issue-33.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/start/jquery-ui.css" />
2-
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
2+
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
33
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
44
<script src="../jquery.ui-contextmenu.js"></script>
55

test/tests.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ function TestHelpers() {
1010

1111
var lastItem = "",
1212
log = [],
13-
$ = jQuery;
13+
$ = jQuery,
14+
match = $.ui.menu.version.match(/^(\d)\.(\d+).*$/),
15+
uiVersion = {
16+
major: parseInt(match[1], 10),
17+
minor: parseInt(match[2], 10)
18+
};
1419

1520
return {
1621
log: function( message, clear ) {
@@ -32,12 +37,20 @@ function TestHelpers() {
3237
entryEvent: function( menu, item, type ) {
3338
lastItem = item;
3439
// window.console.log(type + ": ", menu.children( ":eq(" + item + ")" ).find( "a:first" ).length);
35-
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( type );
40+
if ( uiVersion.major < 3 && uiVersion.minor < 11 ) {
41+
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( type );
42+
} else {
43+
menu.children( ":eq(" + item + ")" ).trigger( type );
44+
}
3645
},
3746
click: function( menu, item ) {
3847
lastItem = item;
3948
// window.console.log("clck: ", menu.children( ":eq(" + item + ")" ).find( "a:first" ).length);
40-
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( "click" );
49+
if ( uiVersion.major < 3 && uiVersion.minor < 11 ) {
50+
menu.children( ":eq(" + item + ")" ).find( "a:first" ).trigger( "click" );
51+
} else {
52+
menu.children( ":eq(" + item + ")" ).trigger( "click" );
53+
}
4154
},
4255
entry: function( menu, item ) {
4356
return menu.children( ":eq(" + item + ")" );

0 commit comments

Comments
 (0)