Projet

Général

Profil

Paste
Télécharger (6,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / libraries / Superfish-for-Drupal-1.x / sfsmallscreen.js @ 2734bffc

1
/*
2
 * sf-Smallscreen v1.0b - Provides small-screen compatibility for the jQuery Superfish plugin.
3
 *
4
 * Developer's note:
5
 * Built as a part of the Superfish project for Drupal (http://drupal.org/project/superfish)
6
 * Found any bug? have any cool ideas? contact me right away! http://drupal.org/user/619294/contact
7
 *
8
 * jQuery version: 1.3.x or higher.
9
 *
10
 * Dual licensed under the MIT and GPL licenses:
11
 *  http://www.opensource.org/licenses/mit-license.php
12
 *  http://www.gnu.org/licenses/gpl.html
13
 */
14

    
15
(function($){
16
  $.fn.sfsmallscreen = function(options){
17
    options = $.extend({
18
      mode: 'inactive',
19
      breakpoint: 768,
20
      useragent: '',
21
      title: '',
22
      addSelected: true,
23
      menuClasses: true,
24
      hyperlinkClasses: true,
25
      excludeClass_menu: '',
26
      excludeClass_hyperlink: '',
27
      includeClass_menu: '',
28
      includeClass_hyperlink: ''
29
    }, options);
30

    
31
    // We need to clean up the menu from anything unnecessary.
32
    function refine(menu){
33
      if ($('.sf-megamenu', menu).length > 0){
34
        var refined = menu.clone();
35
        refined.find('div.sf-megamenu-column > ol').each(function(){
36
          $(this).replaceWith('<ul>' + $(this).html() + '</ul>');
37
        });
38
        refined.find('div.sf-megamenu-column').each(function(){
39
          $(this).replaceWith($(this).html());
40
        }).end().find('.sf-megamenu-wrapper > ol').each(function(){
41
          $(this).replaceWith($(this).html());
42
        }).end().find('li.sf-megamenu-wrapper').each(function(){
43
          $(this).replaceWith($(this).html());
44
        });
45
      } else {
46
        var refined = menu.clone();
47
      }
48
      refined.find('.sf-smallscreen-remove').each(function(){
49
        $(this).replaceWith($(this).html());
50
      }).end().find('.sf-sub-indicator, .sf-description').each(function(){
51
        $(this).remove();
52
      });
53
      return refined;
54
    }
55

    
56
    // Currently the only available reaction is converting the menu into a <select> element;
57
    // In the next version there will be another reaction that will create a "compact" version of
58
    // the menu, using <ul> element hence easy to style with CSS and so on and so forth.
59
    function toSelect(menu, level){
60
      var items = '';
61
      $(menu).children('li').each(function(){
62
        var list = $(this);
63
        list.children('a, span').each(function(){
64
          var item = $(this),
65
          path = item.is('a') ? item.attr('href') : '',
66
          itemClone = item.clone(),
67
          classes = (options.hyperlinkClasses) ? ((options.excludeClass_hyperlink && itemClone.hasClass(options.excludeClass_hyperlink)) ? itemClone.removeClass(options.excludeClass_hyperlink).attr('class') : itemClone.attr('class')) : '',
68
          classes = (options.includeClass_hyperlink && !itemClone.hasClass(options.includeClass_hyperlink)) ? ((options.hyperlinkClasses) ? itemClone.addClass(options.includeClass_hyperlink).attr('class') : options.includeClass_hyperlink) : classes,
69
          classes = (classes) ? ' class="' + classes + '"' : '',
70
          disable = item.is('span') ? ' disabled="disabled"' : '',
71
          subIndicator = 1 < level ? Array(level).join('-') + ' ' : '';
72
          items += '<option value="' + path + '"' + classes + disable + '>' + subIndicator + $.trim(item.text()) +'</option>';
73
          list.find('> ul').each(function(){
74
            items += toSelect(this, level + 1);
75
          });
76
        });
77
      });
78
      return items;
79
    }
80

    
81
    // Create the new version, hide the original.
82
    function convert(menu){
83
      var menuClone = menu.clone(), classes = (options.menuClasses) ? ((options.excludeClass_menu && menuClone.hasClass(options.excludeClass_menu)) ? menuClone.removeClass(options.excludeClass_menu).attr('class') : menuClone.attr('class')) : '',
84
      classes = (options.includeClass_menu && !menuClone.hasClass(options.includeClass_menu)) ? ((options.menuClasses) ? menuClone.addClass(options.includeClass_menu).attr('class') : options.includeClass_menu) : classes,
85
      classes = (classes) ? ' class="' + classes + '"' : '';
86
      if ($('#' + menu.attr('id') + '-select').length == 0){
87
        var selectList = $('<select' + classes + ' id="' + menu.attr('id') + '-select"/>'),
88
        refinedMenu = refine(menu);
89
        newMenu = toSelect(refinedMenu, 1);
90
        selectList.append('<option>' + options.title + '</option>').append(newMenu).change(function(){
91
          window.location = selectList.val();
92
        });
93
        if (options.addSelected) {
94
          selectList.find('.active').attr("selected", !0);
95
        }
96
        menu.before(selectList).hide();
97
      }
98
    }
99

    
100
    // Turn everything back to normal.
101
    function turnBack(menu){
102
      var id = '#' + menu.attr('id');
103
      $(id + '-select').remove();
104
      $(id).show();
105
    }
106

    
107
    // Return original object to support chaining.
108
    return this.each(function(){
109
      var menu = $(this),
110
      mode = options.mode;
111
      // The rest is crystal clear, isn't it? :)
112
      switch (mode){
113
        case 'always_active' :
114
          convert(menu);
115
        break;
116
        case 'window_width' :
117
          if ($(window).width() < options.breakpoint){
118
            convert(menu);
119
          }
120
          var timer;
121
          $(window).resize(function(){
122
            clearTimeout(timer);
123
            timer = setTimeout(function(){
124
              if ($(window).width() < options.breakpoint){
125
                convert(menu);
126
              }
127
              else {
128
                turnBack(menu);
129
              }
130
            }, 100);
131
          });
132
        break;
133
        case 'useragent_custom' :
134
          if (options.useragent != ''){
135
            var ua = RegExp(options.useragent, 'i');
136
            if (navigator.userAgent.match(ua)){
137
              convert(menu);
138
            }
139
          }
140
        break;
141
        case 'useragent_predefined' :
142
          if (navigator.userAgent.match(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i)){
143
            convert(menu);
144
          }
145
        break;
146
      }
147
    });
148
  };
149
})(jQuery);