1/*jslint unparam: true, browser: true, indent: 2 */ 2 3; 4(function($, window, document) { 5 'use strict'; 6 7 Foundation.libs.section = { 8 name : 'section', 9 10 version : '4.3.1', 11 12 settings: { 13 deep_linking: false, 14 small_breakpoint: 768, 15 one_up: true, 16 section_selector: '[data-section]', 17 region_selector: 'section, .section, [data-section-region]', 18 title_selector: '.title, [data-section-title]', 19 //marker: container is resized 20 resized_data_attr: 'data-section-resized', 21 //marker: container should apply accordion style 22 small_style_data_attr: 'data-section-small-style', 23 content_selector: '.content, [data-section-content]', 24 nav_selector: '[data-section="vertical-nav"], [data-section="horizontal-nav"]', 25 active_class: 'active', 26 callback: function() {} 27 }, 28 29 init: function(scope, method, options) { 30 var self = this; 31 Foundation.inherit(this, 'throttle data_options position_right offset_right'); 32 33 if (typeof method === 'object') { 34 $.extend(true, self.settings, method); 35 } 36 37 if (typeof method !== 'string') { 38 this.events(); 39 return true; 40 } else { 41 return this[method].call(this, options); 42 } 43 }, 44 45 events: function() { 46 var self = this; 47 48 //combine titles selector from settings for click event binding 49 var click_title_selectors = [], 50 section_selector = self.settings.section_selector, 51 region_selectors = self.settings.region_selector.split(","), 52 title_selectors = self.settings.title_selector.split(","); 53 54 for (var i = 0, len = region_selectors.length; i < len; i++) { 55 var region_selector = region_selectors[i]; 56 57 for (var j = 0, len1 = title_selectors.length; j < len1; j++) { 58 var title_selector = section_selector + ">" + region_selector + ">" + title_selectors[j]; 59 60 click_title_selectors.push(title_selector + " a"); //or we can not do preventDefault for click event of <a> 61 click_title_selectors.push(title_selector); 62 } 63 } 64 65 $(self.scope) 66 .on('click.fndtn.section', click_title_selectors.join(","), function(e) { 67 var title = $(this).closest(self.settings.title_selector); 68 69 self.close_navs(title); 70 if (title.siblings(self.settings.content_selector).length > 0) { 71 self.toggle_active.call(title[0], e); 72 } 73 }); 74 75 $(window) 76 .on('resize.fndtn.section', self.throttle(function() { self.resize(); }, 30)) 77 .on('hashchange.fndtn.section', self.set_active_from_hash); 78 79 $(document).on('click.fndtn.section', function (e) { 80 if (e.isPropagationStopped && e.isPropagationStopped()) return; 81 if (e.target === document) return; 82 self.close_navs($(e.target).closest(self.settings.title_selector)); 83 }); 84 85 $(window).triggerHandler('resize.fndtn.section'); 86 $(window).triggerHandler('hashchange.fndtn.section'); 87 }, 88 89 //close nav !one_up on click elsewhere 90 close_navs: function(except_nav_with_title) { 91 var self = Foundation.libs.section, 92 navsToClose = $(self.settings.nav_selector) 93 .filter(function() { return !$.extend({}, 94 self.settings, self.data_options($(this))).one_up; }); 95 96 if (except_nav_with_title.length > 0) { 97 var section = except_nav_with_title.parent().parent(); 98 99 if (self.is_horizontal_nav(section) || self.is_vertical_nav(section)) { 100 //exclude current nav from list 101 navsToClose = navsToClose.filter(function() { return this !== section[0]; }); 102 } 103 } 104 //close navs on click on title 105 navsToClose.children(self.settings.region_selector).removeClass(self.settings.active_class); 106 }, 107 108 toggle_active: function(e) { 109 var $this = $(this), 110 self = Foundation.libs.section, 111 region = $this.parent(), 112 content = $this.siblings(self.settings.content_selector), 113 section = region.parent(), 114 settings = $.extend({}, self.settings, self.data_options(section)), 115 prev_active_region = section.children(self.settings.region_selector).filter("." + self.settings.active_class); 116 117 //for anchors inside [data-section-title] 118 if (!settings.deep_linking && content.length > 0) { 119 e.preventDefault(); 120 } 121 122 e.stopPropagation(); //do not catch same click again on parent 123 124 if (!region.hasClass(self.settings.active_class)) { 125 prev_active_region.removeClass(self.settings.active_class); 126 region.addClass(self.settings.active_class); 127 //force resize for better performance (do not wait timer) 128 self.resize(region.find(self.settings.section_selector).not("[" + self.settings.resized_data_attr + "]"), true); 129 } else if (!settings.one_up && (self.small(section) || self.is_vertical_nav(section) || self.is_horizontal_nav(section) || self.is_accordion(section))) { 130 region.removeClass(self.settings.active_class); 131 } 132 settings.callback(section); 133 }, 134 135 check_resize_timer: null, 136 137 //main function that sets title and content positions; runs for :not(.resized) and :visible once when window width is medium up 138 //sections: 139 // selected sections to resize, are defined on resize forced by visibility changes 140 //ensure_has_active_region: 141 // is true when we force resize for no resized sections that were hidden and became visible,
142 // these sections can have no selected region, because all regions were hidden along with section on executing set_active_from_hash 143 resize: function(sections, ensure_has_active_region) { 144 145 var self = Foundation.libs.section, 146 is_small_window = self.small($(document)), 147 //filter for section resize 148 should_be_resized = function (section, now_is_hidden) { 149 return !self.is_accordion(section) && 150 !section.is("[" + self.settings.resized_data_attr + "]") && 151 (!is_small_window || self.is_horizontal_tabs(section)) && 152 now_is_hidden === (section.css('display') === 'none' || 153 !section.parent().is(':visible')); 154 }; 155 156 sections = sections || $(self.settings.section_selector); 157 158 clearTimeout(self.check_resize_timer); 159 160 if (!is_small_window) { 161 sections.removeAttr(self.settings.small_style_data_attr); 162 } 163 164 //resize 165 sections.filter(function() { return should_be_resized($(this), false); }) 166 .each(function() { 167 var section = $(this), 168 regions = section.children(self.settings.region_selector), 169 titles = regions.children(self.settings.title_selector), 170 content = regions.children(self.settings.content_selector), 171 titles_max_height = 0; 172 173 if (ensure_has_active_region && 174 section.children(self.settings.region_selector).filter("." + self.settings.active_class).length == 0) { 175 var settings = $.extend({}, self.settings, self.data_options(section)); 176 177 if (!settings.deep_linking && (settings.one_up || !self.is_horizontal_nav(section) && 178 !self.is_vertical_nav(section) && !self.is_accordion(section))) { 179 regions.filter(":visible").first().addClass(self.settings.active_class); 180 } 181 } 182 183 if (self.is_horizontal_tabs(section) || self.is_auto(section)) { 184 // region: position relative 185 // title: position absolute 186 // content: position static 187 var titles_sum_width = 0; 188 189 titles.each(function() { 190 var title = $(this); 191 192 if (title.is(":visible")) { 193 title.css(!self.rtl ? 'left' : 'right', titles_sum_width); 194 var title_h_border_width = parseInt(title.css("border-" + (self.rtl ? 'left' : 'right') + "-width"), 10); 195 196 if (title_h_border_width.toString() === 'Nan') { 197 title_h_border_width = 0; 198 } 199 200 titles_sum_width += self.outerWidth(title) - title_h_border_width; 201 titles_max_height = Math.max(titles_max_height, self.outerHeight(title)); 202 } 203 }); 204 titles.css('height', titles_max_height); 205 regions.each(function() { 206 var region = $(this), 207 region_content = region.children(self.settings.content_selector), 208 content_top_border_width = parseInt(region_content.css("border-top-width"), 10); 209 210 if (content_top_border_width.toString() === 'Nan') { 211 content_top_border_width = 0; 212 } 213 214 region.css('padding-top', titles_max_height - content_top_border_width); 215 }); 216 217 section.css("min-height", titles_max_height); 218 } else if (self.is_horizontal_nav(section)) { 219 var first = true; 220 // region: positon relative, float left 221 // title: position static 222 // content: position absolute 223 titles.each(function() { 224 titles_max_height = Math.max(titles_max_height, self.outerHeight($(this))); 225 }); 226 227 regions.each(function() { 228 var region = $(this); 229 230 region.css("margin-left", "-" + (first ? section : region.children(self.settings.title_selector)).css("border-left-width")); 231 first = false; 232 }); 233 234 regions.css("margin-top", "-" + section.css("border-top-width")); 235 titles.css('height', titles_max_height); 236 content.css('top', titles_max_height); 237 section.css("min-height", titles_max_height); 238 } else if (self.is_vertical_tabs(section)) { 239 var titles_sum_height = 0; 240 // region: position relative, for .active: fixed padding==title.width 241 // title: fixed width, position absolute 242 // content: position static 243 titles.each(function() { 244 var title = $(this); 245
246 if (title.is(":visible")) { 247 title.css('top', titles_sum_height); 248 var title_top_border_width = parseInt(title.css("border-top-width"), 10); 249 250 if (title_top_border_width.toString() === 'Nan') { 251 title_top_border_width = 0; 252 } 253 254 titles_sum_height += self.outerHeight(title) - title_top_border_width; 255 } 256 }); 257 258 content.css('min-height', titles_sum_height + 1); 259 } else if (self.is_vertical_nav(section)) { 260 var titles_max_width = 0, 261 first1 = true; 262 // region: positon relative 263 // title: position static 264 // content: position absolute 265 titles.each(function() { 266 titles_max_width = Math.max(titles_max_width, self.outerWidth($(this))); 267 }); 268 269 regions.each(function () { 270 var region = $(this); 271 272 region.css("margin-top", "-" + (first1 ? section : region.children(self.settings.title_selector)).css("border-top-width")); 273 first1 = false; 274 }); 275 276 titles.css('width', titles_max_width); 277 content.css(!self.rtl ? 'left' : 'right', titles_max_width); 278 section.css('width', titles_max_width); 279 } 280 281 section.attr(self.settings.resized_data_attr, true); 282 }); 283 284 //wait elements to become visible then resize 285 if ($(self.settings.section_selector).filter(function() { return should_be_resized($(this), true); }).length > 0) 286 self.check_resize_timer = setTimeout(function() { 287 self.resize(sections.filter(function() { return should_be_resized($(this), false); }), true); 288 }, 700); 289 290 if (is_small_window) { 291 sections.attr(self.settings.small_style_data_attr, true); 292 } 293 }, 294 295 is_vertical_nav: function(el) { 296 return /vertical-nav/i.test(el.data('section')); 297 }, 298 299 is_horizontal_nav: function(el) { 300 return /horizontal-nav/i.test(el.data('section')); 301 }, 302 303 is_accordion: function(el) { 304 return /accordion/i.test(el.data('section')); 305 }, 306 307 is_horizontal_tabs: function(el) { 308 return /^tabs$/i.test(el.data('section')); 309 }, 310 311 is_vertical_tabs: function(el) { 312 return /vertical-tabs/i.test(el.data('section')); 313 }, 314 315 is_auto: function (el) { 316 var data_section = el.data('section'); 317 return data_section === '' || /auto/i.test(data_section); 318 }, 319 320 set_active_from_hash: function() { 321 var self = Foundation.libs.section, 322 hash = window.location.hash.substring(1), 323 sections = $(self.settings.section_selector); 324 325 sections.each(function() { 326 var section = $(this), 327 settings = $.extend({}, self.settings, self.data_options(section)), 328 regions = section.children(self.settings.region_selector), 329 set_active_from_hash = settings.deep_linking && hash.length > 0, 330 selected = false; 331 332 regions.each(function() { 333 var region = $(this); 334 335 if (selected) { 336 region.removeClass(self.settings.active_class); 337 } else if (set_active_from_hash) { 338 var data_slug = region.children(self.settings.content_selector).data('slug'); 339 340 if (data_slug && new RegExp(data_slug, 'i').test(hash)) { 341 if (!region.hasClass(self.settings.active_class)) 342 region.addClass(self.settings.active_class); 343 selected = true; 344 } else { 345 region.removeClass(self.settings.active_class); 346 } 347 } else if (region.hasClass(self.settings.active_class)) { 348 selected = true; 349 } 350 }); 351 352 if (!selected && !settings.deep_linking && (settings.one_up || !self.is_horizontal_nav(section) && 353 !self.is_vertical_nav(section) && !self.is_accordion(section))) 354 regions.filter(":visible").first().addClass(self.settings.active_class); 355 }); 356 }, 357 358 reflow: function() { 359 var self = Foundation.libs.section; 360 361 $(self.settings.section_selector).removeAttr(self.settings.resized_data_attr); 362 self.throttle(function() { self.resize(); }, 30)(); 363 }, 364 365 small: function(el) { 366 var settings = $.extend({}, this.settings, this.data_options(el)); 367 368 if (this.is_horizontal_tabs(el)) { 369 return false;
370 } 371 if (el && this.is_accordion(el)) { 372 return true; 373 } 374 if ($('html').hasClass('lt-ie9')) { 375 return true; 376 } 377 if ($('html').hasClass('ie8compat')) { 378 return true; 379 } 380 return $(this.scope).width() < settings.small_breakpoint; 381 }, 382 383 off: function() { 384 $(this.scope).off('.fndtn.section'); 385 $(window).off('.fndtn.section'); 386 $(document).off('.fndtn.section'); 387 } 388 }; 389 390 //resize selected sections 391 $.fn.reflow_section = function(ensure_has_active_region) { 392 var section = this, 393 self = Foundation.libs.section; 394 395 section.removeAttr(self.settings.resized_data_attr); 396 self.throttle(function() { self.resize(section, ensure_has_active_region); }, 30)(); 397 return this; 398 }; 399 400}(Foundation.zj, window, document));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.