Created
June 17, 2013 14:15
-
-
Save chrisjimallen/5797197 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*jslint unparam: true, browser: true, indent: 2 */ | |
;(function ($, window, document, undefined) { | |
'use strict'; | |
Foundation.libs.section = { | |
name: 'section', | |
version : '4.2.2', | |
settings : { | |
deep_linking: false, | |
small_breakpoint: 768, | |
one_up: true, | |
section_selector : '[data-section]', | |
region_selector : 'section, .section, [data-section-region]', | |
title_selector : '.title, [data-section-title]', | |
active_region_selector : 'section.active, .section.active, .active[data-section-region]', | |
content_selector : '.content, [data-section-content]', | |
nav_selector : '[data-section="vertical-nav"], [data-section="horizontal-nav"]', | |
callback: function (){} | |
}, | |
init : function (scope, method, options) { | |
var self = this; | |
Foundation.inherit(this, 'throttle data_options position_right offset_right'); | |
if (typeof method === 'object') { | |
$.extend(true, self.settings, method); | |
} | |
if (typeof method !== 'string') { | |
this.set_active_from_hash(); | |
this.events(); | |
return true; | |
} else { | |
return this[method].call(this, options); | |
} | |
}, | |
events : function () { | |
var self = this; | |
$(this.scope) | |
.on('click.fndtn.section', '[data-section] .title, [data-section] [data-section-title]', function (e) { | |
var $this = $(this), | |
section = $this.closest(self.settings.region_selector); | |
if (section.children(self.settings.content_selector).length > 0) { | |
self.toggle_active.call(this, e, self); | |
self.reflow(); | |
} | |
}); | |
$(window) | |
.on('resize.fndtn.section', self.throttle(function () { | |
self.resize.call(this); | |
}, 30)) | |
.on('hashchange', function () { | |
if (!self.settings.toggled){ | |
self.set_active_from_hash(); | |
$(this).trigger('resize'); | |
} | |
}).trigger('resize'); | |
$(document) | |
.on('click.fndtn.section', function (e) { | |
if ($(e.target).closest(self.settings.title_selector).length < 1) { | |
$(self.settings.nav_selector) | |
.children(self.settings.region_selector) | |
.removeClass('active') | |
.attr('style', ''); | |
} | |
}); | |
}, | |
toggle_active : function (e, self) { | |
var $this = $(this), | |
self = Foundation.libs.section, | |
region = $this.closest(self.settings.region_selector), | |
content = $this.siblings(self.settings.content_selector), | |
parent = region.parent(), | |
settings = $.extend({}, self.settings, self.data_options(parent)), | |
prev_active_section = parent | |
.children(self.settings.active_region_selector); | |
console.log(self,'self'); | |
console.log(region,'region'); | |
console.log(content,'content'); | |
console.log(parent,'parent'); | |
console.log(settings,'settings'); | |
console.log(prev_active_section,'prev_active_section'); | |
self.settings.toggled = true; | |
if (!settings.deep_linking && content.length > 0) { | |
e.preventDefault(); | |
} | |
if (region.hasClass('active')) { | |
// this is causing the style flash. | |
if (self.small(parent) | |
|| self.is_vertical_nav(parent) | |
|| self.is_horizontal_nav(parent) | |
|| self.is_accordion(parent)) { | |
if (prev_active_section[0] !== region[0] | |
|| (prev_active_section[0] === region[0] && !settings.one_up)) { | |
region | |
.removeClass('active') | |
.attr('style', ''); | |
} | |
} | |
} else { | |
var prev_active_section = parent | |
.children(self.settings.active_region_selector), | |
title_height = self.outerHeight(region | |
.children(self.settings.title_selector)); | |
if (self.small(parent) || settings.one_up) { | |
if (self.small(parent)) { | |
prev_active_section.attr('style', ''); | |
} else { | |
prev_active_section.attr('style', | |
'visibility: hidden; padding-top: '+title_height+'px;'); | |
} | |
} | |
if (self.small(parent)) { | |
region.attr('style', ''); | |
} else { | |
region.css('padding-top', title_height); | |
} | |
region.addClass('active'); | |
if (prev_active_section.length > 0) { | |
prev_active_section | |
.removeClass('active') | |
.attr('style', ''); | |
} | |
// Toggle the content display attribute. This is done to | |
// ensure accurate outerWidth measurements that account for | |
// the scrollbar. | |
if (self.is_vertical_tabs(parent)) { | |
content.css('display', 'block'); | |
if (prev_active_section !== null) { | |
prev_active_section | |
.children(self.settings.content_selector) | |
.css('display', 'none'); | |
} | |
} | |
} | |
setTimeout(function () { | |
self.settings.toggled = false; | |
}, 300); | |
settings.callback(); | |
}, | |
resize : function () { | |
var self = Foundation.libs.section, | |
sections = $(self.settings.section_selector); | |
sections.each(function() { | |
var $this = $(this), | |
active_section = $this | |
.children(self.settings.active_region_selector), | |
settings = $.extend({}, self.settings, self.data_options($this)); | |
if (active_section.length > 1) { | |
active_section | |
.not(':first') | |
.removeClass('active') | |
.attr('style', ''); | |
} else if (active_section.length < 1 | |
&& !self.is_vertical_nav($this) | |
&& !self.is_horizontal_nav($this) | |
&& !self.is_accordion($this)) { | |
var first = $this.children(self.settings.region_selector).first(); | |
if (settings.one_up || !self.small($this)) { | |
first.addClass('active'); | |
} | |
if (self.small($this)) { | |
first.attr('style', ''); | |
} else { | |
first.css('padding-top', self.outerHeight(first | |
.children(self.settings.title_selector))); | |
} | |
} | |
if (self.small($this)) { | |
active_section.attr('style', ''); | |
} else { | |
active_section.css('padding-top', self.outerHeight(active_section | |
.children(self.settings.title_selector))); | |
} | |
self.position_titles($this); | |
if ( (self.is_horizontal_nav($this) && !self.small($this)) | |
|| self.is_vertical_tabs($this) && !self.small($this)) { | |
self.position_content($this); | |
} else { | |
self.position_content($this, false); | |
} | |
}); | |
}, | |
is_vertical_nav : function (el) { | |
return /vertical-nav/i.test(el.data('section')); | |
}, | |
is_horizontal_nav : function (el) { | |
return /horizontal-nav/i.test(el.data('section')); | |
}, | |
is_accordion : function (el) { | |
return /accordion/i.test(el.data('section')); | |
}, | |
is_horizontal_tabs : function (el) { | |
return /^tabs$/i.test(el.data('section')); | |
}, | |
is_vertical_tabs : function (el) { | |
return /vertical-tabs/i.test(el.data('section')); | |
}, | |
set_active_from_hash : function () { | |
var hash = window.location.hash.substring(1), | |
sections = $('[data-section]'), | |
self = this; | |
sections.each(function () { | |
var section = $(this), | |
settings = $.extend({}, self.settings, self.data_options(section)); | |
if (hash.length > 0 && settings.deep_linking) { | |
var regions = section | |
.children(self.settings.region_selector) | |
.attr('style', '') | |
.removeClass('active'); | |
var hash_regions = regions.map(function () { | |
var content = $(self.settings.content_selector, this), | |
content_slug = content.data('slug'); | |
if (new RegExp(content_slug, 'i').test(hash)) | |
return content; | |
}); | |
var count = hash_regions.length; | |
for (var i = count - 1; i >= 0; i--) { | |
$(hash_regions[i]).parent().addClass('active'); | |
} | |
} | |
}); | |
}, | |
position_titles : function (section, off) { | |
var self = this, | |
titles = section | |
.children(this.settings.region_selector) | |
.map(function () { | |
return $(this).children(self.settings.title_selector); | |
}), | |
previous_width = 0, | |
previous_height = 0, | |
self = this; | |
if (typeof off === 'boolean') { | |
titles.attr('style', ''); | |
} else { | |
titles.each(function () { | |
if (self.is_vertical_tabs(section)) { | |
$(this).css('top', previous_height); | |
previous_height += self.outerHeight($(this)); | |
} else { | |
if (!self.rtl) { | |
$(this).css('left', previous_width); | |
} else { | |
$(this).css('right', previous_width); | |
} | |
previous_width += self.outerWidth($(this)); | |
} | |
}); | |
} | |
}, | |
position_content : function (section, off) { | |
var self = this, | |
regions = section.children(self.settings.region_selector), | |
titles = regions | |
.map(function () { | |
return $(this).children(self.settings.title_selector); | |
}), | |
content = regions | |
.map(function () { | |
return $(this).children(self.settings.content_selector); | |
}); | |
if (typeof off === 'boolean') { | |
content.attr('style', ''); | |
section.attr('style', ''); | |
} else { | |
if (self.is_vertical_tabs(section) | |
&& !self.small(section)) { | |
var content_min_height = 0, | |
content_min_width = Number.MAX_VALUE, | |
title_width = null; | |
regions.each(function () { | |
var region = $(this), | |
title = region.children(self.settings.title_selector), | |
content = region.children(self.settings.content_selector), | |
content_width = 0; | |
title_width = self.outerWidth(title); | |
content_width = self.outerWidth(section) - title_width; | |
if (content_width < content_min_width) { | |
content_min_width = content_width; | |
} | |
// Increment the minimum height of the content region | |
// to align with the height of the titles. | |
content_min_height += self.outerHeight(title); | |
// Set all of the inactive tabs to 'display: none' | |
// The CSS sets all of the tabs as 'display: block' | |
// in order to account for scrollbars when measuring the width | |
// of the content regions. | |
if (!$(this).hasClass('active')) { | |
content.css('display', 'none'); | |
} | |
}); | |
regions.each(function () { | |
var content = $(this).children(self.settings.content_selector); | |
content.css('minHeight', content_min_height); | |
// Remove 2 pixels to account for the right-shift in the CSS | |
content.css('maxWidth', content_min_width - 2); | |
}); | |
} else { | |
regions.each(function () { | |
var region = $(this), | |
title = region.children(self.settings.title_selector), | |
content = region.children(self.settings.content_selector); | |
if (!self.rtl) { | |
content | |
.css({left: title.position().left - 1, | |
top: self.outerHeight(title) - 2}); | |
} else { | |
content | |
.css({right: self.position_right(title) + 1, | |
top: self.outerHeight(title) - 2}); | |
} | |
}); | |
// temporary work around for Zepto outerheight calculation issues. | |
if (typeof Zepto === 'function') { | |
section.height(this.outerHeight($(titles[0]))); | |
} else { | |
section.height(this.outerHeight($(titles[0])) - 2); | |
} | |
} | |
} | |
}, | |
position_right : function (el) { | |
var self = this, | |
section = el.closest(this.settings.section_selector), | |
regions = section.children(this.settings.region_selector), | |
section_width = el.closest(this.settings.section_selector).width(), | |
offset = regions | |
.map(function () { | |
return $(this).children(self.settings.title_selector); | |
}).length; | |
return (section_width - el.position().left - el.width() * (el.index() + 1) - offset); | |
}, | |
reflow : function (scope) { | |
var scope = scope || document; | |
$(this.settings.section_selector, scope).trigger('resize'); | |
}, | |
small : function (el) { | |
var settings = $.extend({}, this.settings, this.data_options(el)); | |
if (this.is_horizontal_tabs(el)) { | |
return false; | |
} | |
if (el && this.is_accordion(el)) { | |
return true; | |
} | |
if ($('html').hasClass('lt-ie9')) { | |
return true; | |
} | |
if ($('html').hasClass('ie8compat')) { | |
return true; | |
} | |
return $(this.scope).width() < settings.small_breakpoint; | |
}, | |
off : function () { | |
$(this.scope).off('.fndtn.section'); | |
$(window).off('.fndtn.section'); | |
$(document).off('.fndtn.section') | |
} | |
}; | |
}(Foundation.zj, this, this.document)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment