vendor/assets/stylesheets/bower_components/foundation/js/foundation/foundation.tab.js in paint-rails-0.6.7 vs vendor/assets/stylesheets/bower_components/foundation/js/foundation/foundation.tab.js in paint-rails-0.7.24

- old
+ new

@@ -2,59 +2,78 @@ 'use strict'; Foundation.libs.tab = { name : 'tab', - version : '5.4.7', + version : '5.5.2', settings : { - active_class: 'active', + active_class : 'active', callback : function () {}, - deep_linking: false, - scroll_to_content: true, - is_hover: false + deep_linking : false, + scroll_to_content : true, + is_hover : false }, - default_tab_hashes: [], + default_tab_hashes : [], init : function (scope, method, options) { var self = this, S = this.S; + // Store the default active tabs which will be referenced when the + // location hash is absent, as in the case of navigating the tabs and + // returning to the first viewing via the browser Back button. + S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () { + self.default_tab_hashes.push(this.hash); + }); + + // store the initial href, which is used to allow correct behaviour of the + // browser back button when deep linking is turned on. + self.entry_location = window.location.href; + this.bindings(method, options); this.handle_location_hash_change(); - - // Store the default active tabs which will be referenced when the - // location hash is absent, as in the case of navigating the tabs and - // returning to the first viewing via the browser Back button. - S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () { - self.default_tab_hashes.push(this.hash); - }); }, events : function () { var self = this, S = this.S; - var usual_tab_behavior = function (e) { - var settings = S(this).closest('[' + self.attr_name() +']').data(self.attr_name(true) + '-init'); + var usual_tab_behavior = function (e, target) { + var settings = S(target).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'); if (!settings.is_hover || Modernizr.touch) { e.preventDefault(); e.stopPropagation(); - self.toggle_active_tab(S(this).parent()); + self.toggle_active_tab(S(target).parent()); } }; S(this.scope) .off('.tab') + // Key event: focus/tab key + .on('keydown.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) { + var el = this; + var keyCode = e.keyCode || e.which; + // if user pressed tab key + if (keyCode == 9) { + e.preventDefault(); + // TODO: Change usual_tab_behavior into accessibility function? + usual_tab_behavior(e, el); + } + }) // Click event: tab title - .on('focus.fndtn.tab', '[' + this.attr_name() + '] > * > a', usual_tab_behavior ) - .on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', usual_tab_behavior ) + .on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) { + var el = this; + usual_tab_behavior(e, el); + }) // Hover event: tab title .on('mouseenter.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) { - var settings = S(this).closest('[' + self.attr_name() +']').data(self.attr_name(true) + '-init'); - if (settings.is_hover) self.toggle_active_tab(S(this).parent()); + var settings = S(this).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'); + if (settings.is_hover) { + self.toggle_active_tab(S(this).parent()); + } }); // Location hash change event S(window).on('hashchange.fndtn.tab', function (e) { e.preventDefault(); @@ -101,20 +120,21 @@ } } }); }, - toggle_active_tab: function (tab, location_hash) { - var S = this.S, + toggle_active_tab : function (tab, location_hash) { + var self = this, + S = self.S, tabs = tab.closest('[' + this.attr_name() + ']'), tab_link = tab.find('a'), anchor = tab.children('a').first(), target_hash = '#' + anchor.attr('href').split('#')[1], target = S(target_hash), siblings = tab.siblings(), settings = tabs.data(this.attr_name(true) + '-init'), - interpret_keyup_action = function(e) { + interpret_keyup_action = function (e) { // Light modification of Heydon Pickering's Practical ARIA Examples: http://heydonworks.com/practical_aria_examples/js/a11y.js // define current, previous and next (possible) tabs var $original = $(this); @@ -155,55 +175,67 @@ // Show panel which corresponds to target $('#' + $(document.activeElement).attr('href').substring(1)) .attr('aria-hidden', null); + }, + go_to_hash = function(hash) { + // This function allows correct behaviour of the browser's back button when deep linking is enabled. Without it + // the user would get continually redirected to the default hash. + var is_entry_location = window.location.href === self.entry_location, + default_hash = settings.scroll_to_content ? self.default_tab_hashes[0] : is_entry_location ? window.location.hash :'fndtn-' + self.default_tab_hashes[0].replace('#', '') + + if (!(is_entry_location && hash === default_hash)) { + window.location.hash = hash; + } }; // allow usage of data-tab-content attribute instead of href - if (S(this).data(this.data_attr('tab-content'))) { - target_hash = '#' + S(this).data(this.data_attr('tab-content')).split('#')[1]; + if (anchor.data('tab-content')) { + target_hash = '#' + anchor.data('tab-content').split('#')[1]; target = S(target_hash); } if (settings.deep_linking) { if (settings.scroll_to_content) { + // retain current hash to scroll to content - window.location.hash = location_hash || target_hash; + go_to_hash(location_hash || target_hash); + if (location_hash == undefined || location_hash == target_hash) { tab.parent()[0].scrollIntoView(); } else { S(target_hash)[0].scrollIntoView(); } } else { // prefix the hashes so that the browser doesn't scroll down if (location_hash != undefined) { - window.location.hash = 'fndtn-' + location_hash.replace('#', ''); + go_to_hash('fndtn-' + location_hash.replace('#', '')); } else { - window.location.hash = 'fndtn-' + target_hash.replace('#', ''); + go_to_hash('fndtn-' + target_hash.replace('#', '')); } } } // WARNING: The activation and deactivation of the tab content must // occur after the deep linking in order to properly refresh the browser // window (notably in Chrome). // Clean up multiple attr instances to done once tab.addClass(settings.active_class).triggerHandler('opened'); - tab_link.attr({"aria-selected": "true", tabindex: 0}); + tab_link.attr({'aria-selected' : 'true', tabindex : 0}); siblings.removeClass(settings.active_class) - siblings.find('a').attr({"aria-selected": "false", tabindex: -1}); - target.siblings().removeClass(settings.active_class).attr({"aria-hidden": "true", tabindex: -1}); - target.addClass(settings.active_class).attr('aria-hidden', 'false').removeAttr("tabindex"); + siblings.find('a').attr({'aria-selected' : 'false', tabindex : -1}); + target.siblings().removeClass(settings.active_class).attr({'aria-hidden' : 'true', tabindex : -1}); + target.addClass(settings.active_class).attr('aria-hidden', 'false').removeAttr('tabindex'); settings.callback(tab); - target.triggerHandler('toggled', [tab]); - tabs.triggerHandler('toggled', [target]); + target.triggerHandler('toggled', [target]); + tabs.triggerHandler('toggled', [tab]); tab_link.off('keydown').on('keydown', interpret_keyup_action ); }, - data_attr: function (str) { + data_attr : function (str) { if (this.namespace.length > 0) { return this.namespace + '-' + str; } return str;