/[drupal]/contributions/modules/outline_designer/jquery.contextmenu.js
ViewVC logotype

Contents of /contributions/modules/outline_designer/jquery.contextmenu.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Tue Feb 10 22:36:34 2009 UTC (9 months, 1 week ago) by btopro
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-RC1, DRUPAL-6--1-0-RC2, DRUPAL-6--1-0-RC3, HEAD
Changes since 1.1: +264 -0 lines
File MIME type: text/javascript
the new context menu pack!
1 /**
2 * Copyright (c)2005-2008 Matt Kruse (javascripttoolbox.com)
3 *
4 * Dual licensed under the MIT and GPL licenses.
5 * This basically means you can use this code however you want for
6 * free, but don't claim to have written it yourself!
7 * Donations always accepted: http://www.JavascriptToolbox.com/donate/
8 *
9 * Please do not link to the .js files on javascripttoolbox.com from
10 * your site. Copy the files locally to your server instead.
11 *
12 */
13 /**
14 * jquery.contextmenu.js
15 * jQuery Plugin for Context Menus
16 * http://www.JavascriptToolbox.com/lib/contextmenu/
17 *
18 * Copyright (c) 2008 Matt Kruse (javascripttoolbox.com)
19 * Dual licensed under the MIT and GPL licenses.
20 *
21 * @version 1.0
22 * @history 1.0 2008-10-20 Initial Release
23 * @todo slideUp doesn't work in IE - because of iframe?
24 * @todo Hide all other menus when contextmenu is shown?
25 * @todo More themes
26 * @todo Nested context menus
27 */
28 ;(function($){
29 $.contextMenu = {
30 shadow:true,
31 shadowOffset:0,
32 shadowOffsetX:5,
33 shadowOffsetY:5,
34 shadowWidthAdjust:-3,
35 shadowHeightAdjust:-3,
36 shadowOpacity:.2,
37 shadowClass:'context-menu-shadow',
38 shadowColor:'black',
39
40 offsetX:0,
41 offsetY:0,
42 appendTo:'body',
43 direction:'down',
44 constrainToScreen:true,
45
46 showTransition:'show',
47 hideTransition:'hide',
48 showSpeed:'',
49 hideSpeed:'',
50 showCallback:null,
51 hideCallback:null,
52
53 className:'context-menu',
54 itemClassName:'context-menu-item',
55 itemHoverClassName:'context-menu-item-hover',
56 disabledItemClassName:'context-menu-item-disabled',
57 disabledItemHoverClassName:'context-menu-item-disabled-hover',
58 separatorClassName:'context-menu-separator',
59 innerDivClassName:'context-menu-item-inner',
60 themePrefix:'context-menu-theme-',
61 theme:'default',
62
63 separator:'context-menu-separator', // A specific key to identify a separator
64 target:null, // The target of the context click, to be populated when triggered
65 menu:null, // The jQuery object containing the HTML object that is the menu itself
66 shadowObj:null, // Shadow object
67 bgiframe:null, // The iframe object for IE6
68 shown:false, // Currently being shown?
69 useIframe:/*@cc_on @*//*@if (@_win32) true, @else @*/false,/*@end @*/ // This is a better check than looking at userAgent!
70
71 // Create the menu instance
72 create: function(menu,opts) {
73 var cmenu = $.extend({},this,opts); // Clone all default properties to created object
74
75 // If a selector has been passed in, then use that as the menu
76 if (typeof menu=="string") {
77 cmenu.menu = $(menu);
78 }
79 // If a function has been passed in, call it each time the menu is shown to create the menu
80 else if (typeof menu=="function") {
81 cmenu.menuFunction = menu;
82 }
83 // Otherwise parse the Array passed in
84 else {
85 cmenu.menu = cmenu.createMenu(menu,cmenu);
86 }
87 if (cmenu.menu) {
88 cmenu.menu.css({display:'none'});
89 $(cmenu.appendTo).append(cmenu.menu);
90 }
91
92 // Create the shadow object if shadow is enabled
93 if (cmenu.shadow) {
94 cmenu.createShadow(cmenu); // Extracted to method for extensibility
95 if (cmenu.shadowOffset) { cmenu.shadowOffsetX = cmenu.shadowOffsetY = cmenu.shadowOffset; }
96 }
97 $('body').bind('click',function(){cmenu.hide();}); // If right-clicked somewhere else in the document, hide this menu
98 return cmenu;
99 },
100
101 // Create an iframe object to go behind the menu
102 createIframe: function() {
103 return $('<iframe frameborder="0" tabindex="-1" src="javascript:false" style="display:block;position:absolute;z-index:-1;filter:Alpha(Opacity=0);"/>');
104 },
105
106 // Accept an Array representing a menu structure and turn it into HTML
107 createMenu: function(menu,cmenu) {
108 var className = cmenu.className;
109 $.each(cmenu.theme.split(","),function(i,n){className+=' '+cmenu.themePrefix+n});
110 var $t = $('<table id="context_menu" cellspacing=0 cellpadding=0></table>').click(function(){cmenu.hide(); return false;}); // We wrap a table around it so width can be flexible
111 var $tr = $('<tr></tr>');
112 var $td = $('<td></td>');
113 var $div = $('<div class="'+className+'"></div>');
114
115 // Each menu item is specified as either:
116 // title:function
117 // or title: { property:value ... }
118 for (var i=0; i<menu.length; i++) {
119 var m = menu[i];
120 if (m==$.contextMenu.separator) {
121 $div.append(cmenu.createSeparator());
122 }
123 else {
124 for (var opt in menu[i]) {
125 $div.append(cmenu.createMenuItem(opt,menu[i][opt])); // Extracted to method for extensibility
126 }
127 }
128 }
129 if ( cmenu.useIframe ) {
130 $td.append(cmenu.createIframe());
131 }
132 $t.append($tr.append($td.append($div)))
133 return $t;
134 },
135
136 // Create an individual menu item
137 createMenuItem: function(label,obj) {
138 var cmenu = this;
139 if (typeof obj=="function") { obj={onclick:obj}; } // If passed a simple function, turn it into a property of an object
140 // Default properties, extended in case properties are passed
141 var o = $.extend({
142 onclick:function() { },
143 className:'',
144 hoverClassName:cmenu.itemHoverClassName,
145 icon:'',
146 disabled:false,
147 title:'',
148 hoverItem:cmenu.hoverItem,
149 hoverItemOut:cmenu.hoverItemOut
150 },obj);
151 // If an icon is specified, hard-code the background-image style. Themes that don't show images should take this into account in their CSS
152 var iconStyle = (o.icon)?'background-image:url('+o.icon+');':'';
153 var $div = $('<div class="'+cmenu.itemClassName+' '+o.className+((o.disabled)?' '+cmenu.disabledItemClassName:'')+'" title="'+o.title+'"></div>')
154 // If the item is disabled, don't do anything when it is clicked
155 .click(function(e){if(cmenu.isItemDisabled(this)){return false;}else{return o.onclick.call(cmenu.target,this,cmenu,e)}})
156 // Change the class of the item when hovered over
157 .hover( function(){ o.hoverItem.call(this,(cmenu.isItemDisabled(this))?cmenu.disabledItemHoverClassName:o.hoverClassName); }
158 ,function(){ o.hoverItemOut.call(this,(cmenu.isItemDisabled(this))?cmenu.disabledItemHoverClassName:o.hoverClassName); }
159 );
160 var $idiv = $('<div class="'+cmenu.innerDivClassName+'" style="'+iconStyle+'">'+label+'</div>');
161 $div.append($idiv);
162 return $div;
163 },
164
165 // Create a separator row
166 createSeparator: function() {
167 return $('<div class="'+this.separatorClassName+'"></div>');
168 },
169
170 // Determine if an individual item is currently disabled. This is called each time the item is hovered or clicked because the disabled status may change at any time
171 isItemDisabled: function(item) { return $(item).is('.'+this.disabledItemClassName); },
172
173 // Functions to fire on hover. Extracted to methods for extensibility
174 hoverItem: function(c) { $(this).addClass(c); },
175 hoverItemOut: function(c) { $(this).removeClass(c); },
176
177 // Create the shadow object
178 createShadow: function(cmenu) {
179 cmenu.shadowObj = $('<div class="'+cmenu.shadowClass+'"></div>').css( {display:'none',position:"absolute", zIndex:9998, opacity:cmenu.shadowOpacity, backgroundColor:cmenu.shadowColor } );
180 $(cmenu.appendTo).append(cmenu.shadowObj);
181 },
182
183 // Display the shadow object, given the position of the menu itself
184 showShadow: function(x,y,e) {
185 var cmenu = this;
186 if (cmenu.shadow) {
187 cmenu.shadowObj.css( {
188 width:(cmenu.menu.width()+cmenu.shadowWidthAdjust)+"px",
189 height:(cmenu.menu.height()+cmenu.shadowHeightAdjust)+"px",
190 top:(y+cmenu.shadowOffsetY)+"px",
191 left:(x+cmenu.shadowOffsetX)+"px"
192 }).addClass(cmenu.shadowClass)[cmenu.showTransition](cmenu.showSpeed);
193 }
194 },
195
196 // A hook to call before the menu is shown, in case special processing needs to be done.
197 // Return false to cancel the default show operation
198 beforeShow: function() { return true; },
199
200 // Show the context menu
201 show: function(t,e) {
202 var cmenu=this, x=e.pageX, y=e.pageY;
203 cmenu.target = t; // Preserve the object that triggered this context menu so menu item click methods can see it
204 if (cmenu.beforeShow()!==false) {
205 // If the menu content is a function, call it to populate the menu each time it is displayed
206 if (cmenu.menuFunction) {
207 if (cmenu.menu) { $(cmenu.menu).remove(); }
208 cmenu.menu = cmenu.createMenu(cmenu.menuFunction(cmenu,t),cmenu);
209 cmenu.menu.css({display:'none'});
210 $(cmenu.appendTo).append(cmenu.menu);
211 }
212 var $c = cmenu.menu;
213 x+=cmenu.offsetX; y+=cmenu.offsetY;
214 var pos = cmenu.getPosition(x,y,cmenu,e); // Extracted to method for extensibility
215 cmenu.showShadow(pos.x,pos.y,e);
216 // Resize the iframe if needed
217 if (cmenu.useIframe) {
218 $c.find('iframe').css({width:$c.width()+cmenu.shadowOffsetX+cmenu.shadowWidthAdjust,height:$c.height()+cmenu.shadowOffsetY+cmenu.shadowHeightAdjust});
219 }
220 $c.css( {top:pos.y+"px", left:pos.x+"px", position:"absolute",zIndex:9999} )[cmenu.showTransition](cmenu.showSpeed,((cmenu.showCallback)?function(){cmenu.showCallback.call(cmenu);}:null));
221 cmenu.shown=true;
222 $(document).one('click',null,function(){cmenu.hide()}); // Handle a single click to the document to hide the menu
223 }
224 },
225
226 // Find the position where the menu should appear, given an x,y of the click event
227 getPosition: function(clickX,clickY,cmenu,e) {
228 var x = clickX+cmenu.offsetX;
229 var y = clickY+cmenu.offsetY
230 var h = $(cmenu.menu).height();
231 var w = $(cmenu.menu).width();
232 var dir = cmenu.direction;
233 if (cmenu.constrainToScreen) {
234 var $w = $(window);
235 var wh = $w.height();
236 var ww = $w.width();
237 if (dir=="down" && (y+h-$w.scrollTop() > wh)) { dir = "up"; }
238 var maxRight = x+w-$w.scrollLeft();
239 if (maxRight > ww) { x -= (maxRight-ww); }
240 }
241 if (dir=="up") { y -= h; }
242 return {'x':x,'y':y};
243 },
244
245 // Hide the menu, of course
246 hide: function() {
247 var cmenu=this;
248 if (cmenu.shown) {
249 if (cmenu.iframe) { $(cmenu.iframe).hide(); }
250 if (cmenu.menu) { cmenu.menu[cmenu.hideTransition](cmenu.hideSpeed,((cmenu.hideCallback)?function(){cmenu.hideCallback.call(cmenu);}:null)); }
251 if (cmenu.shadow) { cmenu.shadowObj[cmenu.hideTransition](cmenu.hideSpeed); }
252 }
253 cmenu.shown = false;
254 }
255 };
256
257 // This actually adds the .contextMenu() function to the jQuery namespace
258 $.fn.contextMenu = function(menu,options) {
259 var cmenu = $.contextMenu.create(menu,options);
260 return this.each(function(){
261 $(this).bind('click',function(e){cmenu.show(this,e);return false;});
262 });
263 };
264 })(jQuery);

  ViewVC Help
Powered by ViewVC 1.1.2