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