1/** 2 *------------------------------------------------------------------------------ 3 * @package T3 Framework for Joomla! 4 *------------------------------------------------------------------------------ 5 * @copyright Copyright (C) 2004-2013 JoomlArt.com. All Rights Reserved. 6 * @license GNU General Public License version 2 or later; see LICENSE.txt 7 * @authors JoomlArt, JoomlaBamboo, (contribute to this project at github 8 * & Google group to become co-author) 9 * @Google group: https://groups.google.com/forum/#!forum/t3fw 10 * @Link: http://t3-framework.org 11 *------------------------------------------------------------------------------ 12 */ 13 14;(function($){ 15 16 17 var T3Menu = function(elm, options){ 18 this.$menu = $(elm); 19 if (!this.$menu.length){ 20 return; 21 } 22 23 this.options = $.extend({}, $.fn.t3menu.defaults, options); 24 this.child_open = []; 25 this.loaded = false; 26 27 this.start(); 28 }; 29 30 T3Menu.prototype = { 31 constructor: T3Menu, 32 33 start: function () { 34 //init once 35 if (this.loaded){ 36 return; 37 } 38 this.loaded = true; 39 40 //start 41 var self = this, 42 options = this.options, 43 $menu = this.$menu; 44 45 this.$items = $menu.find('li'); 46 this.$items.each(function (idx, li) { 47 48 var $item = $(this), 49 $child = $item.children('.dropdown-menu'), 50 $link = $item.children('a'), 51 item = { 52 $item: $item, 53 child: $child.length, 54 link: $link.length, 55 clickable: !($link.length && $child.length), 56 mega: $item.hasClass('mega'), 57 status: 'close', 58 timer: null, 59 atimer: null 60 }; 61 62 //store 63 $item.data('t3menu.item', item); 64 65 //click action 66 if ($child.length && !options.hover) { 67 $item.on('click', function (e) { 68 e.stopPropagation(); 69 70 if ($item.hasClass('group')) { 71 return; 72 } 73 74 if (item.status == 'close') { 75 e.preventDefault(); 76 self.show(item); 77 } 78 }); 79 } else { 80 81 //stop if click on menu item - prevent bubble event 82 $item.on('click', function (e) { 83 e.stopPropagation() 84 }); 85 } 86 87 if (options.hover) { 88 $item.on('mouseover', function (e) { 89 if ($item.hasClass('group')) { 90 return; 91 } 92 93 e.stopPropagation(); 94 self.show(item); 95 96 }).on('mouseleave', function (e) { 97 if ($item.hasClass('group')) { 98 return; 99 } 100 101 e.stopPropagation(); 102 self.hide(item); 103 }); 104 105 //if has child, don't goto link before open child - fix for touch screen 106 if ($link.length && $child.length) { 107 $link.on('click', function (e) { 108 return item.clickable; 109 }); 110 } 111 } 112 113 }); 114 115 $(document.body).on('tap hideall.t3menu', function(e){ 116 clearTimeout(self.timer); 117 self.timer = setTimeout($.proxy(self.hide_alls, self), e.type == 'tap' ? 500 : self.options.hidedelay); 118 }); 119 }, 120 121 show: function (item) { 122 // hide all others menu of this instance 123 if($.inArray(item, this.child_open) < this.child_open.length -1){ 124 this.hide_others(item); 125 } 126 127 // hide all for other instances as well 128 $(document.body).trigger('hideall.t3menu', [this]); 129 130 clearTimeout(this.timer); //hide alls 131 clearTimeout(item.timer); //hide this item 132 clearTimeout(item.ftimer); //on hidden 133 clearTimeout(item.ctimer); //on hidden 134 135 if(item.status != 'open' || !item.$item.hasClass('open') || !this.child_open.length){ 136 if(item.mega){ 137 //remove timer 138 clearTimeout(item.astimer); //animate 139 clearTimeout(item.atimer); //animate 140 141 //place menu 142 this.position(item.$item); 143 144 // add class animate 145 item.astimer = setTimeout(function(){item.$item.addClass('animating')}, 10); 146 item.atimer = setTimeout(function(){item.$item.removeClass('animating')}, this.options.duration + 50); 147 item.timer = setTimeout(function(){item.$item.addClass('open')}, 100); 148 149 } else { 150 item.$item.addClass('open'); 151 } 152 153 item.status = 'open'; 154 if (item.child && $.inArray(item, this.child_open) == -1) { 155 this.child_open.push(item); 156 } 157 } 158 159 item.ctimer = setTimeout($.proxy(this.clickable, this, item), 300); 160 }, 161 162 hide: function (item) { 163 clearTimeout(this.timer); //hide alls 164 clearTimeout(item.timer); //hide this item 165 clearTimeout(item.astimer); //animate timer 166 clearTimeout(item.atimer); //animate timer 167 clearTimeout(item.ftimer); //on hidden 168 169 if(item.mega){ 170 //animate out 171 item.$item.addClass('animating'); 172 item.atimer = setTimeout(function(){item.$item.removeClass('animating')}, this.options.duration); 173 item.timer = setTimeout(function(){item.$item.removeClass('open')}, 100); 174 } else { 175 item.$item.removeClass('open'); 176 } 177 178 item.status = 'close'; 179 for (var i = this.child_open.length; i--;){ 180 if (this.child_open[i] === item){ 181 this.child_open.splice(i, 1); 182 } 183 } 184 185 item.ftimer = setTimeout($.proxy(this.hidden, this, item), this.options.duration); 186 this.timer = setTimeout($.proxy(this.hide_alls, this), this.options.hidedelay); 187 }, 188 189 hidden: function (item) { 190 //hide done 191 if (item.status == 'close') { 192 item.clickable = false;
193 } 194 }, 195 196 hide_others: function (item) { 197 var self = this; 198 $.each(this.child_open.slice(), function (idx, open) { 199 if (!item || (open != item && !open.$item.has(item.$item).length)) { 200 self.hide(open); 201 } 202 }); 203 }, 204 205 hide_alls: function (e, inst) { 206 if(!e || e.type == 'tap' || (e.type == 'hideall' && this != inst)){ 207 var self = this; 208 $.each(this.child_open.slice(), function (idx, item) { 209 item && self.hide(item); 210 }); 211 } 212 }, 213 214 clickable: function (item) { 215 item.clickable = true; 216 }, 217 218 position: function ($item) { 219 var sub = $item.children('.mega-dropdown-menu'), 220 is_show = sub.is(':visible'); 221 222 if(!is_show){ 223 sub.show(); 224 } 225 226 var offset = $item.offset(), 227 width = $item.outerWidth(), 228 screen_width = $(window).width() - this.options.sb_width, 229 sub_width = sub.outerWidth(), 230 level = $item.data('level'); 231 232 if(!is_show){ 233 sub.css('display', ''); 234 } 235 236 //reset custom align 237 sub.css({left : '', right : ''}); 238 239 if(level == 1){ 240 241 var align = $item.data('alignsub'), 242 align_offset = 0,
243 align_delta = 0, 244 align_trans = 0; 245 246 if(align == 'justify'){ 247 return; //do nothing 248 } 249 250 if(!align){ 251 align = 'left'; 252 } 253 254 if(align == 'center'){ 255 align_offset = offset.left + (width /2); 256 257 if(!$.support.t3transform){ 258 align_trans = -sub_width /2; 259 sub.css(this.options.rtl ? 'right' : 'left', align_trans + width /2); 260 } 261 262 } else { 263 align_offset = offset.left + ((align == 'left' && this.options.rtl || align == 'right' && !this.options.rtl) ? width : 0); 264 } 265 266 if (this.options.rtl) { 267 268 if(align == 'right'){ 269 if(align_offset + sub_width > screen_width){ 270 align_delta = screen_width - align_offset - sub_width; 271 sub.css('left', align_delta); 272 273 if(screen_width < sub_width){ 274 sub.css('left', align_delta + sub_width - screen_width); 275 } 276 } 277 } else { 278 if(align_offset < (align == 'center' ? sub_width /2 : sub_width)){ 279 align_delta = align_offset - (align == 'center' ? sub_width /2 : sub_width); 280 sub.css('right', align_delta + align_trans); 281 } 282 283 if(align_offset + (align == 'center' ? sub_width /2 : 0) - align_delta > screen_width){ 284 sub.css('right', align_offset + (align == 'center' ? (sub_width + width) /2 : 0) + align_trans - screen_width); 285 } 286 } 287 288 } else { 289 290 if(align == 'right'){ 291 if(align_offset < sub_width){ 292 align_delta = align_offset - sub_width; 293 sub.css('right', align_delta); 294 295 if(sub_width > screen_width){ 296 sub.css('right', sub_width - screen_width + align_delta); 297 } 298 } 299 } else { 300 301 if(align_offset + (align == 'center' ? sub_width /2 : sub_width) > screen_width){ 302 align_delta = screen_width - align_offset -(align == 'center' ? sub_width /2 : sub_width); 303 sub.css('left', align_delta + align_trans); 304 } 305 306 if(align_offset - (align == 'center' ? sub_width /2 : 0) + align_delta < 0){ 307 sub.css('left', (align == 'center' ? (sub_width + width) /2 : 0) + align_trans - align_offset); 308 } 309 } 310 } 311 } else { 312 313 if (this.options.rtl) { 314 if ($item.closest('.mega-dropdown-menu').parent().hasClass('mega-align-right')) { 315 316 //should be align to the right as parent 317 // $item.removeClass('mega-align-left').addClass('mega-align-right'); 318 319 // check if not able => revert the direction 320 if (offset.left + width + sub_width > screen_width) { 321 $item.removeClass('mega-align-right'); //should we add align left ? it is th default now 322 323 if(offset.left - sub_width < 0){ 324 sub.css('right', offset.left + width - sub_width); 325 } 326 } 327 } else { 328 if (offset.left - sub_width < 0) { 329 $item.removeClass('mega-align-left').addClass('mega-align-right'); 330 331 if(offset.left + width + sub_width > screen_width){ 332 sub.css('left', screen_width - offset.left - sub_width); 333 } 334 } 335 } 336 } else { 337 338 if ($item.closest('.mega-dropdown-menu').parent().hasClass('mega-align-right')) { 339 //should be align to the right as parent 340 // $item.removeClass('mega-align-left').addClass('mega-align-right'); 341 342 // check if not able => revert the direction 343 if (offset.left - sub_width < 0) { 344 $item.removeClass('mega-align-right'); //should we add align left ? it is th default now 345 346 if(offset.left + width + sub_width > screen_width){ 347 sub.css('left', screen_width - offset.left - sub_width); 348 } 349 } 350 } else { 351 352 if (offset.left + width + sub_width > screen_width) { 353 $item.removeClass('mega-align-left').addClass('mega-align-right'); 354 355 if(offset.left - sub_width < 0){ 356 sub.css('right', offset.left + width - sub_width); 357 } 358 } 359 } 360 } 361 } 362 } 363 }; 364 365 $.fn.t3menu = function (option) { 366 return this.each(function () { 367 var $this = $(this), 368 data = $this.data('megamenu'), 369 options = typeof option == 'object' && option; 370 371 if (!data) { 372 $this.data('megamenu', (data = new T3Menu(this, options))); 373 374 } else { 375 if (typeof option == 'string' && data[option]){ 376 data[option]() 377 } 378 } 379 }) 380 }; 381 382 $.fn.t3menu.defaults = { 383 duration: 400, 384 timeout: 100, 385 hidedelay: 200, 386 hover: true, 387 sb_width: 20 388 }; 389 390 391 //apply script 392 $(document).ready(function(){ 393 394 //detect settings 395 var mm_duration = $('.t3-megamenu').data('duration') || 0; 396 if (mm_duration) { 397 398 $('<style type="text/css">' + 399 '.t3-megamenu.animate .animating > .mega-dropdown-menu,' + 400 '.t3-megamenu.animate.slide .animating > .mega-dropdown-menu > div {' + 401 'transition-duration: ' + mm_duration + 'ms !important;' + 402 '-webkit-transition-duration: ' + mm_duration + 'ms !important;' + 403 '}
403' + 404 '</style>').appendTo ('head'); 405 } 406 407 var mm_timeout = mm_duration ? 100 + mm_duration : 500, 408 mm_rtl = $(document.documentElement).attr('dir') == 'rtl', 409 mm_trigger = $(document.documentElement).hasClass('mm-hover'), 410 sb_width = (function () { 411 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 412 child = parent.children(), 413 width = child.innerWidth() - child.height(100).innerWidth(); 414 415 parent.remove(); 416 417 return width; 418 })(); 419 420 //lt IE 10 421 if(!$.support.transition){ 422 //it is not support animate 423 $('.t3-megamenu').removeClass('animate'); 424 425 mm_timeout = 100; 426 } 427 428 //get ready 429 $('.nav').has('.dropdown-menu').t3menu({ 430 duration: mm_duration, 431 timeout: mm_timeout, 432 rtl: mm_rtl, 433 sb_width: sb_width, 434 hover: mm_trigger 435 }); 436 437 438 $(window).load(function(){ 439 440 //check we miss any nav 441 $('.nav').has('.dropdown-menu').t3menu({ 442 duration: mm_duration, 443 timeout: mm_timeout, 444 rtl: mm_rtl, 445 sb_width: sb_width, 446 hover: mm_trigger 447 }); 448 449 }); 450 }); 451 452})(jQuery);
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.