~ubuntu-branches/ubuntu/karmic/transmission/karmic-proposed

« back to all changes in this revision

Viewing changes to web/javascript/jquery/.svn/text-base/jquery.transmenu.js.svn-base

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Klimonda
  • Date: 2009-12-06 19:11:34 UTC
  • mfrom: (2.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20091206191134-t0ayk0mv6xuoyt0t
Tags: 1.75-0ubuntu2.1
* debian/patches/25_new_inhibition_api.diff:
  - Port Transmission to the new gnome-session inhibit API in order
    to make suspend/hibernate inhibiting work again on Karmic (LP: #457123)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* transMenu - v0.1.5 (2007-07-07)
 
2
 * Copyright (c) 2007 Roman Weich
 
3
 * http://p.sohei.org
 
4
 *
 
5
 */
 
6
 
 
7
(function($)
 
8
{
 
9
        var defaults = {
 
10
                onClick: function(){
 
11
                        $(this).find('>a').each(function(){
 
12
                                if ( this.href )
 
13
                                {
 
14
                                        window.location = this.href;
 
15
                                }
 
16
                        });
 
17
                },
 
18
                arrow_char: '►',
 
19
                selected_char: '✓',
 
20
                subDelay: 300,
 
21
                direction: 'down',
 
22
                mainDelay: 10
 
23
        };
 
24
        
 
25
        var transMenuSettings;
 
26
 
 
27
        $.fn.transMenu = function(options) 
 
28
        {
 
29
                var shown = false;
 
30
                var liOffset = 2;
 
31
 
 
32
                transMenuSettings = $.extend({}, defaults, options);
 
33
 
 
34
                var hideDIV = function(div, delay) {
 
35
                        //a timer running to show the div?
 
36
                        if ( div.timer && !div.isVisible ) {
 
37
                                clearTimeout(div.timer);
 
38
                        } else if (div.timer) {
 
39
                                return; //hide-timer already running
 
40
                        }
 
41
                        if ( div.isVisible ) {
 
42
                                div.timer = setTimeout( function() {
 
43
                                        //remove events
 
44
                                        $(div).find('ul li').unbind('mouseover', liHoverIn).unbind('mouseout', liHoverOut).unbind('click', transMenuSettings.onClick);
 
45
                                        $(div).hide();
 
46
                                        div.isVisible = false;
 
47
                                        div.timer = null;
 
48
                                }, delay);
 
49
                        }
 
50
                };
 
51
 
 
52
                var showDIV = function(div, delay) {
 
53
                        if ( div.timer ) {
 
54
                                clearTimeout(div.timer);
 
55
                        }
 
56
                        if ( !div.isVisible ) {
 
57
                                div.timer = setTimeout( function() {
 
58
                                        //check if the mouse is still over the parent item - if not dont show the submenu
 
59
                                        if (! $('div').parent().is('.hover')) {
 
60
                                                return;
 
61
                                        }
 
62
                                        //assign events to all div>ul>li-elements
 
63
                                        $(div).find('ul li').mouseover(liHoverIn).mouseout(liHoverOut).click(transMenuSettings.onClick);
 
64
                                        //positioning
 
65
                                        if (! $(div).parent().is('.main')) {
 
66
                                                $(div).css('left', $(div).parent().parent().width() - liOffset);
 
67
                                        }
 
68
                                        
 
69
                                        if (transMenuSettings.direction == 'up') {
 
70
                                                $(div).css('top', ($(div).height() * -1) + $(div).parent().parent().height());
 
71
                                        }
 
72
                                        
 
73
                                        div.isVisible = true; //we use this over :visible to speed up traversing
 
74
                                        $(div).show();
 
75
                                        div.timer = null;
 
76
                                }, delay);
 
77
                        }
 
78
                };
 
79
 
 
80
                //same as hover.handlehover in jquery - just can't use hover() directly - need the ability to unbind only the one hover event
 
81
                var testHandleHover = function(e) {
 
82
                        // Check if mouse(over|out) are still within the same parent element
 
83
                        var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
 
84
                        // Traverse up the tree
 
85
                        while ( p && p != this ) {
 
86
                                try { 
 
87
                                        p = p.parentNode;
 
88
                                } catch(e) { 
 
89
                                        p = this;
 
90
                                }
 
91
                        }
 
92
                        // If we actually just moused on to a sub-element, ignore it
 
93
                        if ( p == this ) {
 
94
                                return false;
 
95
                        }
 
96
                        return true;
 
97
                };
 
98
                
 
99
                var mainHoverIn = function(e) {
 
100
                        $(this).addClass('hover').siblings('li.hover').removeClass('hover');
 
101
                        if ( shown ) {
 
102
                                hoverIn(this, transMenuSettings.mainDelay);
 
103
                        }
 
104
                };
 
105
 
 
106
                var liHoverIn = function(e) {
 
107
                        if ( !testHandleHover(e) ) {
 
108
                                return false;
 
109
                        }
 
110
                        if ( e.target != this ) {
 
111
                                //look whether the target is a direct child of this (maybe an image)
 
112
                                if ( !isChild(this, e.target) ) {
 
113
                                        return;
 
114
                                }
 
115
                        }
 
116
                        hoverIn(this, transMenuSettings.subDelay);
 
117
                };
 
118
 
 
119
                var hoverIn = function(li, delay) {
 
120
                        //stop running timers from the other menus on the same level - a little faster than $('>*>div', li.parentNode)
 
121
                        var n = li.parentNode.firstChild;
 
122
                        for ( ; n; n = n.nextSibling ) {
 
123
                                if ( n.nodeType == 1 && n.nodeName.toUpperCase() == 'LI' ) {
 
124
                                        var div = getOneChild(n, 'DIV');
 
125
                                        //clear show-div timer
 
126
                                        if ( div && div.timer && !div.isVisible ) {
 
127
                                                clearTimeout(div.timer);
 
128
                                                div.timer = null;
 
129
                                        }
 
130
                                }
 
131
                        }
 
132
                        //is there a timer running to hide one of the parent divs? stop it
 
133
                        var pNode = li.parentNode;
 
134
                        for ( ; pNode; pNode = pNode.parentNode ) {
 
135
                                if ( pNode.nodeType == 1 && pNode.nodeName.toUpperCase() == 'DIV' ) {
 
136
                                        if (pNode.timer) {
 
137
                                                clearTimeout(pNode.timer);
 
138
                                                pNode.timer = null;
 
139
                                                $(pNode.parentNode).addClass('hover');
 
140
                                        }
 
141
                                }
 
142
                        }
 
143
                        //highlight the current element
 
144
                        $(li).addClass('hover');
 
145
                        var innerDiv = $(li).children('div');
 
146
                        innerDiv = innerDiv.length ? innerDiv[0] : null;
 
147
                        //is the submenu already visible?
 
148
                        if ( innerDiv && innerDiv.isVisible ) {
 
149
                                //hide-timer running?
 
150
                                if ( innerDiv.timer ) {
 
151
                                        clearTimeout(innerDiv.timer);
 
152
                                        innerDiv.timer = null;
 
153
                                } else {
 
154
                                        return;
 
155
                                }
 
156
                        }
 
157
                        //hide all open menus on the same level and below and unhighlight the li item (but not the current submenu!)
 
158
                        $(li.parentNode.getElementsByTagName('DIV')).each( function() {
 
159
                                if ( this != innerDiv && this.isVisible ) {
 
160
                                        hideDIV(this, delay);
 
161
                                        $(this.parentNode).removeClass('hover');
 
162
                                }
 
163
                        });
 
164
                        //show the submenu, if there is one
 
165
                        if ( innerDiv ) {
 
166
                                showDIV(innerDiv, delay);
 
167
                        }
 
168
                };
 
169
 
 
170
                var liHoverOut = function(e) {
 
171
                        if ( !testHandleHover(e) ) {
 
172
                                return false;
 
173
                        }
 
174
                        if ( e.target != this ) {
 
175
                                //return only if the target is no direct child of this
 
176
                                if ( !isChild(this, e.target) )  {
 
177
                                        return;
 
178
                                }
 
179
                        }
 
180
                        // Remove the hover from the submenu item, if the mouse is hovering out of the 
 
181
                        // menu (this is only for the last open (levelwise) (sub-)menu)
 
182
                        var div = getOneChild(this, 'DIV');
 
183
                        if ( !div ) {
 
184
                                $(this).removeClass('hover');
 
185
                        } else  {
 
186
                                if ( !div.isVisible ) {
 
187
                                        $(this).removeClass('hover');
 
188
                                }
 
189
                        }
 
190
                };
 
191
 
 
192
                var mainHoverOut = function(e) {
 
193
                        //no need to test e.target==this, as no child has the same event bound
 
194
                        var div = getOneChild(this, 'DIV');
 
195
                        var relTarget = e.relatedTarget || e.toElement; //this is undefined sometimes (e.g. when the mouse moves out of the window), so dont remove hover then
 
196
                        var p;
 
197
                        if ( !shown ) {
 
198
                                $(this).removeClass('hover');
 
199
                                
 
200
                        //menuitem has no submenu, so dont remove the hover if the mouse goes outside the menu  
 
201
                        } else if ( !div && relTarget ) {
 
202
                                p = $(e.target).parents('UL.trans_menu');
 
203
                                if ( p.contains(relTarget)) {
 
204
                                        $(this).removeClass('hover');
 
205
                                }
 
206
                        } else if ( relTarget ) {
 
207
                                //remove hover only when moving to anywhere inside the trans_menu
 
208
                                p = $(e.target).parents('UL.trans_menu');
 
209
                                if ( !div.isVisible && (p.contains(relTarget)) ) {
 
210
                                        $(this).removeClass('hover');
 
211
                                }
 
212
                        }
 
213
                };
 
214
 
 
215
                var mainClick = function() {
 
216
                        var div = getOneChild(this, 'DIV');
 
217
                        //clicked on an open main-menu-item
 
218
                        if ( div && div.isVisible ) {
 
219
                                clean();
 
220
                                $(this).addClass('hover');
 
221
                        } else {
 
222
                                hoverIn(this, transMenuSettings.mainDelay);
 
223
                                shown = true;
 
224
                                $('ul.trans_menu li').addClass('active');
 
225
                                $(document).bind('mousedown', checkMouse);
 
226
                        }
 
227
                };
 
228
 
 
229
                var checkMouse = function(e) {
 
230
                        //is the mouse inside a trans_menu? if yes, is it an open (the current) one?
 
231
                        var vis = false;
 
232
                        $(e.target).parents('UL.trans_menu').find('div').each( function(){
 
233
                                if ( this.isVisible ) {
 
234
                                        vis = true;
 
235
                                }
 
236
                        });
 
237
                        if ( !vis ) {
 
238
                                clean();
 
239
                        }
 
240
                };
 
241
 
 
242
                var clean = function() {
 
243
                        //remove timeout and hide the divs
 
244
                        $('ul.trans_menu div.outerbox').each(function(){
 
245
                                if ( this.timer ) {
 
246
                                        clearTimeout(this.timer);
 
247
                                        this.timer = null;
 
248
                                }
 
249
                                if ( this.isVisible ) {
 
250
                                        $(this).hide();
 
251
                                        this.isVisible = false;
 
252
                                }
 
253
                        });
 
254
                        $('ul.trans_menu li').removeClass('hover');
 
255
                        //remove events
 
256
                        $('ul.trans_menu>li li').unbind('mouseover', liHoverIn).unbind('mouseout', liHoverOut).unbind('click', transMenuSettings.onClick);
 
257
                        $(document).unbind('mousedown', checkMouse);
 
258
                        shown = false;
 
259
                        $('ul.trans_menu li').removeClass('active');
 
260
                };
 
261
 
 
262
                var getOneChild = function(elem, name) {
 
263
                        if ( !elem ) {
 
264
                                return null;
 
265
                        }
 
266
                        var n = elem.firstChild;
 
267
                        for ( ; n; n = n.nextSibling )  {
 
268
                                if ( n.nodeType == 1 && n.nodeName.toUpperCase() == name ) {
 
269
                                        return n;
 
270
                                }
 
271
                        }
 
272
                        return null;
 
273
                };
 
274
                
 
275
                var isChild = function(elem, childElem) {
 
276
                        var n = elem.firstChild;
 
277
                        for ( ; n; n = n.nextSibling ) {
 
278
                                if ( n == childElem ) {
 
279
                                        return true;
 
280
                                }
 
281
                        }
 
282
                        return false;
 
283
                };
 
284
 
 
285
            return this.each(function() {
 
286
                        //add .contains() to mozilla - http://www.quirksmode.org/blog/archives/2006/01/contains_for_mo.html
 
287
                        if (window.Node && Node.prototype && !Node.prototype.contains) {
 
288
                                Node.prototype.contains = function(arg)  {
 
289
                                        return !!(this.compareDocumentPosition(arg) & 16);
 
290
                                };
 
291
                        }
 
292
                        if (! $(this).is('.trans_menu')) {
 
293
                                $(this).addClass('trans_menu');
 
294
                        }
 
295
                        //add shadows
 
296
                        $('ul', this).shadowBox();
 
297
                        
 
298
                        //assign events
 
299
                        $(this).bind('closemenu', function(){clean();}); //assign closemenu-event, through wich the menu can be closed from outside the plugin
 
300
                        //add click event handling, if there are any elements inside the main menu
 
301
                        var liElems = $(this).children('li');
 
302
                        for ( var j = 0; j < liElems.length; j++ ) {
 
303
                                if ( getOneChild(getOneChild(getOneChild(liElems[j], 'DIV'), 'UL'), 'LI') ) {
 
304
                                        $(liElems[j]).click(mainClick);
 
305
                                }
 
306
                        }
 
307
                        //add hover event handling and assign classes
 
308
                        $(liElems).hover(mainHoverIn, mainHoverOut).addClass('main').find('>div').addClass('inner');
 
309
                        //add the little arrow before each submenu
 
310
                        if ( transMenuSettings.arrow_char ) {
 
311
                                var arrow_markup = $("<span class='arrow'>" + transMenuSettings.arrow_char + '</span>');
 
312
                                // Mozilla float/position hack
 
313
                                if ($.browser.mozilla && +$.browser.version.replace(/\./g,'').slice(0,3) < 191) {
 
314
                                        arrow_markup.css('margin-top', '-13px');
 
315
                                }
 
316
                                $('div.inner div.outerbox', this).before(arrow_markup);
 
317
                        }
 
318
 
 
319
                        //the floating list elements are destroying the layout..so make it nice again..
 
320
                        $(this).wrap('<div class="main_container"></div>').after('<div style="clear: both; visibility: hidden;"></div>');
 
321
            });
 
322
        };
 
323
        
 
324
        $.fn.transMenu.setDefaults = function(o) {
 
325
                $.extend(defaults, o);
 
326
        };
 
327
 
 
328
        $.fn.shadowBox = function() {
 
329
            return this.each(function() {
 
330
                        var outer = $('<div class="outerbox"></div>').get(0);
 
331
                        if ( $(this).css('position') == 'absolute' ) {
 
332
                                //if the child(this) is positioned abolute, we have to use relative positioning and shrink the outerbox accordingly to the innerbox
 
333
                                $(outer).css({position:'relative', width:this.offsetWidth, height:this.offsetHeight});
 
334
                        } else {
 
335
                                //shrink the outerbox
 
336
                                $(outer).css('position', 'absolute');
 
337
                        }
 
338
                        //add the boxes
 
339
                        $(this).addClass('innerBox').wrap(outer).
 
340
                                        before('<div class="shadowbox1"></div><div class="shadowbox2"></div><div class="shadowbox3"></div>');
 
341
            });
 
342
        };
 
343
        
 
344
        $.fn.selectMenuItem = function() {
 
345
                if (this.find('span.selected').length == 0) {
 
346
                        this.prepend($("<span class='selected'>" + transMenuSettings.selected_char + "</span>"));
 
347
                }
 
348
            return this;
 
349
        };
 
350
        
 
351
        $.fn.deselectMenuItem = function() {
 
352
                return this.find('span.selected').remove();
 
353
        };
 
354
        
 
355
        $.fn.menuItemIsSelected = function() {
 
356
                return (this.find('span.selected').length > 0);
 
357
        };
 
358
        
 
359
        $.fn.deselectMenuSiblings = function() {
 
360
                this.parent().find('span.selected').remove();
 
361
            this.selectMenuItem();
 
362
                return this; 
 
363
        };
 
364
})(jQuery);