1/** 2 * UpSolution Theme Core JavaScript Code 3 * 4 * @requires jQuery 5 */ 6if (window.$us === undefined) window.$us = {}; 7 8/** 9 * Retrieve/set/erase dom modificator class <mod>_<value> for UpSolution CSS Framework 10 * @param {String} mod Modificator namespace 11 * @param {String} [value] Value 12 * @returns {string|jQuery} 13 */ 14jQuery.fn.usMod = function(mod, value){ 15 if (this.length == 0) return this; 16 // Remove class modificator 17 if (value === false) { 18 this.get(0).className = this.get(0).className.replace(new RegExp('(^| )' + mod + '\_[a-z0-9]+( |$)'), '$2'); 19 return this; 20 } 21 var pcre = new RegExp('^.*?' + mod + '\_([a-z0-9]+).*?$'), 22 arr; 23 // Retrieve modificator 24 if (value === undefined) { 25 return (arr = pcre.exec(this.get(0).className)) ? arr[1] : false; 26 } 27 // Set modificator 28 else { 29 this.usMod(mod, false).get(0).className += ' ' + mod + '_' + value; 30 return this; 31 } 32}; 33 34/** 35 * Convert data from PHP to boolean the right way 36 * @param {mixed} value 37 * @returns {Boolean} 38 */ 39$us.toBool = function(value){ 40 if (typeof value == 'string') return (value == 'true' || value == 'True' || value == 'TRUE' || value == '1'); 41 if (typeof value == 'boolean') return value; 42 return !!parseInt(value); 43}; 44 45// Fixing hovers for devices with both mouse and touch screen 46jQuery.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); 47jQuery('html').toggleClass('no-touch', !jQuery.isMobile); 48 49/** 50 * Commonly used jQuery objects 51 */ 52!function($){ 53 $us.$window = $(window); 54 $us.$document = $(document); 55 $us.$html = $('html'); 56 $us.$body = $('.l-body:first'); 57 $us.$htmlBody = $us.$html.add($us.$body); 58 $us.$canvas = $('.l-canvas:first'); 59}(jQuery); 60 61/** 62 * $us.canvas 63 * 64 * All the needed data and functions to work with overall canvas. 65 */ 66!function($){ 67 "use strict"; 68 69 function USCanvas(options){ 70 71 // Setting options 72 var defaults = { 73 disableEffectsWidth: 900, 74 responsive: true 75 }; 76 this.options = $.extend({}, defaults, options || {}); 77 78 // Commonly used dom elements 79 this.$header = $us.$canvas.find('.l-header'); 80 this.$main = $us.$canvas.find('.l-main'); 81 this.$titlebar = $us.$canvas.find('.l-titlebar'); 82 this.$sections = $us.$canvas.find('.l-section'); 83 this.$firstSection = this.$sections.first(); 84 this.$fullscreenSections = this.$sections.filter('.height_full'); 85 this.$topLink = $('.w-toplink'); 86 87 // Canvas modificators 88 this.sidebar = $us.$canvas.usMod('sidebar'); 89 this.type = $us.$canvas.usMod('type'); 90 // Initial header position 91 this._headerPos = this.$header.usMod('pos'); 92 // Current header position 93 this.headerPos = this._headerPos; 94 this.headerBg = this.$header.usMod('bg'); 95 this.rtl = $us.$body.hasClass('rtl'); 96 97 // Will be used to count fullscreen sections heights and proper scroll positions 98 this.scrolledOccupiedHeight = 0; 99 100 // Used to prevent resize events on scroll for Android browsers 101 this.isScrolling = false; 102 this.scrollTimeout = false; 103 this.isAndroid = /Android/i.test(navigator.userAgent); 104 105 // Boundable events 106 this._events = { 107 scroll: this.scroll.bind(this), 108 resize: this.resize.bind(this) 109 }; 110 111 $us.$window.on('scroll', this._events.scroll); 112 $us.$window.on('resize load', this._events.resize); 113 // Complex logics requires two initial renders: before inner elements render and after 114 setTimeout(this._events.resize, 25); 115 setTimeout(this._events.resize, 75); 116 } 117 118 USCanvas.prototype = { 119 120 /** 121 * Scroll-driven logics 122 */ 123 scroll: function(){ 124 var scrollTop = parseInt($us.$window.scrollTop()); 125 126 // Show/hide go to top link 127 this.$topLink.toggleClass('active', (scrollTop >= this.winHeight)); 128 129 if (this.isAndroid) { 130 this.isScrolling = true; 131 if (this.scrollTimeout) clearTimeout(this.scrollTimeout); 132 this.scrollTimeout = setTimeout(function () { 133 this.isScrolling = false; 134 }, 100); 135 } 136 }, 137 138 /** 139 * Resize-driven logics 140 */ 141 resize: function(){ 142 // Window dimensions 143 this.winHeight = parseInt($us.$window.height()); 144 this.winWidth = parseInt($us.$window.width()); 145 146 // Disabling animation on mobile devices 147 $us.$body.toggleClass('disable_effects', (this.winWidth <= this.options.disableEffectsWidth)); 148 149 // Updating fullscreen sections 150 if (this.$fullscreenSections.length > 0 && ! this.isScrolling) { 151 var adminBar = $('#wpadminbar'), 152 adminBarHeight = (adminBar.length)?adminBar.height():0; 153 if ($.isMobile) { 154 155 } 156 this.$fullscreenSections.each(function(index, section){ 157 var $section = $(section), 158 sectionHeight = this.winHeight, 159 isFirstSection = (index == 0 && this.$titlebar.length == 0 && $section.is(this.$firstSection)); 160 // First section 161 if (isFirstSection) { 162 sectionHeight -= $section.offset().top; 163 } 164 // 2+ sections 165 else { 166 sectionHeight -= $us.header.scrolledOccupiedHeight + adminBarHeight; 167 } 168 $section.css('min-height', sectionHeight); 169 if ($section.hasClass('valign_center')) { 170 var $sectionH = $section.find('.l-section-h'), 171 sectionTopPadding = parseInt($section.css('padding-top')), 172 contentHeight = $sectionH.outerHeight(), 173 topMargin; 174 $sectionH.css('margin-top', ''); 175 // Section was extended by extra top padding that is overlapped by fixed solid header and n
175ot visible 176 var sectionOverlapped = isFirstSection && $us.header.pos == 'fixed' && $us.header.bg != 'transparent' && $us.header.orientation != 'ver'; 177 if (sectionOverlapped) { 178 // Part of first section is overlapped by header 179 topMargin = Math.max(0, (sectionHeight - sectionTopPadding - contentHeight) / 2); 180 } else { 181 topMargin = Math.max(0, (sectionHeight - contentHeight) / 2 - sectionTopPadding); 182 } 183 $sectionH.css('margin-top', topMargin || ''); 184 } 185 $section.find('.upb_row_bg').css('min-height', $section.height()); 186 }.bind(this)); 187 $us.$canvas.trigger('contentChange'); 188 } 189 190 // Fix scroll glitches that could occur after the resize 191 this.scroll(); 192 } 193 }; 194 195 $us.canvas = new USCanvas($us.canvasOptions || {}); 196 197}(jQuery); 198 199/** 200 * $us.header 201 * Dev note: should be initialized after $us.canvas 202 */ 203!function($){ 204 "use strict"; 205 function USHeader(settings){ 206 this.settings = settings || {}; 207 this.state = 'default'; // 'tablets' / 'mobiles' 208 this.$container = $us.$canvas.find('.l-header'); 209 this.$topCell = this.$container.find('.l-subheader.at_top .l-subheader-cell:first'); 210 this.$middleCell = this.$container.find('.l-subheader.at_middle .l-subheader-cell:first'); 211 this.$bottomCell = this.$container.find('.l-subheader.at_bottom .l-subheader-cell:first'); 212 this.$showBtn = $('.w-header-show:first'); 213 this.orientation = $us.$body.usMod('header'); 214 this.pos = this.$container.usMod('pos'); // 'fixed' / 'static' 215 this.bg = this.$container.usMod('bg'); // 'solid' / 'transparent' 216 this.shadow = this.$container.usMod('shadow'); // 'none' / 'thin' / 'wide' 217 218 // Will be used to count fullscreen sections heights and proper scroll positions 219 this.scrolledOccupiedHeight = 0; 220 221 this._events = { 222 scroll: this.scroll.bind(this), 223 resize: this.resize.bind(this), 224 contentChange: function(){ 225 this._countScrollable(); 226 }.bind(this), 227 hideMobileVerticalHeader: function(e){ 228 if ($.contains(this.$container[0], e.target)) return; 229 $us.$body 230 .off($.isMobile ? 'touchstart' : 'click', this._events.hideMobileVerticalHeader) 231 .removeClass('header-show'); 232 }.bind(this) 233 }; 234 this.$elms = {}; 235 this.$places = { 236 hidden: this.$container.find('.l-subheader.for_hidden') 237 }; 238 this.$container.find('.l-subheader-cell').each(function(index, cell){ 239 var $cell = $(cell); 240 this.$places[$cell.parent().parent().usMod('at') + '_' + $cell.usMod('at')] = $cell; 241 }.bind(this)); 242 var regexp = /(^| )ush_([a-z_]+)_([0-9]+)( |$)/; 243 this.$container.find('[class*=ush_]').each(function(index, elm){ 244 var $elm = $(elm), 245 matches = regexp.exec($elm.attr('class')); 246 if (!matches) return; 247 var id = matches[2] + ':' + matches[3]; 248 this.$elms[id] = $elm; 249 if ($elm.is('.w-vwrapper, .w-hwrapper')) { 250 this.$places[id] = $elm; 251 } 252 }.bind(this)); 253 // TODO Objects with the header elements 254 $us.$window.on('scroll', this._events.scroll); 255 $us.$window.on('resize load', this._events.resize); 256 this.resize(); 257 258 $us.$canvas.on('contentChange', function(){ 259 if (this.orientation == 'ver') this.docHeight = $us.$document.height(); 260 }.bind(this)); 261 262 this.$container.on('contentChange', this._events.contentChange); 263 264 this.$showBtn.on('click', function(e){ 265 if ($us.$body.hasClass('header-show')) return; 266 e.stopPropagation(); 267 $us.$body 268 .addClass('header-show') 269 .on($.isMobile ? 'touchstart' : 'click', this._events.hideMobileVerticalHeader); 270 }.bind(this)); 271 } 272 273 $.extend(USHeader.prototype, { 274 scroll: function(){ 275 var scrollTop = parseInt($us.$window.scrollTop()); 276 if (this.pos == 'fixed') { 277 if (this.orientation == 'hor') { 278 this.$container.toggleClass('sticky', scrollTop >= (this.settings[this.state].options.scroll_breakpoint || 100)); 279 } else if (this.$container.hasClass('scrollable') && this.docHeight > this.headerHeight + this.htmlTopMargin) { 280 var scrollRangeDiff = this.headerHeight - $us.canvas.winHeight + this.htmlTopMargin; 281 if (this._sidedHeaderScrollRange === undefined) { 282 this._sidedHeaderScrollRange = [0, scrollRangeDiff]; 283 } 284 if (scrollTop <= this._sidedHeaderScrollRange[0]) { 285 this._sidedHeaderScrollRange[0] = Math.max(0, scrollTop); 286 this._sidedHeaderScrollRange[1] = this._sidedHeaderScrollRange[0] + scrollRangeDiff; 287 this.$container.css({ 288 position: 'fixed', 289 top: this.htmlTopMargin 290 }); 291 } 292 else if (this._sidedHeaderScrollRange[0] < scrollTop && scrollTop < this._sidedHeaderScrollRange[1]) { 293 this.$container.css({ 294 position: 'absolute', 295 top: this._sidedHeaderScrollRange[0] 296 }); 297 } 298 else if (this._sidedHeaderScrollRange[1] <= scrollTop) { 299 this._sidedHeaderScrollRange[1] = Math.min(this.docHeight - $us.canvas.winHeight, scrollTop); 300 this._sidedHeaderScrollRange[0] = this._sidedHeaderScrollRange[1] - scrollRangeDiff; 301 this.$container.css({ 302 position: 'fixed', 303 top: $us.canvas.winHeight - this.headerHeight 304 }); 305 } 306 } 307 } 308 }, 309 resize: function(){ 310 var newState = 'default'; 311 if (window.innerWidth <= 900) newState = (window.innerWidth <= 600) ? 'mobiles' : 'tablets'; 312 this.setState(newState); 313 if (this.pos == 'fixed' && this.orientation == 'hor') { 314 var isSticky = this.$container.hasClass('sticky'); 315 this.$container.addClass('notransition'); 316 if (!isSticky) this.$container.addClass('sticky'); 317 this.scrolledOccupiedHeight = this.$container.height(); 318 if (!isSticky) this.$container.removeClass('sticky'); 319 // Removing with a small delay to prevent css glitch 320 setTimeout(function(){ 321 this.$container.removeClass('notransition'); 322 }.bind(this), 50); 323 } else /*if (this.orientation == 'ver' || this.pos == 'static')*/ { 324 this.scrolledOccupiedHeight = 0; 325 } 326 this._countScrollable(); 327 this.scroll(); 328 }, 329 setState: function(newState){ 330 if (newState == this.state) return; 331 var newOrientation = this.settings[newState].options.orientation || 'hor', 332 newPos = $us.toBool(this.settings[newState].options.sticky) ? 'fixed' : 'static', 333 newBg = $us.toBool(this.settings[newState].options.transparent) ? 'transparent' : 'solid', 334 newShadow = this.settings[newState].options.shadow || 'thin'; 335 if (newOrientation == 'ver') { 336 newPos = 'fixed'; 337 newBg = 'solid'; 338 } 339 this.state = newState; 340 // Don't change the order: orientation -> pos -> bg -> layout 341 this._setOrientation(newOrientation); 342 this._setPos(newPos); 343 this._setBg(newBg); 344 this._setShadow(newShadow); 345 this._setLayout(this.settings[newState].layout || {}); 346 $us.$body.usMod('state', newState); 347 if (newState == 'default') $us.$body.removeClass('header-show'); 348 // Updating the main menu because of dependencies 349 if ($us.nav !== undefined) $us.nav.resize(); 350 }, 351 _setOrientation: function(newOrientation){ 352 if (newOrientation == this.orientation) return; 353 $us.$body.usMod('header', newOrientation); 354 this.orientation = newOrientation; 355 }, 356 _countScrollable: function(){ 357 if (this.orientation == 'ver' && this.pos == 'fixed' && this.state == 'default') { 358 this.docHeight = $us.$document.height(); 359 this.htmlTopMargin = parseInt($us.$html.css('margin-top')); 360 this.headerHeight = this.$topCell.height() + this.$middleCell.height() + this.$bottomCell.height(); 361 if (this.headerHeight > $us.canvas.winHeight - this.htmlTopMargin) { 362 this.$container.addClass('scrollable'); 363 } else if (this.$container.hasClass('scrollable')) { 364 this.$container.removeClass('scrollable').resetInlineCSS('position', 'top', 'bottom'); 365 delete this._sidedHeaderScrollRange; 366 } 367 if (this.headerHeight + this.htmlTopMargin >= this.docHeight) { 368 this.$container.css({ 369 position: 'absolute', 370 top: 0 371 }); 372 } 373 } else if (this.$container.hasClass('scrollable')) { 374 this.$container.removeClass('scrollable').resetInlineCSS('position', 'top', 'bottom'); 375 delete this._sidedHeaderScrollRange; 376 } 377 }, 378 _setPos: function(newPos){ 379 if (newPos == this.pos) return; 380 this.$container.usMod('pos', newPos); 381 if (newPos == 'static') { 382 this.$container.removeClass('sticky'); 383 } 384 this.pos = newPos; 385 this._countScrollable(); 386 }, 387 _setBg: function(newBg){ 388 if (newBg == this.bg) return; 389 this.$container.usMod('bg', newBg); 390 this.bg = newBg; 391 }, 392 _setShadow: function(newShadow){ 393 if (newShadow == this.shadow) return; 394 this.$container.usMod('shadow', newShadow); 395 this.shadow = newShadow; 396 }, 397 /** 398 * Recursive function to place elements based on their ids 399 * @param {Array} elms 400 * @param {jQuery} $place 401 * @private 402 */ 403 _placeElements: function(elms, $place){ 404 for (var i = 0; i < elms.length; i++) { 405 var elmId; 406 if (typeof elms[i] == 'object') { 407 // Wrapper 408 elmId = elms[i][0]; 409 if (this.$places[elmId] === undefined || this.$elms[elmId] === undefined) continue; 410 this.$elms[elmId].appendTo($place); 411 this._placeElements(elms[i].shift(), this.$places[elmId]); 412 } else { 413 // Element 414 elmId = elms[i]; 415 if (this.$elms[elmId] === undefined) continue; 416 this.$elms[elmId].appendTo($place); 417 } 418 } 419 }, 420 _setLayout: function(newLayout){ 421 // Retrieving the currently shown layout structure 422 var curLayout = {}; 423 $.each(this.$places, function(place, $place){ 424 }.bind(this)); 425 for (var place in newLayout) { 426 if (!newLayout.hasOwnProperty(place) || this.$places[place] === undefined) continue; 427 this._placeElements(newLayout[place], this.$places[place]); 428 } 429 } 430 }); 431 $us.header = new USHeader($us.headerSettings || {}); 432}(jQuery); 433 434/** 435 * $us.nav 436 * 437 * Header navigation will all the possible states 438 * 439 * @requires $us.canvas 440 */ 441!function($){ 442 443 function USNav(){ 444 445 // Commonly used dom elements 446 this.$nav = $('.l-header .w-nav:first'); 447 if (this.$nav.length == 0) return; 448 this.$control = this.$nav.find('.w-nav-control'); 449 this.$items = this.$nav.find('.w-nav-item'); 450 this.$list = this.$nav.find('.w-nav-list.level_1'); 451 this.$subItems = this.$list.find('.w-nav-item.menu-item-has-children'); 452 this.$subAnchors = this.$list.find('.w-nav-item.menu-item-has-children > .w-nav-anchor'); 453 this.$subLists = this.$list.find('.w-nav-item.menu-item-has-children > .w-nav-list'); 454 this.$anchors = this.$nav.find('.w-nav-anchor'); 455 456 // Setting options 457 this.options = this.$nav.find('.w-nav-options:first')[0].onclick() || {}; 458 459 // In case the nav doesn't exist, do nothing 460 if (this.$nav.length == 0) return; 461 462 this.type = this.$nav.usMod('type'); 463 464 this.mobileOpened = false;
465 this.animationType = this.$nav.usMod('animation'); 466 var showFn = 'fadeInCSS', 467 hideFn = 'fadeOutCSS'; 468 if (this.animationType == 'height') { 469 showFn = 'slideDownCSS'; 470 hideFn = 'slideUpCSS'; 471 } 472 else if (this.animationType == 'mdesign') { 473 showFn = 'showMD'; 474 hideFn = 'hideMD'; 475 } 476 477 // Mobile menu toggler 478 this.$control.on('click', function(){ 479 this.mobileOpened = !this.mobileOpened; 480 if (this.mobileOpened) { 481 // Closing opened sublists 482 this.$items.filter('.opened').removeClass('opened'); 483 this.$subLists.resetInlineCSS('display', 'opacity', 'height', 'padding-top', 'padding-bottom', 'margin-top'); 484 this.$list.slideDownCSS(250, this._events.contentChanged); 485 } else { 486 this.$list.slideUpCSS(250, this._events.contentChanged); 487 } 488 }.bind(this)); 489 490 // Boundable events 491 this._events = { 492 // Mobile submenu togglers 493 toggle: function(e){ 494 if (this.type != 'mobile') return; 495 e.stopPropagation(); 496 e.preventDefault(); 497 var $item = $(e.currentTarget).closest('.w-nav-item'), 498 $sublist = $item.children('.w-nav-list'); 499 if ($item.hasClass('opened')) { 500 $item.removeClass('opened'); 501 $sublist.slideUpCSS(250, this._events.contentChanged); 502 } else { 503 $item.addClass('opened'); 504 $sublist.slideDownCSS(250, this._events.contentChanged); 505 } 506 }.bind(this), 507 resize: this.resize.bind(this), 508 contentChanged: function(){ 509 if (this.type == 'mobile' && $us.header.orientation == 'hor' && $us.canvas.headerPos == 'fixed') { 510 this.setFixedMobileMaxHeight(); 511 } 512 $us.header.$container.trigger('contentChange'); 513 }.bind(this) 514 }; 515 516 // Toggle on item clicks 517 if (this.options.mobileBehavior) { 518 this.$subAnchors.on('click', this._events.toggle); 519 } 520 // Toggle on arrows 521 else { 522 this.$list.find('.w-nav-item.menu-item-has-children > .w-nav-anchor > .w-nav-arrow').on('click', this._events.toggle); 523 } 524 // Mark all the togglable items 525 this.$subItems.each(function(){ 526 var $this = $(this), 527 $parentItem = $this.parent().closest('.w-nav-item'); 528 if ($parentItem.length == 0 || $parentItem.usMod('columns') === false) $this.addClass('togglable'); 529 }); 530 // Touch device handling in default (notouch) layout 531 if (!$us.$html.hasClass('no-touch')) { 532 this.$list.find('.w-nav-item.menu-item-has-children.togglable > .w-nav-anchor').on('click', function(e){ 533 if (this.type == 'mobile') return; 534 e.preventDefault(); 535 var $this = $(e.currentTarget), 536 $item = $this.parent(), 537 $list = $item.children('.w-nav-list'); 538 539 // Second tap: going to the URL 540 if ($item.hasClass('opened')) return location.assign($this.attr('href')); 541 $list[showFn](); 542 $item.addClass('opened'); 543 var outsideClickEvent = function(e){ 544 if ($.contains($item[0], e.target)) return; 545 $item.removeClass('opened'); 546 $list[hideFn](); 547 $us.$body.off('touchstart', outsideClickEvent); 548 }; 549 550 $us.$body.on('touchstart', outsideClickEvent); 551 }.bind(this)); 552 } 553 // Desktop device hovers 554 else { 555 this.$subItems 556 .filter('.togglable') 557 .on('mouseenter', function(e){ 558 if (this.type == 'mobile') return; 559 var $list = $(e.currentTarget).children('.w-nav-list'); 560 $list[showFn](); 561 }.bind(this)) 562 .on('mouseleave', function(e){ 563 if (this.type == 'mobile') return; 564 var $list = $(e.currentTarget).children('.w-nav-list'); 565 $list[hideFn](); 566 }.bind(this)); 567 } 568 // Close menu on anchor clicks 569 this.$anchors.on('click', function(e){ 570 if (this.type != 'mobile' || $us.header.orientation != 'hor') return; 571 // Toggled the item 572 if (this.options.mobileBehavior && $(e.currentTarget).closest('.w-nav-item').hasClass('menu-item-has-children')) return; 573 this.$list.slideUpCSS(); 574 this.mobileOpened = false; 575 }.bind(this)); 576 577 $us.$window.on('resize', this._events.resize); 578 setTimeout(function(){ 579 this.resize(); 580 $us.header.$container.trigger('contentChange'); 581 }.bind(this), 50); 582 } 583 584 USNav.prototype = { 585 586 /** 587 * Count proper dimensions 588 */ 589 setFixedMobileMaxHeight: function(){ 590 var listTop = Math.min(this.$list.position().top, $us.header.scrolledOccupiedHeight); 591 this.$list.css('max-height', $us.canvas.winHeight - listTop + 'px'); 592 }, 593 594 /** 595 * Resize handler 596 */ 597 resize: function(){ 598 if (this.$nav.length == 0) return; 599 var nextType = (window.innerWidth <= this.options.mobileWidth) ? 'mobile' : 'desktop'; 600 if ($us.header.orientation != this.headerOrientation || nextType != this.type) { 601 // Clearing the previous state 602 this.$subLists.resetInlineCSS('display', 'opacity', 'height', 'padding-top', 'padding-bottom', 'margin-top'); 603 if (this.headerOrientation == 'hor' && this.type == 'mobile') { 604 this.$list.resetInlineCSS('height', 'max-height', 'display', 'opacity', 'padding-top', 'padding-bottom'); 605 } 606 // Closing opened sublists 607 this.$items.removeClass('opened'); 608 // Applying the new state 609 if ($us.header.orientation == 'hor') { 610 if (nextType == 'desktop') { 611 this.$items.filter('.togglable').children('.w-nav-list').css('display', 'none'); 612 } else if (nextType == 'mobile') { 613 this.mobileOpened = false;
614 this.$list.css('height', 0); 615 this.$subLists.css('height', 0); 616 } 617 } 618 this.headerOrientation = $us.header.orientation; 619 this.type = nextType; 620 this.$nav.usMod('type', nextType); 621 } 622 // Max-height limitation for fixed header layouts 623 if ($us.header.orientation == 'hor' && this.type == 'mobile' && $us.canvas.headerPos == 'fixed') this.setFixedMobileMaxHeight(); 624 this.$list.removeClass('hidden'); 625 } 626 }; 627 628 $us.nav = new USNav(); 629 630}(jQuery); 631 632 633/** 634 * $us.scroll 635 * 636 * ScrollSpy, Smooth scroll links and hash-based scrolling all-in-one 637 * 638 * @requires $us.canvas 639 */ 640!function($){ 641 "use strict"; 642 643 function USScroll(options){ 644 645 // Setting options 646 var defaults = { 647 /** 648 * @param {String|jQuery} Selector or object of hash scroll anchors that should be attached on init 649 */ 650 attachOnInit: '.w-nav a[href*="#"], .w-menu a[href*="#"], a.w-btn[href*="#"], .w-iconbox a[href*="#"], .w-image a[href*="#"], .w-img a[href*="#"], .w-text a[href*="#"], ' + 651 '.vc_icon_element a[href*="#"], .vc_custom_heading a[href*="#"], a.w-portfolio-item-anchor[href*="#"], .widget_nav_menu a[href*="#"], .w-toplink, ' + 652 '.w-blog-post-meta-comments a[href*="#"], .w-comments-title a[href*="#"], .w-comments-item-date, a.smooth-scroll[href*="#"]', 653 /** 654 * @param {String} Classname that will be toggled on relevant buttons 655 */ 656 buttonActiveClass: 'active', 657 /** 658 * @param {String} Classname that will be toggled on relevant menu items 659 */ 660 menuItemActiveClass: 'current-menu-item', 661 /** 662 * @param {String} Classname that will be toggled on relevant menu ancestors 663 */ 664 menuItemAncestorActiveClass: 'current-menu-ancestor', 665 /** 666 * @param {Number} Duration of scroll animation 667 */ 668 animationDuration: 1200, 669 /** 670 * @param {String} Easing for scroll animation 671 */ 672 animationEasing: 'easeInOutQuint' 673 }; 674 this.options = $.extend({}, defaults, options || {}); 675 676 // Hash blocks with targets and activity indicators 677 this.blocks = {}; 678 679 // Is scrolling to some specific block at the moment? 680 this.isScrolling = false; 681 682 // Waypoints that will be called at certain scroll position 683 this.waypoints = []; 684 685 // Boundable events 686 this._events = { 687 cancel: this.cancel.bind(this), 688 scroll: this.scroll.bind(this), 689 resize: this.resize.bind(this) 690 }; 691 692 this._canvasTopOffset = 0; 693 $us.$window.on('resize load', this._events.resize); 694 setTimeout(this._events.resize, 75); 695 696 $us.$window.on('scroll', this._events.scroll); 697 setTimeout(this._events.scroll, 75); 698 699 if (this.options.attachOnInit) { 700 this.attach(this.options.attachOnInit); 701 } 702 703 // Recount scroll positions on any content changes 704 $us.$canvas.on('contentChange', this._countAllPositions.bind(this)); 705 706 // Handling initial document hash 707 if (document.location.hash && document.location.hash.indexOf('#!') == -1) { 708 var hash = document.location.hash, 709 scrollPlace = (this.blocks[hash] !== undefined) ? hash : undefined; 710 if (scrollPlace === undefined) { 711 try { 712 var $target = $(hash); 713 if ($target.length != 0) { 714 scrollPlace = $target; 715 } 716 } catch (error) { 717 //Do not have to do anything here since scrollPlace is already undefined 718 } 719 720 } 721 if (scrollPlace !== undefined) { 722 // While page loads, its content changes, and we'll keep the proper scroll on each sufficient content change 723 // until the page finishes loading or user scrolls the page manually 724 var keepScrollPositionTimer = setInterval(function(){ 725 this.scrollTo(scrollPlace); 726 }.bind(this), 100); 727 var clearHashEvents = function(){ 728 // Content size still may change via other script right after page load 729 setTimeout(function(){ 730 clearInterval(keepScrollPositionTimer); 731 $us.canvas.resize(); 732 this._countAllPositions(); 733 this.scrollTo(scrollPlace); 734 }.bind(this), 100); 735 $us.$window.off('load touchstart mousewheel DOMMouseScroll touchstart', clearHashEvents); 736 }.bind(this); 737 $us.$window.on('load touchstart mousewheel DOMMouseScroll touchstart', clearHashEvents); 738 } 739 } 740 } 741 742 USScroll.prototype = { 743 744 /** 745 * Count hash's target position and store it properly 746 * 747 * @param {String} hash 748 * @private 749 */ 750 _countPosition: function(hash){ 751 this.blocks[hash].top = Math.ceil(this.blocks[hash].target.offset().top - $us.header.scrolledOccupiedHeight - this._canvasTopOffset); 752 this.blocks[hash].bottom = this.blocks[hash].top + this.blocks[hash].target.outerHeight(false); 753 }, 754 755 /** 756 * Count all targets' positions for proper scrolling 757 * 758 * @private 759 */ 760 _countAllPositions: function(){ 761 // Take into account #wpadminbar (and others possible) offset 762 this._canvasTopOffset = $us.$canvas.offset().top; 763 for (var hash in this.blocks) { 764 if (!this.blocks.hasOwnProperty(hash)) continue; 765 this._countPosition(hash); 766 } 767 // Counting waypoints 768 for (var i = 0; i < this.waypoints.length; i++) { 769 this._countWaypoint(this.waypoints[i]); 770 } 771 }, 772 773 /** 774 * Indicate scroll position by hash 775 * 776 * @param {String} activeHash 777 * @private 778 */ 779 _indicatePosition: function(activeHash){ 780 var activeMenuAncestors = []; 781 for (var hash in this.blocks) { 782 if (!this.blocks.hasOwnProperty(hash)) continue; 783 if (this.blocks[hash].buttons !== undefined) { 784 this.blocks[hash].buttons.toggleClass(this.options.buttonActiveClass, hash === activeHash); 785 } 786 if (this.blocks[hash].menuItems !== undefined) { 787 this.blocks[hash].menuItems.toggleClass(this.options.menuItemActiveClass, hash === activeHash); 788 } 789 if (this.blocks[hash].menuAncestors !== undefined) { 790 this.blocks[hash].menuAncestors.removeClass(this.options.menuItemAncestorActiveClass); 791 } 792 } 793 if (this.blocks[activeHash] !== undefined && this.blocks[activeHash].menuAncestors !== undefined) { 794 this.blocks[activeHash].menuAncestors.addClass(this.options.menuItemAncestorActiveClass); 795 } 796 }, 797 798 /** 799 * Attach anchors so their targets will be listened for possible scrolls 800 * 801 * @param {String|jQuery} anchors Selector or list of anchors to attach 802 */ 803 attach: function(anchors){ 804 // Location pattern to check absolute URLs for current location 805 var locationPattern = new RegExp('^' + location.pathname.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + '#'); 806 807 var $anchors = $(anchors); 808 if ($anchors.length == 0) return; 809 $anchors.each(function(index, anchor){ 810 var $anchor = $(anchor), 811 href = $anchor.attr('href'), 812 hash = $anchor.prop('hash'); 813 // Ignoring ajax links 814 if (hash.indexOf('#!') != -1) return; 815 // Checking if the hash is connected with the current page 816 if (!( 817 // Link type: #something 818 href.charAt(0) == '#' || 819 // Link type: /#something 820 (href.charAt(0) == '/' && locationPattern.test(href)) || 821 // Link type: http://example.com/some/path/#something 822 href.indexOf(location.host + location.pathname + '#') > -1 823 )) return; 824 // Do we have an actual target, for which we'll need to count geometry? 825 if (hash != '' && hash != '#') { 826 // Attach target 827 if (this.blocks[hash] === undefined) { 828 var $target = $(hash); 829 // Don't attach anchors that actually have no target 830 if ($target.length == 0) return; 831 // If it's the only row in a section, than use section instead 832 if ($target.hasClass('g-cols') && $target.parent().children().length == 1) { 833 $target = $target.closest('.l-section'); 834 } 835 this.blocks[hash] = { 836 target: $target 837 }; 838 this._countPosition(hash); 839 } 840 // Attach activity indicator 841 if ($anchor.hasClass('w-nav-anchor')) { 842 var $menuIndicator = $anchor.closest('.w-nav-item'); 843 this.blocks[hash].menuItems = (this.blocks[hash].menuItems || $()).add($menuIndicator); 844 var $menuAncestors = $menuIndicator.parents('.menu-item-has-children'); 845 if ($menuAncestors.length > 0) { 846 this.blocks[hash].menuAncestors = (this.blocks[hash].menuAncestors || $()).add($menuAncestors); 847 } 848 } 849 else { 850 this.blocks[hash].buttons = (this.blocks[hash].buttons || $()).add($anchor); 851 } 852 } 853 $anchor.on('click', function(event){ 854 event.preventDefault(); 855 this.scrollTo(hash, true); 856 }.bind(this)); 857 }.bind(this)); 858 }, 859 860 /** 861 * Scroll page to a certain position or hash 862 * 863 * @param {Number|String|jQuery} place 864 * @param {Boolean} animate 865 */ 866 scrollTo: function(place, animate){ 867 var placeType, 868 newY; 869 // Scroll to top 870 if (place == '' || place == '#') { 871 newY = 0; 872 placeType = 'top'; 873 } 874 // Scroll by hash 875 else if (this.blocks[place] !== undefined) { 876 newY = this.blocks[place].top; 877 placeType = 'hash'; 878 } 879 else if (place instanceof $) { 880 newY = Math.floor(place.offset().top - $us.header.scrolledOccupiedHeight - this._canvasTopOffset); 881 placeType = 'element'; 882 } 883 else { 884 newY = Math.floor(place - $us.header.scrolledOccupiedHeight - this._canvasTopOffset); 885 } 886 var indicateActive = function(){ 887 if (placeType == 'hash') { 888 this._indicatePosition(place); 889 } 890 else { 891 this.scroll(); 892 } 893 }.bind(this); 894 if (animate) { 895 this.isScrolling = true; 896 $us.$htmlBody.stop(true, false).animate({ 897 scrollTop: newY + 'px' 898 }, { 899 duration: this.options.animationDuration, 900 easing: this.options.animationEasing, 901 always: function(){ 902 $us.$window.off('keydown mousewheel DOMMouseScroll touchstart', this._events.cancel); 903 this.isScrolling = false;
904 indicateActive(); 905 }.bind(this) 906 }); 907 // Allow user to stop scrolling manually 908 $us.$window.on('keydown mousewheel DOMMouseScroll touchstart', this._events.cancel); 909 } 910 else { 911 $us.$htmlBody.stop(true, false).scrollTop(newY); 912 indicateActive(); 913 } 914 }, 915 916 /** 917 * Cancel scroll 918 */ 919 cancel: function(){ 920 $us.$htmlBody.stop(true, false); 921 }, 922 923 /** 924 * Add new waypoint 925 * 926 * @param {jQuery} $elm object with the element 927 * @param {mixed} offset Offset from bottom of screen in pixels ('100') or percents ('20%') 928 * @param {Function} fn The function that will be called 929 */ 930 addWaypoint: function($elm, offset, fn){ 931 $elm = ($elm instanceof $) ? $elm : $($elm); 932 if ($elm.length == 0) return; 933 if (typeof offset != 'string' || offset.indexOf('%') == -1) { 934 // Not percent: using pixels 935 offset = parseInt(offset); 936 } 937 var waypoint = { 938 $elm: $elm, 939 offset: offset, 940 fn: fn 941 }; 942 this._countWaypoint(waypoint); 943 this.waypoints.push(waypoint); 944 }, 945 946 /** 947 * 948 * @param {Object} waypoint 949 * @private 950 */ 951 _countWaypoint: function(waypoint){ 952 var elmTop = waypoint.$elm.offset().top, 953 winHeight = $us.$window.height(); 954 if (typeof waypoint.offset == 'number') { 955 // Offset is defined in pixels 956 waypoint.scrollPos = elmTop - winHeight + waypoint.offset; 957 } else { 958 // Offset is defined in percents 959 waypoint.scrollPos = elmTop - winHeight + winHeight * parseInt(waypoint.offset) / 100; 960 } 961 }, 962 963 /** 964 * Scroll handler 965 */ 966 scroll: function(){ 967 var scrollTop = parseInt($us.$window.scrollTop()); 968 if (!this.isScrolling) { 969 var activeHash; 970 for (var hash in this.blocks) { 971 if (!this.blocks.hasOwnProperty(hash)) continue; 972 if (scrollTop >= this.blocks[hash].top && scrollTop < this.blocks[hash].bottom) { 973 activeHash = hash; 974 break; 975 } 976 } 977 this._indicatePosition(activeHash); 978 } 979 // Handling waypoints 980 for (var i = 0; i < this.waypoints.length; i++) { 981 if (this.waypoints[i].scrollPos < scrollTop) { 982 this.waypoints[i].fn(this.waypoints[i].$elm); 983 this.waypoints.splice(i, 1); 984 i--; 985 } 986 } 987 }, 988 989 /** 990 * Resize handler 991 */ 992 resize: function(){ 993 // Delaying the resize event to prevent glitches 994 setTimeout(function(){ 995 this._countAllPositions(); 996 this.scroll(); 997 }.bind(this), 150); 998 this._countAllPositions(); 999 this.scroll(); 1000 } 1001 }; 1002 1003 $(function(){ 1004 $us.scroll = new USScroll($us.scrollOptions || {}); 1005 }); 1006 1007}(jQuery); 1008 1009 1010jQuery(function($){ 1011 "use strict"; 1012 1013 // TODO Move all of the below to us.widgets 1014 if ($.fn.magnificPopup) { 1015 1016 $('.product .images').magnificPopup({ 1017 type: 'image', 1018 delegate: 'a.with-lightbox', 1019 gallery: { 1020 enabled: true, 1021 navigateByImgClick: true, 1022 preload: [0, 1], 1023 tPrev: $us.langOptions.magnificPopup.tPrev, // Alt text on left arrow 1024 tNext: $us.langOptions.magnificPopup.tNext, // Alt text on right arrow 1025 tCounter: $us.langOptions.magnificPopup.tCounter // Markup for "1 of 7" counter 1026 }, 1027 removalDelay: 300, 1028 mainClass: 'mfp-fade', 1029 fixedContentPos: false 1030 1031 }); 1032 1033 $('a[ref=magnificPopup][class!=direct-link]').magnificPopup({ 1034 type: 'image', 1035 fixedContentPos: false 1036 }); 1037 } 1038 1039 if ($.fn.revolution) { 1040 $('.fullwidthbanner').revolution({ 1041 delay: 9000, 1042 startwidth: 1140, 1043 startheight: 500, 1044 soloArrowLeftHOffset: 20, 1045 soloArrowLeftVOffset: 0, 1046 soloArrowRightHOffset: 20, 1047 soloArrowRightVOffset: 0, 1048 onHoverStop: "on", // Stop Banner Timet at Hover on Slide on/off 1049 fullWidth: "on", 1050 hideThumbs: false, 1051 shadow: 0 //0 = no Shadow, 1,2,3 = 3 Different Art of Shadows - (No Shadow in Fullwidth Version !) 1052 }); 1053 // Redrawing all the Revolution Sliders 1054 if (window.revapi3 !== undefined && window.revapi3.revredraw !== undefined) { 1055 $us.$window.on('resize', function(){ 1056 window.revapi3.revredraw(); 1057 }); 1058 } 1059 } 1060 1061 $('.animate_fade, .animate_afc, .animate_afl, .animate_afr, .animate_aft, .animate_afb, .animate_wfc, ' + 1062 '.animate_hfc, .animate_rfc, .animate_rfl, .animate_rfr').each(function(){ 1063 $us.scroll.addWaypoint($(this), '15%', function($elm){ 1064 if (!$elm.hasClass('animate_start')) { 1065 setTimeout(function(){ 1066 $elm.addClass('animate_start'); 1067 }, 20); 1068 } 1069 }); 1070 }); 1071 $('.wpb_animate_when_almost_visible').each(function(){ 1072 $us.scroll.addWaypoint($(this), '15%', function($elm){ 1073 if (!$elm.hasClass('wpb_start_animation')) { 1074 setTimeout(function(){ 1075 $elm.addClass('wpb_start_animation'); 1076 }, 20); 1077 } 1078 }); 1079 }); 1080
1081 var $submainVideos = $('.l-section-video'); 1082 var updateVideosSizes = function(){ 1083 $submainVideos.each(function(){ 1084 var $this = $(this), 1085 $video = $this.find('video'), 1086 player = $video.data('mediaelementplayer'); 1087 // Hiding videos on small (some mobiles) resolutions 1088 if ($us.canvas.winWidth <= 1024) { 1089 if (player && player.pause && !player.media.paused) { 1090 player.pause(); 1091 } 1092 return $this.hide(); 1093 } 1094 var mejsContainer = $this.find('.mejs-container'), 1095 poster = $this.find('.mejs-mediaelement img'), 1096 videoWidth = $video.attr('width'), 1097 videoHeight = $video.attr('height'), 1098 videoProportion = videoWidth / videoHeight, 1099 parent = $this.parent(), 1100 parentWidth = parent.outerWidth(), 1101 parentHeight = parent.outerHeight(), 1102 proportion, 1103 centerX, centerY; 1104 if (mejsContainer.length == 0) return; 1105 1106 // Proper sizing 1107// if (video.length > 0 && video[0].player && video[0].player.media) videoWidth = video[0].player.media.videoWidth; 1108// if (video.length > 0 && video[0].player && video[0].player.media) videoHeight = video[0].player.media.videoHeight; 1109 if (player && player.play && player.media.paused) { 1110 player.play(); 1111 } 1112 $this.show(); 1113 parent.find('span.mejs-offscreen').hide(); 1114 1115 proportion = (parentWidth / parentHeight > videoWidth / videoHeight) ? parentWidth / videoWidth : parentHeight / videoHeight; 1116 $this.width(proportion * videoWidth); 1117 $this.height(proportion * videoHeight); 1118 1119 poster.width(proportion * videoWidth); 1120 poster.height(proportion * videoHeight); 1121 1122 centerX = (parentWidth < videoWidth * proportion) ? (parentWidth - videoWidth * proportion) / 2 : 0; 1123 centerY = (parentHeight < videoHeight * proportion) ? (parentHeight - videoHeight * proportion) / 2 : 0; 1124 1125 $this.css({left: centerX, top: centerY}); 1126 1127 mejsContainer.css({width: '100%', height: '100%'}); 1128 $video.css({'object-fit': 'cover', display: 'inline-block'}); 1129 }); 1130 }; 1131 if (window.MediaElementPlayer) { 1132 $('.l-section-video video').mediaelementplayer({ 1133 enableKeyboard: false, 1134 iPadUseNativeControls: false, 1135 pauseOtherPlayers: false, 1136 iPhoneUseNativeControls: false, 1137 AndroidUseNativeControls: false, 1138 videoWidth: '100%', 1139 videoHeight: '100%', 1140 success: function(mediaElement, domObject){ 1141 $(domObject).css('display', 'block'); 1142 updateVideosSizes(); 1143 } 1144 }); 1145 setTimeout(updateVideosSizes, 75); 1146 $us.$window.on('resize load', updateVideosSizes); 1147 } 1148 1149 jQuery('input[type="text"], input[type="email"], textarea').each(function(index, input){ 1150 var $input = $(input), 1151 $row = $input.closest('.w-form-row'); 1152 if ($input.attr('type') == 'hidden') return; 1153 $row.toggleClass('not-empty', $input.val() != ''); 1154 $input.on('input', function(){ 1155 $row.toggleClass('not-empty', $input.val() != ''); 1156 }); 1157 }); 1158 1159 jQuery('.l-section-img, .l-titlebar-img').each(function(){ 1160 var $this = $(this), 1161 img = new Image(); 1162 1163 img.onload = function(){ 1164 if (!$this.hasClass('loaded')) { 1165 $this.addClass('loaded') 1166 } 1167 }; 1168 1169 img.src = ($this.css('background-image') || '').replace(/url\(['"]*(.*?)['"]*\)/g, '$1'); 1170 }); 1171 1172 /* Ultimate Addons for Visual Composer integration */ 1173 jQuery('.upb_bg_img, .upb_color, .upb_grad, .upb_content_iframe, .upb_content_video, .upb_no_bg').each(function(){ 1174 var $bg = jQuery(this), 1175 $prev = $bg.prev(); 1176 1177 if ($prev.length == 0) { 1178 var $parent = $bg.parent(), 1179 $parentParent = $parent.parent(), 1180 $prevParentParent = $parentParent.prev(); 1181 1182 if ($prevParentParent.length) { 1183 $bg.insertAfter($prevParentParent); 1184 1185 if ($parent.children().length == 0) { 1186 $parentParent.remove(); 1187 } 1188 } 1189 } 1190 }); 1191 $('.g-cols > .ult-item-wrap').each(function(index, elm){ 1192 var $elm = jQuery(elm); 1193 $elm.replaceWith($elm.children()); 1194 }); 1195 jQuery('.overlay-show').click(function(){ 1196 window.setTimeout(function(){ 1197 $us.$canvas.trigger('contentChange'); 1198 }, 1000); 1199 }); 1200 1201}); 1202 1203/** 1204 * CSS-analog of jQuery slideDown/slideUp/fadeIn/fadeOut functions (for better rendering) 1205 */ 1206!function(){ 1207 1208 /** 1209 * Remove the passed inline CSS attributes. 1210 * 1211 * Usage: $elm.resetInlineCSS('height', 'width'); 1212 */ 1213 jQuery.fn.resetInlineCSS = function(){ 1214 for (var index = 0; index < arguments.length; index++) { 1215 this.css(arguments[index], ''); 1216 } 1217 return this; 1218 }; 1219 1220 jQuery.fn.clearPreviousTransitions = function(){ 1221 // Stopping previous events, if there were any 1222 var prevTimers = (this.data('animation-timers') || '').split(','); 1223 if (prevTimers.length >= 2) { 1224 this.resetInlineCSS('transition', '-webkit-transition'); 1225 prevTimers.map(clearTimeout); 1226 this.removeData('animation-timers'); 1227 } 1228 return this; 1229 }; 1230 /** 1231 * 1232 * @param {Object} css key-value pairs of animated css 1233 * @param {Number} duration in milliseconds 1234 * @param {Function} onFinish 1235 * @param {String} easing CSS easing name 1236 * @param {Number} delay in milliseconds 1237 */ 1238 jQuery.fn.performCSSTransition = function(css, duration, onFinish, easing, delay){ 1239 duration = duration || 250; 1240 delay = delay || 25; 1241 easing = easing || 'ease-in-out'; 1242 var $this = this, 1243 transition = []; 1244 1245 this.clearPreviousTransitions(); 1246 1247 for (var attr in css) { 1248 if (!css.hasOwnProperty(attr)) continue; 1249 transition.push(attr + ' ' + (duration / 1000) + 's ' + easing); 1250 } 1251 transition = transition.join(', '); 1252 $this.css({ 1253 transition: transition, 1254 '-webkit-transition': transition 1255 }); 1256 1257 // Starting the transition with a slight delay for the proper application of CSS transition properties 1258 var timer1 = setTimeout(function(){ 1259 $this.css(css); 1260 }, delay); 1261 1262 var timer2 = setTimeout(function(){ 1263 $this.resetInlineCSS('transition', '-webkit-transition'); 1264 if (typeof onFinish == 'function') onFinish(); 1265 }, duration + delay); 1266 1267 this.data('animation-timers', timer1 + ',' + timer2); 1268 }; 1269 // Height animations 1270 jQuery.fn.slideDownCSS = function(duration, onFinish, easing, delay){ 1271 if (this.length == 0) return; 1272 var $this = this; 1273 this.clearPreviousTransitions(); 1274 // Grabbing paddings 1275 this.resetInlineCSS('padding-top', 'padding-bottom'); 1276 var timer1 = setTimeout(function(){ 1277 var paddingTop = parseInt($this.css('padding-top')), 1278 paddingBottom = parseInt($this.css('padding-bottom')); 1279 // Grabbing the "auto" height in px 1280 $this.css({ 1281 visibility: 'hidden', 1282 position: 'absolute', 1283 height: 'auto', 1284 'padding-top': 0, 1285 'padding-bottom': 0, 1286 display: 'block' 1287 }); 1288 var height = $this.height(); 1289 $this.css({ 1290 overflow: 'hidden', 1291 height: '0px', 1292 visibility: '', 1293 position: '', 1294 opacity: 0 1295 }); 1296 $this.performCSSTransition({ 1297 height: height + paddingTop + paddingBottom, 1298 opacity: 1, 1299 'padding-top': paddingTop, 1300 'padding-bottom': paddingBottom 1301 }, duration, function(){ 1302 $this.resetInlineCSS('overflow').css('height', 'auto'); 1303 if (typeof onFinish == 'function') onFinish(); 1304 }, easing, delay); 1305 }, 25); 1306 this.data('animation-timers', timer1 + ',null'); 1307 }; 1308 jQuery.fn.slideUpCSS = function(duration, onFinish, easing, delay){ 1309 if (this.length == 0) return; 1310 this.clearPreviousTransitions(); 1311 this.css({ 1312 height: this.outerHeight(), 1313 overflow: 'hidden', 1314 'padding-top': this.css('padding-top'), 1315 'padding-bottom': this.css('padding-bottom'), 1316 opacity: 1 1317 }); 1318 var $this = this; 1319 this.performCSSTransition({ 1320 height: 0, 1321 'padding-top': 0, 1322 'padding-bottom': 0, 1323 opacity: 0 1324 }, duration, function(){ 1325 $this.resetInlineCSS('overflow', 'padding-top', 'padding-bottom', 'opacity').css({ 1326 display: 'none' 1327 }); 1328 if (typeof onFinish == 'function') onFinish(); 1329 }, easing, delay); 1330 }; 1331 // Opacity animations 1332 jQuery.fn.fadeInCSS = function(duration, onFinish, easing, delay){ 1333 if (this.length == 0) return; 1334 this.clearPreviousTransitions(); 1335 this.css({ 1336 opacity: 0, 1337 display: 'block' 1338 }); 1339 this.performCSSTransition({ 1340 opacity: 1 1341 }, duration, onFinish, easing, delay); 1342 }; 1343 jQuery.fn.fadeOutCSS = function(duration, onFinish, easing, delay){ 1344 if (this.length == 0) return; 1345 var $this = this; 1346 this.performCSSTransition({ 1347 opacity: 0 1348 }, duration, function(){ 1349 $this.css('display', 'none'); 1350 if (typeof onFinish == 'function') onFinish(); 1351 }, easing, delay); 1352 }; 1353 // Material design animations 1354 jQuery.fn.showMD = function(duration, onFinish, easing, delay){ 1355 if (this.length == 0) return; 1356 this.clearPreviousTransitions(); 1357 // Grabbing paddings 1358 this.resetInlineCSS('padding-top', 'padding-bottom'); 1359 var paddingTop = parseInt(this.css('padding-top')), 1360 paddingBottom = parseInt(this.css('padding-bottom')); 1361 // Grabbing the "auto" height in px 1362 this.css({ 1363 visibility: 'hidden', 1364 position: 'absolute', 1365 height: 'auto', 1366 'padding-top': 0, 1367 'padding-bottom': 0, 1368 'margin-top': -20, 1369 opacity: '', 1370 display: 'block' 1371 }); 1372 var height = this.height(); 1373 this.css({ 1374 overflow: 'hidden', 1375 height: '0px' 1376 }).resetInlineCSS('visibility', 'position'); 1377 var $this = this; 1378 this.performCSSTransition({ 1379 height: height + paddingTop + paddingBottom, 1380 'margin-top': 0, 1381 'padding-top': paddingTop, 1382 'padding-bottom': paddingBottom 1383 }, duration || 350, function(){ 1384 $this.resetInlineCSS('overflow', 'margin-top', 'padding-top', 'padding-bottom').css('height', 'auto'); 1385 if (typeof onFinish == 'function') onFinish(); 1386 }, easing || 'cubic-bezier(.23,1,.32,1)', delay || 150); 1387 }; 1388 jQuery.fn.hideMD = function(duration, onFinish, easing, delay){ 1389 if (this.length == 0) return; 1390 this.clearPreviousTransitions(); 1391 var $this = this; 1392 this.resetInlineCSS('margin-top'); 1393 this.performCSSTransition({ 1394 opacity: 0 1395 }, duration || 100, function(){ 1396 $this.css({ 1397 display: 'none' 1398 }).resetInlineCSS('opacity'); 1399 if (typeof onFinish == 'function') onFinish(); 1400 }, easing, delay); 1401 }; 1402 // Slide element left / right 1403 var slideIn = function($this, from){ 1404 if ($this.length == 0) return; 1405 $this.clearPreviousTransitions(); 1406 $this.css({width: 'auto', height: 'auto'}); 1407 var width = $this.width(), 1408 height = $this.height(); 1409 $this.css({ 1410 width: width, 1411 height: height, 1412 position: 'relative', 1413 left: (from == 'right') ? '100%' : '-100%', 1414 opacity: 0, 1415 display: 'block' 1416 }); 1417 $this.performCSSTransition({ 1418 left: '0%', 1419 opacity: 1 1420 }, arguments[0] || 250, function(){ 1421 $this.resetInlineCSS('position', 'left', 'opacity', 'display').css({width: 'auto', height: 'auto'}); 1422 }); 1423 }, 1424 slideOut = function($this, to){ 1425 if ($this.length == 0) return; 1426 $this.clearPreviousTransitions(); 1427 $this.css({ 1428 position: 'relative', 1429 left: 0, 1430 opacity: 1 1431 }); 1432 $this.performCSSTransition({ 1433 left: (to == 'left') ? '-100%' : '100%', 1434 opacity: 0 1435 }, arguments[0] || 250, function(){ 1436 $this.css({ 1437 display: 'none' 1438 }).resetInlineCSS('position', 'left', 'opacity'); 1439 }); 1440 }; 1441 jQuery.fn.slideOutLeft = function(){ 1442 slideOut(this, 'left'); 1443 }; 1444 jQuery.fn.slideOutRight = function(){ 1445 slideOut(this, 'right'); 1446 }; 1447 jQuery.fn.slideInLeft = function(){ 1448 slideIn(this, 'left'); 1449 }; 1450 jQuery.fn.slideInRight = function(){ 1451 slideIn(this, 'right'); 1452 }; 1453}();
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.