/*
* Supersubs v0.4b - jQuery plugin
* Copyright (c) 2013 Joel Birch
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
* their longest list item children. If you use this, please expect bugs and report them
* to the jQuery Google Group with the word 'Superfish' in the subject line.
*
*/
/*
* This is not the original jQuery Supersubs plugin.
* Please refer to the README for more information.
*/
(function($){ // $ will refer to jQuery within this closure
$.fn.supersubs = function(options){
var opts = $.extend({}, $.fn.supersubs.defaults, options);
// return original object to support chaining
// Although this is unnecessary due to the way the module uses these plugins.
for (var a = 0; a < this.length; a++) {
// cache selections
var $$ = $(this).eq(a),
// support metadata
o = $.meta ? $.extend({}, opts, $$.data()) : opts;
// Jump one level if it's a "NavBar"
if ($$.hasClass('sf-navbar')) {
$$ = $$.children('li').children('ul');
}
// cache all ul elements
var $ULs = $$.find('ul'),
// get the font size of menu.
// .css('fontSize') returns various results cross-browser, so measure an em dash instead
fontsize = $('
'),
size = fontsize.attr('style','padding:0;position:absolute;top:-99999em;width:auto;')
.appendTo($$)[0].clientWidth; //clientWidth is faster than width()
// remove em dash
fontsize.remove();
// loop through each ul in menu
for (var b = 0; b < $ULs.length; b++) {
var
// cache this ul
$ul = $ULs.eq(b);
// If a multi-column sub-menu, and only if correctly configured.
if (o.megamenu && $ul.hasClass('sf-megamenu') && $ul.find('.sf-megamenu-column').length > 0){
// Look through each column.
var $column = $ul.find('div.sf-megamenu-column > ol'),
// Overall width.
mwWidth = 0;
for (var d = 0; d < $column.length; d++){
resize($column.eq(d));
// New column width, in pixels.
var colWidth = $column.width();
// Just a trick to convert em unit to px.
$column.css({width:colWidth})
// Making column parents the same size.
.parents('.sf-megamenu-column').css({width:colWidth});
// Overall width.
mwWidth += parseInt(colWidth);
}
// Resizing the columns container too.
$ul.add($ul.find('li.sf-megamenu-wrapper, li.sf-megamenu-wrapper > ol')).css({width:mwWidth});
}
else {
resize($ul);
}
}
}
function resize($ul){
var
// get all (li) children of this ul
$LIs = $ul.children(),
// get all anchor grand-children
$As = $LIs.children('a');
// force content to one line and save current float property
$LIs.css('white-space','nowrap');
// remove width restrictions and floats so elements remain vertically stacked
$ul.add($LIs).add($As).css({float:'none',width:'auto'});
// this ul will now be shrink-wrapped to longest li due to position:absolute
// so save its width as ems.
var emWidth = $ul.get(0).clientWidth / size;
// add more width to ensure lines don't turn over at certain sizes in various browsers
emWidth += o.extraWidth;
// restrict to at least minWidth and at most maxWidth
if (emWidth > o.maxWidth) {emWidth = o.maxWidth;}
else if (emWidth < o.minWidth) {emWidth = o.minWidth;}
emWidth += 'em';
// set ul to width in ems
$ul.css({width:emWidth});
// restore li floats to avoid IE bugs
// set li width to full width of this ul
// revert white-space to normal
$LIs.add($As).css({float:'',width:'',whiteSpace:''});
// update offset position of descendant ul to reflect new width of parent.
// set it to 100% in case it isn't already set to this in the CSS
for (var c = 0; c < $LIs.length; c++) {
var $childUl = $LIs.eq(c).children('ul');
var offsetDirection = $childUl.css('left') !== undefined ? 'left' : 'right';
$childUl.css(offsetDirection,'100%');
}
}
return this;
};
// expose defaults
$.fn.supersubs.defaults = {
megamenu: true, // define width for multi-column sub-menus and their columns.
minWidth: 12, // requires em unit.
maxWidth: 27, // requires em unit.
extraWidth: 1 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
};
})(jQuery); // plugin code ends