Projet

Général

Profil

Paste
Télécharger (12,4 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / adminimal_admin_menu / js / slicknav / jquery-no-conflict.slicknav.js @ 651307cd

1
/*!
2
        SlickNav Responsive Mobile Menu
3
        (c) 2014 Josh Cope
4
        licensed under MIT
5
*/
6
;(function ($, document, window) {
7
        var
8
        // default settings object.
9
        defaults = {
10
                label: 'MENU',
11
                duplicate: true,
12
                duration: 200,
13
                easingOpen: 'swing',
14
                easingClose: 'swing',
15
                closedSymbol: '►',
16
                openedSymbol: '▼',
17
                prependTo: 'body',
18
                parentTag: 'a',
19
                closeOnClick: false,
20
                allowParentLinks: false,
21
                init: function(){},
22
                open: function(){},
23
                close: function(){}
24
        },
25
        mobileMenu = 'slicknav',
26
        prefix = 'slicknav';
27
        
28
        function Plugin( element, options ) {
29
                this.element = element;
30

    
31
        // jQuery has an extend method which merges the contents of two or
32
        // more objects, storing the result in the first object. The first object
33
        // is generally empty as we don't want to alter the default options for
34
        // future instances of the plugin
35
        this.settings = $.extend( {}, defaults, options) ;
36
        
37
        this._defaults = defaults;
38
        this._name = mobileMenu;
39
        
40
        this.init();
41
        }
42
        
43
        Plugin.prototype.init = function () {
44
        var $this = this;
45
                var menu = $(this.element);
46
                var settings = this.settings;
47
                
48
                // clone menu if needed
49
                if (settings.duplicate) {
50
                        $this.mobileNav = menu.clone();
51
                        //remove ids from clone to prevent css issues
52
                        $this.mobileNav.removeAttr('id');
53
                        $this.mobileNav.find('*').each(function(i,e){
54
                                $(e).removeAttr('id');
55
                        });
56
                }
57
                else
58
                        $this.mobileNav = menu;
59
                
60
                // styling class for the button
61
                var iconClass = prefix+'_icon';
62
                
63
                if (settings.label == '') {
64
                        iconClass += ' '+prefix+'_no-text';
65
                }
66
                
67
                if (settings.parentTag == 'a') {
68
                        settings.parentTag = 'a href="#"';
69
                }
70
                
71
                // create menu bar
72
                $this.mobileNav.attr('class', prefix+'_nav');
73
                var menuBar = $('<div class="'+prefix+'_menu"></div>');
74
                $this.btn = $('<'+settings.parentTag+' aria-haspopup="true" tabindex="0" class="'+prefix+'_btn '+prefix+'_collapsed"><span class="'+prefix+'_menutxt">'+settings.label+'</span><span class="'+iconClass+'"><span class="'+prefix+'_icon-bar"></span><span class="'+prefix+'_icon-bar"></span><span class="'+prefix+'_icon-bar"></span></span></a>');
75
                $(menuBar).append($this.btn);                
76
                $(settings.prependTo).prepend(menuBar);
77
                menuBar.append($this.mobileNav);
78
                
79
                // iterate over structure adding additional structure
80
                var items = $this.mobileNav.find('li');
81
                $(items).each(function () {
82
                        var item = $(this);
83
                        data = {};
84
                        data.children = item.children('ul').attr('role','menu');
85
                        item.data("menu", data);
86
                        
87
                        // if a list item has a nested menu
88
                        if (data.children.length > 0) {
89
                        
90
                                // select all text before the child menu
91
                                var a = item.contents();
92
                                var nodes = [];
93
                                $(a).each(function(){
94
                                        if(!$(this).is("ul")) {
95
                                                nodes.push(this);
96
                                        }
97
                                        else {
98
                                                return false;
99
                                        }
100
                                });
101
                                
102
                                // wrap item text with tag and add classes
103
                                var wrap = $(nodes).wrapAll('<'+settings.parentTag+' role="menuitem" aria-haspopup="true" tabindex="-1" class="'+prefix+'_item"/>').parent();
104
                                
105
                                item.addClass(prefix+'_collapsed');
106
                                item.addClass(prefix+'_parent');
107
                                
108
                                // create parent arrow
109
                                $(nodes).last().after('<span class="'+prefix+'_arrow">'+settings.closedSymbol+'</span>');
110
                                
111
                        
112
                        } else if ( item.children().length == 0) {
113
                                 item.addClass(prefix+'_txtnode');
114
                        }
115
                        
116
                        // accessibility for links
117
                        item.children('a').attr('role', 'menuitem').click(function(){
118
                                //Emulate menu close if set
119
                                if (settings.closeOnClick)
120
                                        $($this.btn).click();
121
                        });
122
                });
123
                
124
                // structure is in place, now hide appropriate items
125
                $(items).each(function () {
126
                        var data = $(this).data("menu");
127
                        $this._visibilityToggle(data.children, false, null, true);
128
                });
129
                
130
                // finally toggle entire menu
131
                $this._visibilityToggle($this.mobileNav, false, 'init', true);
132
                
133
                // accessibility for menu button
134
                $this.mobileNav.attr('role','menu');
135
                
136
                // outline prevention when using mouse
137
                $(document).mousedown(function(){
138
                        $this._outlines(false);
139
                });
140
                
141
                $(document).keyup(function(){
142
                        $this._outlines(true);
143
                });
144
                
145
                // menu button click
146
                $($this.btn).click(function (e) {
147
                        e.preventDefault();
148
                        $this._menuToggle();                        
149
                });
150
                
151
                // click on menu parent
152
                $this.mobileNav.on('click', '.'+prefix+'_item', function(e){
153
                        e.preventDefault();
154
                        $this._itemClick($(this));
155
                });
156
                
157
                // check for enter key on menu button and menu parents
158
                $($this.btn).keydown(function (e) {
159
                        var ev = e || event;
160
                        if(ev.keyCode == 13) {
161
                                e.preventDefault();
162
                                $this._menuToggle();
163
                        }
164
                });
165
                
166
                $this.mobileNav.on('keydown', '.'+prefix+'_item', function(e) {
167
                        var ev = e || event;
168
                        if(ev.keyCode == 13) {
169
                                e.preventDefault();
170
                                $this._itemClick($(e.target));
171
                        }
172
                });
173
                
174
                // allow links clickable within parent tags if set
175
                if (settings.allowParentLinks) {
176
                        $('.'+prefix+'_item a').click(function(e){
177
                                        e.stopImmediatePropagation();
178
                        });
179
                }
180
    };
181
        
182
        //toggle menu
183
        Plugin.prototype._menuToggle = function(el){
184
                var $this = this;
185
                var btn = $this.btn;
186
                var mobileNav = $this.mobileNav;
187
                
188
                if (btn.hasClass(prefix+'_collapsed')) {
189
                        btn.removeClass(prefix+'_collapsed');
190
                        btn.addClass(prefix+'_open');
191
                } else {
192
                        btn.removeClass(prefix+'_open');
193
                        btn.addClass(prefix+'_collapsed');
194
                }
195
                btn.addClass(prefix+'_animating');
196
                $this._visibilityToggle(mobileNav, true, btn);
197
        }
198
        
199
        // toggle clicked items
200
        Plugin.prototype._itemClick = function(el) {
201
                var $this = this;
202
                var settings = $this.settings;
203
                var data = el.data("menu");
204
                if (!data) {
205
                        data = {};
206
                        data.arrow = el.children('.'+prefix+'_arrow');
207
                        data.ul = el.next('ul');
208
                        data.parent = el.parent();
209
                        el.data("menu", data);
210
                }
211
                if (data.parent.hasClass(prefix+'_collapsed')) {
212
                        data.arrow.html(settings.openedSymbol);
213
                        data.parent.removeClass(prefix+'_collapsed');
214
                        data.parent.addClass(prefix+'_open');
215
                        data.parent.addClass(prefix+'_animating');
216
                        $this._visibilityToggle(data.ul, true, el);
217
                } else {
218
                        data.arrow.html(settings.closedSymbol);
219
                        data.parent.addClass(prefix+'_collapsed');
220
                        data.parent.removeClass(prefix+'_open');
221
                        data.parent.addClass(prefix+'_animating');
222
                        $this._visibilityToggle(data.ul, true, el);
223
                }
224
        }
225

    
226
        // toggle actual visibility and accessibility tags
227
        Plugin.prototype._visibilityToggle = function(el, animate, trigger, init) {
228
                var $this = this;
229
                var settings = $this.settings;
230
                var items = $this._getActionItems(el);
231
                var duration = 0;
232
                if (animate)
233
                        duration = settings.duration;
234
                
235
                if (el.hasClass(prefix+'_hidden')) {
236
                        el.removeClass(prefix+'_hidden');
237
                        el.slideDown(duration, settings.easingOpen, function(){
238
                                
239
                                $(trigger).removeClass(prefix+'_animating');
240
                                $(trigger).parent().removeClass(prefix+'_animating');
241
                                
242
                                //Fire open callback
243
                                if (!init) {
244
                                        settings.open(trigger);
245
                                }
246
                        });
247
                        el.attr('aria-hidden','false');
248
                        items.attr('tabindex', '0');
249
                        $this._setVisAttr(el, false);
250
                } else {
251
                        el.addClass(prefix+'_hidden');
252
                        el.slideUp(duration, this.settings.easingClose, function() {
253
                                el.attr('aria-hidden','true');
254
                                items.attr('tabindex', '-1');
255
                                $this._setVisAttr(el, true);
256
                                el.hide(); //jQuery 1.7 bug fix
257
                                
258
                                $(trigger).removeClass(prefix+'_animating');
259
                                $(trigger).parent().removeClass(prefix+'_animating');
260
                                
261
                                //Fire init or close callback
262
                                if (!init)
263
                                        settings.close(trigger);
264
                                else if (trigger == 'init')
265
                                        settings.init();
266
                        });
267
                }
268
        }
269

    
270
        // set attributes of element and children based on visibility
271
        Plugin.prototype._setVisAttr = function(el, hidden) {
272
                var $this = this;
273
                
274
                // select all parents that aren't hidden
275
                var nonHidden = el.children('li').children('ul').not('.'+prefix+'_hidden');
276
                
277
                // iterate over all items setting appropriate tags
278
                if (!hidden) {
279
                        nonHidden.each(function(){
280
                                var ul = $(this);
281
                                ul.attr('aria-hidden','false');
282
                                var items = $this._getActionItems(ul);
283
                                items.attr('tabindex', '0');
284
                                $this._setVisAttr(ul, hidden);
285
                        });
286
                } else {
287
                        nonHidden.each(function(){
288
                                var ul = $(this);
289
                                ul.attr('aria-hidden','true');
290
                                var items = $this._getActionItems(ul);
291
                                items.attr('tabindex', '-1');
292
                                $this._setVisAttr(ul, hidden);
293
                        });
294
                }
295
        }
296

    
297
        // get all 1st level items that are clickable
298
        Plugin.prototype._getActionItems = function(el) {
299
                var data = el.data("menu");
300
                if (!data) {
301
                        data = {};
302
                        var items = el.children('li');
303
                        var anchors = items.children('a');
304
                        data.links = anchors.add(items.children('.'+prefix+'_item'));
305
                        el.data("menu", data);
306
                }
307
                return data.links;
308
        }
309

    
310
        Plugin.prototype._outlines = function(state) {
311
                if (!state) {
312
                        $('.'+prefix+'_item, .'+prefix+'_btn').css('outline','none');
313
                } else {
314
                        $('.'+prefix+'_item, .'+prefix+'_btn').css('outline','');
315
                }
316
        }
317
        
318
        Plugin.prototype.toggle = function(){
319
                $this._menuToggle();
320
        }
321
        
322
        Plugin.prototype.open = function(){
323
                $this = this;
324
                if ($this.btn.hasClass(prefix+'_collapsed')) {
325
                        $this._menuToggle();
326
                }
327
        }
328
        
329
        Plugin.prototype.close = function(){
330
                $this = this;
331
                if ($this.btn.hasClass(prefix+'_open')) {
332
                        $this._menuToggle();
333
                }
334
        }
335
        
336
        $.fn[mobileMenu] = function ( options ) {
337
                var args = arguments;
338

    
339
                // Is the first parameter an object (options), or was omitted, instantiate a new instance
340
                if (options === undefined || typeof options === 'object') {
341
                        return this.each(function () {
342

    
343
                                // Only allow the plugin to be instantiated once due to methods
344
                                if (!$.data(this, 'plugin_' + mobileMenu)) {
345

    
346
                                        // if it has no instance, create a new one, pass options to our plugin constructor,
347
                                        // and store the plugin instance in the elements jQuery data object.
348
                                        $.data(this, 'plugin_' + mobileMenu, new Plugin( this, options ));
349
                                }
350
                        });
351

    
352
                // If is a string and doesn't start with an underscore or 'init' function, treat this as a call to a public method.
353
                } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
354

    
355
                        // Cache the method call to make it possible to return a value
356
                        var returns;
357

    
358
                        this.each(function () {
359
                                var instance = $.data(this, 'plugin_' + mobileMenu);
360

    
361
                                // Tests that there's already a plugin-instance and checks that the requested public method exists
362
                                if (instance instanceof Plugin && typeof instance[options] === 'function') {
363

    
364
                                        // Call the method of our plugin instance, and pass it the supplied arguments.
365
                                        returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
366
                                }
367
                        });
368

    
369
                        // If the earlier cached method gives a value back return the value, otherwise return this to preserve chainability.
370
                        return returns !== undefined ? returns : this;
371
                }
372
        };
373
}($jQueryAdminimal, document, window));
374

    
375
(function($) {
376

    
377
// Create the responsive menu using SlickNav.
378
Drupal.admin.behaviors.responsivemenu = function (context, settings, $adminMenu) {
379

    
380
    $('#admin-menu-menu-responsive').slicknav({
381
                label: 'Menu',
382
                prependTo:'body',
383
                closedSymbol: "<i class=\"closed\"></i>",
384
                openedSymbol: "<i class=\"open\"></i>",
385
                allowParentLinks: true
386
        });
387

    
388
};
389

    
390
// Create the responsive shortcuts dropdown.
391
Drupal.admin.behaviors.responsiveshortcuts = function (context, settings, $adminMenu) {
392

    
393
  // Check if there are any shortucts to respondify.
394
  if(jQuery("div.toolbar-shortcuts ul.menu li").length){
395

    
396
          // Create the dropdown base
397
          $("<select id='responsive-shortcuts-dropdown'/>").appendTo("#admin-menu-shortcuts-responsive div.toolbar-shortcuts");
398

    
399
          // Create default option "Select"
400
          $("<option />", {
401
            "selected"  :  "selected",
402
            "class"     :  "hide",
403
            "value"     :  "",
404
            "text"      :  Drupal.t('Shortcuts')
405
          }).appendTo("#admin-menu-shortcuts-responsive div.toolbar-shortcuts select");
406

    
407
          // Populate dropdown with menu items
408
          $("#admin-menu-shortcuts-responsive div.toolbar-shortcuts a").each(function() {
409
            var el = $(this);
410
            $("<option />", {
411
              "value"   :  el.attr("href"),
412
              "text"    :  el.text()
413
            }).appendTo("#admin-menu-shortcuts-responsive div.toolbar-shortcuts select");
414
          });
415

    
416
      // Redirect the user when selecting an option.
417
          $("#admin-menu-shortcuts-responsive div.toolbar-shortcuts select").change(function() {
418
            window.location = $(this).find("option:selected").val();
419
          });
420

    
421
          // Clean the mess.
422
          $('#admin-menu-shortcuts-responsive div.toolbar-shortcuts ul').remove();
423
          // Move the select box into the responsive menu.
424
          $("#admin-menu-shortcuts-responsive").prependTo(".slicknav_menu");
425

    
426
          }
427

    
428
  // Remove the edit shortcuts link from the DOM to avoid duble rendering.
429
  $('#admin-menu-shortcuts-responsive #edit-shortcuts').remove();
430

    
431
};
432
})($jQueryAdminimal);