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