Files

149 lines
6.1 KiB
JavaScript
Executable File

/*
* sf-Smallscreen v1.0b - Provides small-screen compatibility for the jQuery Superfish plugin.
*
* Developer's note:
* Built as a part of the Superfish project for Drupal (http://drupal.org/project/superfish)
* Found any bug? have any cool ideas? contact me right away! http://drupal.org/user/619294/contact
*
* jQuery version: 1.3.x or higher.
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
(function($){
$.fn.sfsmallscreen = function(options){
options = $.extend({
mode: 'inactive',
breakpoint: 768,
useragent: '',
title: '',
addSelected: true,
menuClasses: true,
hyperlinkClasses: true,
excludeClass_menu: '',
excludeClass_hyperlink: '',
includeClass_menu: '',
includeClass_hyperlink: ''
}, options);
// We need to clean up the menu from anything unnecessary.
function refine(menu){
if ($('.sf-megamenu', menu).length > 0){
var refined = menu.clone();
refined.find('div.sf-megamenu-column > ol').each(function(){
$(this).replaceWith('<ul>' + $(this).html() + '</ul>');
});
refined.find('div.sf-megamenu-column').each(function(){
$(this).replaceWith($(this).html());
}).end().find('.sf-megamenu-wrapper > ol').each(function(){
$(this).replaceWith($(this).html());
}).end().find('li.sf-megamenu-wrapper').each(function(){
$(this).replaceWith($(this).html());
});
} else {
var refined = menu.clone();
}
refined.find('.sf-smallscreen-remove').each(function(){
$(this).replaceWith($(this).html());
}).end().find('.sf-sub-indicator, .sf-description').each(function(){
$(this).remove();
});
return refined;
}
// Currently the only available reaction is converting the menu into a <select> element;
// In the next version there will be another reaction that will create a "compact" version of
// the menu, using <ul> element hence easy to style with CSS and so on and so forth.
function toSelect(menu, level){
var items = '';
$(menu).children('li').each(function(){
var list = $(this);
list.children('a, span').each(function(){
var item = $(this),
path = item.is('a') ? item.attr('href') : '',
itemClone = item.clone(),
classes = (options.hyperlinkClasses) ? ((options.excludeClass_hyperlink && itemClone.hasClass(options.excludeClass_hyperlink)) ? itemClone.removeClass(options.excludeClass_hyperlink).attr('class') : itemClone.attr('class')) : '',
classes = (options.includeClass_hyperlink && !itemClone.hasClass(options.includeClass_hyperlink)) ? ((options.hyperlinkClasses) ? itemClone.addClass(options.includeClass_hyperlink).attr('class') : options.includeClass_hyperlink) : classes,
classes = (classes) ? ' class="' + classes + '"' : '',
disable = item.is('span') ? ' disabled="disabled"' : '',
subIndicator = 1 < level ? Array(level).join('-') + ' ' : '';
items += '<option value="' + path + '"' + classes + disable + '>' + subIndicator + $.trim(item.text()) +'</option>';
list.find('> ul').each(function(){
items += toSelect(this, level + 1);
});
});
});
return items;
}
// Create the new version, hide the original.
function convert(menu){
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')) : '',
classes = (options.includeClass_menu && !menuClone.hasClass(options.includeClass_menu)) ? ((options.menuClasses) ? menuClone.addClass(options.includeClass_menu).attr('class') : options.includeClass_menu) : classes,
classes = (classes) ? ' class="' + classes + '"' : '';
if ($('#' + menu.attr('id') + '-select').length == 0){
var selectList = $('<select' + classes + ' id="' + menu.attr('id') + '-select"/>'),
refinedMenu = refine(menu);
newMenu = toSelect(refinedMenu, 1);
selectList.append('<option>' + options.title + '</option>').append(newMenu).change(function(){
window.location = selectList.val();
});
if (options.addSelected) {
selectList.find('.active').attr("selected", !0);
}
menu.before(selectList).hide();
}
}
// Turn everything back to normal.
function turnBack(menu){
var id = '#' + menu.attr('id');
$(id + '-select').remove();
$(id).show();
}
// Return original object to support chaining.
return this.each(function(){
var menu = $(this),
mode = options.mode;
// The rest is crystal clear, isn't it? :)
switch (mode){
case 'always_active' :
convert(menu);
break;
case 'window_width' :
if ($(window).width() < options.breakpoint){
convert(menu);
}
var timer;
$(window).resize(function(){
clearTimeout(timer);
timer = setTimeout(function(){
if ($(window).width() < options.breakpoint){
convert(menu);
}
else {
turnBack(menu);
}
}, 100);
});
break;
case 'useragent_custom' :
if (options.useragent != ''){
var ua = RegExp(options.useragent, 'i');
if (navigator.userAgent.match(ua)){
convert(menu);
}
}
break;
case 'useragent_predefined' :
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)){
convert(menu);
}
break;
}
});
};
})(jQuery);