1(function($) {// v5 namespace 2var MK = { 3 api : {}, 4 ui : {}, 5 component : {}, 6}; 7 8// Global 9window.MK = MK; 10'use strict'; 11 12 13console.log( 23423 ); 14/** 15 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level 16 * directory of this distribution and at 17 * https://github.com/marcj/css-element-queries/blob/master/LICENSE. 18 */ 19(function (root, factory) { 20 if (typeof define === "function" && define.amd) { 21 define(factory); 22 } else if (typeof exports === "object") { 23 module.exports = factory(); 24 } else { 25 root.ResizeSensor = factory(); 26 } 27}(typeof window !== 'undefined' ? window : this, function () { 28 29 // Make sure it does not throw in a SSR (Server Side Rendering) situation 30 if (typeof window === "undefined") { 31 return null; 32 } 33 // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor. 34 // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and 35 // would generate too many unnecessary events. 36 var requestAnimationFrame = window.requestAnimationFrame || 37 window.mozRequestAnimationFrame || 38 window.webkitRequestAnimationFrame || 39 function (fn) { 40 return window.setTimeout(fn, 20); 41 }; 42 43 /** 44 * Iterate over each of the provided element(s). 45 * 46 * @param {HTMLElement|HTMLElement[]} elements 47 * @param {Function} callback 48 */ 49 function forEachElement(elements, callback){ 50 var elementsType = Object.prototype.toString.call(elements); 51 var isCollectionTyped = ('[object Array]' === elementsType 52 || ('[object NodeList]' === elementsType) 53 || ('[object HTMLCollection]' === elementsType) 54 || ('[object Object]' === elementsType) 55 || ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery 56 || ('undefined' !== typeof Elements && elements instanceof Elements) //mootools 57 ); 58 var i = 0, j = elements.length; 59 if (isCollectionTyped) { 60 for (; i < j; i++) { 61 callback(elements[i]); 62 } 63 } else { 64 callback(elements); 65 } 66 } 67 68 /** 69 * Get element size 70 * @param {HTMLElement} element 71 * @returns {Object} {width, height} 72 */ 73 function getElementSize(element) { 74 if (!element.getBoundingClientRect) { 75 return { 76 width: element.offsetWidth, 77 height: element.offsetHeight 78 } 79 } 80 81 var rect = element.getBoundingClientRect(); 82 return { 83 width: Math.round(rect.width), 84 height: Math.round(rect.height) 85 } 86 } 87 88 /** 89 * Class for dimension change detection. 90 * 91 * @param {Element|Element[]|Elements|jQuery} element 92 * @param {Function} callback 93 * 94 * @constructor 95 */ 96 var ResizeSensor = function(element, callback) { 97 /** 98 * 99 * @constructor 100 */ 101 function EventQueue() { 102 var q = []; 103 this.add = function(ev) { 104 q.push(ev); 105 }; 106 107 var i, j; 108 this.call = function() { 109 for (i = 0, j = q.length; i < j; i++) { 110 q[i].call(); 111 } 112 }; 113 114 this.remove = function(ev) { 115 var newQueue = []; 116 for(i = 0, j = q.length; i < j; i++) { 117 if(q[i] !== ev) newQueue.push(q[i]); 118 } 119 q = newQueue; 120 }; 121 122 this.length = function() { 123 return q.length; 124 } 125 } 126 127 /** 128 * 129 * @param {HTMLElement} element 130 * @param {Function} resized 131 */ 132 function attachResizeEvent(element, resized) { 133 if (!element) return; 134 if (element.resizedAttached) { 135 element.resizedAttached.add(resized); 136 return; 137 } 138 139 element.resizedAttached = new EventQueue(); 140 element.resizedAttached.add(resized); 141 142 element.resizeSensor = document.createElement('div'); 143 element.resizeSensor.dir = 'ltr'; 144 element.resizeSensor.className = 'resize-sensor'; 145 var style = 'position: absolute; left: -10px; top: -10px; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;'; 146 var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;'; 147 148 element.resizeSensor.style.cssText = style; 149 element.resizeSensor.innerHTML = 150 '<div class="resize-sensor-expand" style="' + style + '">' + 151 '<div style="' + styleChild + '"></div>' + 152 '</div>' + 153 '<div class="resize-sensor-shrink" style="' + style + '">' + 154 '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' + 155 '</div>'; 156 element.appendChild(element.resizeSensor); 157 158 var position = window.getComputedStyle(element).getPropertyPriority('position'); 159 if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) { 160 element.style.position = 'relative'; 161 } 162 163 var expand = element.resizeSensor.childNodes[0]; 164 var expandChild = expand.childNodes[0]; 165 var shrink = element.resizeSensor.childNodes[1]; 166 var dirty, rafId, newWidth, newHeight; 167 var size = getElementSize(element); 168 var lastWidth = size.width; 169 var lastHeight = size.height; 170 171 var reset = function() { 172 //set display to block, necessary otherwise hidden elements won't ever work 173 var invisible = element.offsetWidth === 0 && element.offsetHeight === 0; 174 175 if (invisible) { 176 var saveDisplay = element.style.display; 177 element.style.display = 'block'; 178 } 179 180 expandChild.style.width = '100000px'; 181 expandChild.style.height = '100000px'; 182 183 expand.scrollLeft = 100000; 184 expand.scrollTop = 100000; 185 186 shrink.scrollLeft = 100000; 187 shrink.scrollTop = 100000; 188 189 if (invisible) { 190 element.style.display = saveDisplay; 191 } 192 }; 193 element.resizeSensor.resetSensor = reset; 194 195 var onResized = function() { 196 rafId = 0; 197 198 if (!dirty) return; 199 200 lastWidth = newWidth; 201 lastHeight = newHeight; 202 203 if (element.resizedAttached) { 204 element.resizedAttached.call(); 205 } 206 }; 207 208 var onScroll = function() { 209 var size = getElementSize(element); 210 var newWidth = size.width; 211 var newHeight = size.height; 212 dirty = newWidth != lastWidth || newHeight != lastHeight; 213
214 if (dirty && !rafId) { 215 rafId = requestAnimationFrame(onResized); 216 } 217 218 reset(); 219 }; 220 221 var addEvent = function(el, name, cb) { 222 if (el.attachEvent) { 223 el.attachEvent('on' + name, cb); 224 } else { 225 el.addEventListener(name, cb); 226 } 227 }; 228 229 addEvent(expand, 'scroll', onScroll); 230 addEvent(shrink, 'scroll', onScroll); 231 232 // Fix for custom Elements 233 requestAnimationFrame(reset); 234 } 235 236 forEachElement(element, function(elem){ 237 attachResizeEvent(elem, callback); 238 }); 239 240 this.detach = function(ev) { 241 ResizeSensor.detach(element, ev); 242 }; 243 244 this.reset = function() { 245 element.resizeSensor.resetSensor(); 246 }; 247 }; 248 249 ResizeSensor.reset = function(element, ev) { 250 forEachElement(element, function(elem){ 251 elem.resizeSensor.resetSensor(); 252 }); 253 }; 254 255 ResizeSensor.detach = function(element, ev) { 256 forEachElement(element, function(elem){ 257 if (!elem) return; 258 if(elem.resizedAttached && typeof ev === "function"){ 259 elem.resizedAttached.remove(ev); 260 if(elem.resizedAttached.length()) return; 261 } 262 if (elem.resizeSensor) { 263 if (elem.contains(elem.resizeSensor)) { 264 elem.removeChild(elem.resizeSensor); 265 } 266 delete elem.resizeSensor; 267 delete elem.resizedAttached; 268 } 269 }); 270 }; 271 272 return ResizeSensor; 273 274})); 275 276'use strict'; 277 278/** 279 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level 280 * directory of this distribution and at 281 * https://github.com/marcj/css-element-queries/blob/master/LICENSE. 282 */ 283(function (root, factory) { 284 if (typeof define === "function" && define.amd) { 285 define(['./ResizeSensor.js'], factory); 286 } else if (typeof exports === "object") { 287 module.exports = factory(require('./ResizeSensor.js')); 288 } else { 289 root.ElementQueries = factory(root.ResizeSensor); 290 root.ElementQueries.listen(); 291 } 292}(typeof window !== 'undefined' ? window : this, function (ResizeSensor) { 293 294 /** 295 * 296 * @type {Function} 297 * @constructor 298 */ 299 var ElementQueries = function () { 300 //<style> element with our dynamically created styles 301 var cssStyleElement; 302 303 //all rules found for element queries 304 var allQueries = {}; 305 306 //association map to identify which selector belongs to a element from the animationstart event. 307 var idToSelectorMapping = []; 308 309 /** 310 * 311 * @param element 312 * @returns {Number} 313 */ 314 function getEmSize(element) { 315 if (!element) { 316 element = document.documentElement; 317 } 318 var fontSize = window.getComputedStyle(element, null).fontSize; 319 return parseFloat(fontSize) || 16; 320 } 321 322 /** 323 * Get element size 324 * @param {HTMLElement} element 325 * @returns {Object} {width, height} 326 */ 327 function getElementSize(element) { 328 if (!element.getBoundingClientRect) { 329 return { 330 width: element.offsetWidth, 331 height: element.offsetHeight 332 } 333 } 334 335 var rect = element.getBoundingClientRect(); 336 return { 337 width: Math.round(rect.width), 338 height: Math.round(rect.height) 339 } 340 } 341 342 /** 343 * 344 * @copyright https://github.com/Mr0grog/element-query/blob/master/LICENSE 345 * 346 * @param {HTMLElement} element 347 * @param {*} value 348 * @returns {*} 349 */ 350 function convertToPx(element, value) { 351 var numbers = value.split(/\d/); 352 var units = numbers[numbers.length - 1]; 353 value = parseFloat(value); 354 switch (units) { 355 case "px": 356 return value; 357 case "em": 358 return value * getEmSize(element); 359 case "rem": 360 return value * getEmSize(); 361 // Viewport units! 362 // According to http://quirksmode.org/mobile/tableViewport.html 363 // documentElement.clientWidth/Height gets us the most reliable info 364 case "vw": 365 return value * document.documentElement.clientWidth / 100; 366 case "vh": 367 return value * document.documentElement.clientHeight / 100; 368 case "vmin": 369 case "vmax": 370 var vw = document.documentElement.clientWidth / 100; 371 var vh = document.documentElement.clientHeight / 100; 372 var chooser = Math[units === "vmin" ? "min" : "max"]; 373 return value * chooser(vw, vh); 374 default: 375 return value; 376 // for now, not supporting physical units (since they are just a set number of px) 377 // or ex/ch (getting accurate measurements is hard) 378 } 379 } 380 381 /** 382 * 383 * @param {HTMLElement} element 384 * @param {String} id 385 * @constructor 386 */ 387 function SetupInformation(element, id) { 388 this.element = element; 389 var key, option, elementSize, value, actualValue, attrValues, attrValue, attrName; 390 391 var attributes = ['min-width', 'min-height', 'max-width', 'max-height']; 392 393 /** 394 * Extracts the computed width/height and sets to min/max- attribute. 395 */ 396 this.call = function () { 397 // extract current dimensions 398 elementSize = getElementSize(this.element); 399 400 attrValues = {}; 401 402 for (key in allQueries[id]) { 403 if (!allQueries[id].hasOwnProperty(key)) { 404 continue; 405 } 406 option = allQueries[id][key]; 407 408 value = convertToPx(this.element, option.value); 409 410 actualValue = option.property === 'width' ? elementSize.width : elementSize.height; 411 attrName = option.mode + '-' + option.property; 412 attrValue = ''; 413 414 if (option.mode === 'min' && actualValue >= value) { 415 attrValue += option.value; 416 } 417 418 if (option.mode === 'max' && actualValue <= value) { 419 attrValue += option.value; 420 } 421 422 if (!attrValues[attrName]) attrValues[attrName] = ''; 423 if (attrValue && -1 === (' ' + attrValues[attrName] + ' ').indexOf(' ' + attrValue + ' ')) { 424 attrValues[attrName] += ' ' + attrValue; 425 } 426 } 427 428 for (var k in attributes) { 429 if (!attributes.hasOwnProperty(k)) continue; 430 431 if (attrValues[attributes[k]]) { 432 this.element.setAttribute(attributes[k], attrValues[attributes[k]].substr(1)); 433 } else { 434 this.element.removeAttribute(attributes[k]); 435 } 436 } 437 }; 438 } 439 440 /** 441 * @param {HTMLElement} element 442 * @param {Object} id 443 */ 444 function setupElement(element, id) { 445 if (!element.elementQueriesSetupInformation) { 446 element.elementQueriesSetupInformation = new SetupInformation(element, id); 447 } 448 if (!element.elementQueriesSensor) { 449 element.elementQueriesSensor = new ResizeSensor(element, function () { 450 element.elementQueriesSetupInformation.call(); 451 }); 452 } 453 454 element.elementQueriesSetupInformation.call(); 455 } 456 457 /** 458 * Stores rules to the selector that should be applied once resized. 459 * 460 * @param {String} selector 461 * @param {String} mode min|max 462 * @param {String} property width|height 463 * @param {String} value 464 */ 465 function queueQuery(selector, mode, property, value) { 466 if (typeof(allQueries[selector]) === 'undefined') { 467 allQueries[selector] = []; 468 // add animation to trigger animationstart event, so we know exactly when a element appears in the DOM 469 470 var id = idToSelectorMapping.length; 471 cssStyleElement.innerHTML += '\n' + selector + ' {animation: 0.1s element-queries;}'; 472 cssStyleElement.innerHTML += '\n' + selector + ' > .resize-sensor {min-width: '+id+'px;}'; 473 idToSelectorMapping.push(selector); 474 } 475 476 allQueries[selector].push({ 477 mode: mode, 478 property: property, 479 value: value 480 }); 481 } 482 483 function getQuery(container) { 484 var query; 485 if (document.querySelectorAll) query = (container) ? container.querySelectorAll.bind(container) : document.querySelectorAll.bind(document); 486 if (!query && 'undefined' !== typeof $$) query = $$; 487 if (!query && 'undefined' !== typeof jQuery) query = jQuery; 488 489 if (!query) { 490 throw 'No document.querySelectorAll, jQuery or Mootools\'s $$ found.'; 491 } 492 493 return query; 494 } 495 496 /** 497 * If animationStart didn't catch a new element in the DOM, we can manually search for it 498 */ 499 function findElementQueriesElements(container) { 500 var query = getQuery(container); 501 502 for (var selector in allQueries) if (allQueries.hasOwnProperty(mode)) { 503 // find all elements based on the extract query selector from the element query rule 504 var elements = query(selector, container); 505 506 for (var i = 0, j = elements.length; i < j; i++) { 507 setupElement(elements[i], selector); 508 } 509 } 510 } 511 512 /** 513 * 514 * @param {HTMLElement} element 515 */ 516 function attachResponsiveImage(element) { 517 var children = []; 518 var rules = []; 519 var sources = []; 520 var defaultImageId = 0; 521 var lastActiveImage = -1; 522 var loadedImages = []; 523 524 for (var i in element.children) { 525 if (!element.children.hasOwnProperty(i)) continue; 526 527 if (element.children[i].tagName && element.children[i].tagName.toLowerCase() === 'img') { 528 children.push(element.children[i]); 529 530 var minWidth = element.children[i].getAttribute('min-width') || element.children[i].getAttribute('data-min-width'); 531 //var minHeight = element.children[i].getAttribute('min-height') || element.children[i].getAttribute('data-min-height'); 532 var src = element.children[i].getAttribute('data-src') || element.children[i].getAttribute('url'); 533 534 sources.push(src); 535 536 var rule = { 537 minWidth: minWidth 538 }; 539 540 rules.push(rule); 541 542 if (!minWidth) { 543 defaultImageId = children.length - 1; 544 element.children[i].style.display = 'block'; 545 } else { 546 element.children[i].style.display = 'none'; 547 } 548 } 549 } 550 551 lastActiveImage = defaultImageId; 552 553 function check() { 554 var imageToDisplay = false, i; 555 556 for (i in children) { 557 if (!children.hasOwnProperty(i)) continue; 558 559 if (rules[i].minWidth) { 560 if (element.offsetWidth > rules[i].minWidth) { 561 imageToDisplay = i; 562 } 563 } 564 } 565 566 if (!imageToDisplay) { 567 //no rule matched, show default 568 imageToDisplay = defaultImageId; 569 } 570 571 if (lastActiveImage !== imageToDisplay) { 572 //image change 573 574 if (!loadedImages[imageToDisplay]) { 575 //image has not been loaded yet, we need to load the image first in memory to prevent flash of 576 //no content 577 578 var image = new Image(); 579 image.onload = function () { 580 children[imageToDisplay].src = sources[imageToDisplay]; 581 582 children[lastActiveImage].style.display = 'none'; 583 children[imageToDisplay].style.display = 'block'; 584 585 loadedImages[imageToDisplay] = true; 586 587 lastActiveImage = imageToDisplay; 588 }; 589 590 image.src = sources[imageToDisplay]; 591 } else { 592 children[lastActiveImage].style.display = 'none'; 593 children[imageToDisplay].style.display = 'block'; 594 lastActiveImage = imageToDisplay; 595 } 596 } else { 597 //make sure for initial check call the .src is set correctly 598 children[imageToDisplay].src = sources[imageToDisplay]; 599 } 600 } 601 602 element.resizeSensor = new ResizeSensor(element, check); 603 check(); 604 } 605 606 function findResponsiveImages() { 607 var query = getQuery(); 608 609 var elements = query('[data-responsive-image],[responsive-image]'); 610 for (var i = 0, j = elements.length; i < j; i++) { 611 attachResponsiveImage(elements[i]); 612 } 613 } 614 615 var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mg
615i; 616 var attrRegex = /\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi; 617 618 /** 619 * @param {String} css 620 */ 621 function extractQuery(css) { 622 var match, smatch, attrs, attrMatch; 623 624 css = css.replace(/'/g, '"'); 625 while (null !== (match = regex.exec(css))) { 626 smatch = match[1] + match[3]; 627 attrs = match[2]; 628 629 while (null !== (attrMatch = attrRegex.exec(attrs))) { 630 queueQuery(smatch, attrMatch[1], attrMatch[2], attrMatch[3]); 631 } 632 } 633 } 634 635 /** 636 * @param {CssRule[]|String} rules 637 */ 638 function readRules(rules) { 639 var selector = ''; 640 641 if (!rules) { 642 return; 643 } 644 645 if ('string' === typeof rules) { 646 rules = rules.toLowerCase(); 647 if (-1 !== rules.indexOf('min-width') || -1 !== rules.indexOf('max-width')) { 648 extractQuery(rules); 649 } 650 } else { 651 for (var i = 0, j = rules.length; i < j; i++) { 652 if (1 === rules[i].type) { 653 selector = rules[i].selectorText || rules[i].cssText; 654 if (-1 !== selector.indexOf('min-height') || -1 !== selector.indexOf('max-height')) { 655 extractQuery(selector); 656 } else if (-1 !== selector.indexOf('min-width') || -1 !== selector.indexOf('max-width')) { 657 extractQuery(selector); 658 } 659 } else if (4 === rules[i].type) { 660 readRules(rules[i].cssRules || rules[i].rules); 661 } else if (3 === rules[i].type) { 662 readRules(rules[i].styleSheet.cssRules); 663 } 664 } 665 } 666 } 667 668 var defaultCssInjected = false; 669 670 /** 671 * Searches all css rules and setups the event listener to all elements with element query rules.. 672 */ 673 this.init = function () { 674 var animationStart = 'animationstart'; 675 if (typeof document.documentElement.style['webkitAnimationName'] !== 'undefined') { 676 animationStart = 'webkitAnimationStart'; 677 } else if (typeof document.documentElement.style['MozAnimationName'] !== 'undefined') { 678 animationStart = 'mozanimationstart'; 679 } else if (typeof document.documentElement.style['OAnimationName'] !== 'undefined') { 680 animationStart = 'oanimationstart'; 681 } 682 683 document.body.addEventListener(animationStart, function (e) { 684 var element = e.target; 685 var styles = window.getComputedStyle(element, null); 686 687 if (-1 !== styles.getPropertyValue('animation-name').indexOf('element-queries')) { 688 element.elementQueriesSensor = new ResizeSensor(element, function () { 689 if (element.elementQueriesSetupInformation) { 690 element.elementQueriesSetupInformation.call(); 691 } 692 }); 693 694 var sensorStyles = window.getComputedStyle(element.resizeSensor, null); 695 var id = sensorStyles.getPropertyValue('min-width'); 696 id = parseInt(id.replace('px', '')); 697 setupElement(e.target, idToSelectorMapping[id]); 698 } 699 }); 700 701 if (!defaultCssInjected) { 702 cssStyleElement = document.createElement('style'); 703 cssStyleElement.type = 'text/css'; 704 cssStyleElement.innerHTML = '[responsive-image] > img, [data-responsive-image] {overflow: hidden; padding: 0; } [responsive-image] > img, [data-responsive-image] > img {width: 100%;}'; 705 706 //safari wants at least one rule in keyframes to start working 707 cssStyleElement.innerHTML += '\n@keyframes element-queries { 0% { visibility: inherit; } }'; 708 document.getElementsByTagName('head')[0].appendChild(cssStyleElement); 709 defaultCssInjected = true; 710 } 711 712 for (var i = 0, j = document.styleSheets.length; i < j; i++) { 713 try { 714 if (document.styleSheets[i].href && 0 === document.styleSheets[i].href.indexOf('file://')) { 715 console.log("CssElementQueries: unable to parse local css files, " + document.styleSheets[i].href); 716 } 717 718 readRules(document.styleSheets[i].cssRules || document.styleSheets[i].rules || document.styleSheets[i].cssText); 719 } catch (e) { 720 } 721 } 722 723 // findElementQueriesElements(); 724 findResponsiveImages(); 725 }; 726 727 /** 728 * Go through all collected rules (readRules()) and attach the resize-listener. 729 * Not necessary to call it manually, since we detect automatically when new elements 730 * are available in the DOM. However, sometimes handy for dirty DOM modifications. 731 * 732 * @param {HTMLElement} container only elements of the container are considered (document.body if not set) 733 */ 734 this.findElementQueriesElements = function (container) { 735 findElementQueriesElements(container); 736 }; 737 738 this.update = function () { 739 this.init(); 740 }; 741 }; 742 743 ElementQueries.update = function () {
744 ElementQueries.instance.update(); 745 }; 746 747 /** 748 * Removes all sensor and elementquery information from the element. 749 * 750 * @param {HTMLElement} element 751 */ 752 ElementQueries.detach = function (element) { 753 if (element.elementQueriesSetupInformation) { 754 //element queries 755 element.elementQueriesSensor.detach(); 756 delete element.elementQueriesSetupInformation; 757 delete element.elementQueriesSensor; 758 759 } else if (element.resizeSensor) { 760 //responsive image 761 762 element.resizeSensor.detach(); 763 delete element.resizeSensor; 764 } 765 }; 766 767 ElementQueries.init = function () { 768 if (!ElementQueries.instance) { 769 ElementQueries.instance = new ElementQueries(); 770 } 771 772 ElementQueries.instance.init(); 773 }; 774 775 var domLoaded = function (callback) { 776 /* Mozilla, Chrome, Opera */ 777 if (document.addEventListener) { 778 document.addEventListener('DOMContentLoaded', callback, false); 779 } 780 /* Safari, iCab, Konqueror */ 781 else if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) { 782 var DOMLoadTimer = setInterval(function () { 783 if (/loaded|complete/i.test(document.readyState)) { 784 callback(); 785 clearInterval(DOMLoadTimer); 786 } 787 }, 10); 788 } 789 /* Other web browsers */ 790 else window.onload = callback; 791 }; 792 793 ElementQueries.findElementQueriesElements = function (container) { 794 ElementQueries.instance.findElementQueriesElements(container); 795 }; 796 797 ElementQueries.listen = function () { 798 domLoaded(ElementQueries.init); 799 }; 800 801 return ElementQueries; 802 803})); 804 805(function($) { 806 'use strict'; 807 808 $.exists = function(selector) { 809 return ($(selector).length > 0); 810 }; 811 812 /** 813 * Helper to enable caching async scripts 814 * https://api.jquery.com/jquery.getscript/ 815 * http://www.vrdmn.com/2013/07/overriding-jquerygetscript-to-include.html 816 * 817 * @param {String} script url 818 * @param {Function} callback 819 */ 820 $.getCachedScript = function( url ) { 821 var options = { 822 dataType: "script", 823 cache: true, 824 url: url 825 }; 826 827 // Use $.ajax() since it is more flexible than $.getScript 828 // Return the jqXHR object so we can chain callbacks 829 return $.ajax( options ); 830 }; 831 832 833 834 // Fn to allow an event to fire after all images are loaded 835 // usage: 836 // $.ajax({ 837 // cache: false, 838 // url: 'ajax/content.php', 839 // success: function(data) { 840 // $('#divajax').html(data).imagesLoaded().then(function(){ 841 // // do stuff after images are loaded here 842 // }); 843 // } 844 // }); 845 $.fn.mk_imagesLoaded = function () { 846 847 // Edit: in strict mode, the var keyword is needed 848 var $imgs = this.find('img[src!=""]'); 849 // if there's no images, just return an already resolved promise 850 if (!$imgs.length) {return $.Deferred().resolve().promise();} 851 852 // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails) 853 var dfds = []; 854 $imgs.each(function(){ 855 var dfd = $.Deferred(); 856 dfds.push(dfd); 857 var img = new Image(); 858 img.onload = function(){dfd.resolve();}; 859 img.onerror = function(){dfd.resolve();}; 860 img.src = this.src; 861 }); 862 863 // return a master promise object which will resolve when all the deferred objects have resolved 864 // IE - when all the images are loaded 865 return $.when.apply($,dfds); 866 867 }; 868 869}(jQuery)); 870/** 871* Detect Element Resize 872* 873* https://github.com/sdecima/javascript-detect-element-resize 874* Sebastian Decima 875* 876* version: 0.5.3 877**/ 878 879(function () { 880 var attachEvent = document.attachEvent, 881 stylesCreated = false; 882 883 if (!attachEvent) { 884 var requestFrame = (function(){ 885 var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || 886 function(fn){ return window.setTimeout(fn, 20); }; 887 return function(fn){ return raf(fn); }; 888 })(); 889 890 var cancelFrame = (function(){ 891 var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || 892 window.clearTimeout; 893 return function(id){ return cancel(id); }; 894 })(); 895 896 function resetTriggers(element){ 897 var triggers = element.__resizeTriggers__, 898 expand = triggers.firstElementChild, 899 contract = triggers.lastElementChild, 900 expandChild = expand.firstElementChild; 901 contract.scrollLeft = contract.scrollWidth; 902 contract.scrollTop = contract.scrollHeight; 903 expandChild.style.width = expand.offsetWidth + 1 + 'px'; 904 expandChild.style.height = expand.offsetHeight + 1 + 'px'; 905 expand.scrollLeft = expand.scrollWidth; 906 expand.scrollTop = expand.scrollHeight; 907 }; 908 909 function checkTriggers(element){ 910 return element.offsetWidth != element.__resizeLast__.width || 911 element.offsetHeight != element.__resizeLast__.height; 912 } 913 914 function scrollListener(e){ 915 var element = this; 916 resetTriggers(this); 917 if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__); 918 this.__resizeRAF__ = requestFrame(function(){ 919 if (checkTriggers(element)) { 920 element.__resizeLast__.width = element.offsetWidth; 921 element.__resizeLast__.height = element.offsetHeight; 922 element.__resizeListeners__.forEach(function(fn){ 923 fn.call(element, e); 924 }); 925 } 926 }); 927 }; 928
929 /* Detect CSS Animations support to detect element display/re-attach */ 930 var animation = false, 931 animationstring = 'animation', 932 keyframeprefix = '', 933 animationstartevent = 'animationstart', 934 domPrefixes = 'Webkit Moz O ms'.split(' '), 935 startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '), 936 pfx = ''; 937 { 938 var elm = document.createElement('fakeelement'); 939 if( elm.style.animationName !== undefined ) { animation = true; } 940 941 if( animation === false ) { 942 for( var i = 0; i < domPrefixes.length; i++ ) { 943 if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) { 944 pfx = domPrefixes[ i ]; 945 animationstring = pfx + 'Animation'; 946 keyframeprefix = '-' + pfx.toLowerCase() + '-'; 947 animationstartevent = startEvents[ i ]; 948 animation = true; 949 break; 950 } 951 } 952 } 953 } 954 955 var animationName = 'resizeanim'; 956 var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } '; 957 var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; '; 958 } 959 960 function createStyles() { 961 if (!stylesCreated) { 962 //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360 963 var css = (animationKeyframes ? animationKeyframes : '') + 964 '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' + 965 '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }', 966 head = document.head || document.getElementsByTagName('head')[0], 967 style = document.createElement('style'); 968 969 style.type = 'text/css'; 970 if (style.styleSheet) { 971 style.styleSheet.cssText = css; 972 } else { 973 style.appendChild(document.createTextNode(css)); 974 } 975 976 head.appendChild(style); 977 stylesCreated = true; 978 } 979 } 980 981 window.addResizeListener = function(element, fn){ 982 if (attachEvent) element.attachEvent('onresize', fn); 983 else { 984 if (!element.__resizeTriggers__) { 985 if (getComputedStyle(element).position == 'static') element.style.position = 'relative'; 986 createStyles(); 987 element.__resizeLast__ = {}; 988 element.__resizeListeners__ = []; 989 (element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers'; 990 element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' + 991 '<div class="contract-trigger"></div>'; 992 element.appendChild(element.__resizeTriggers__); 993 resetTriggers(element); 994 element.addEventListener('scroll', scrollListener, true); 995 996 /* Listen for a css animation to detect element display/re-attach */ 997 animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) { 998 if(e.animationName == animationName) 999 resetTriggers(element); 1000 }); 1001 } 1002 element.__resizeListeners__.push(fn); 1003 } 1004 }; 1005 1006 window.removeResizeListener = function(element, fn){ 1007 if (attachEvent) element.detachEvent('onresize', fn); 1008 else { 1009 element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); 1010 if (!element.__resizeListeners__.length) { 1011 element.removeEventListener('scroll', scrollListener); 1012 element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); 1013 } 1014 } 1015 } 1016})(); 1017/** 1018* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 1019*/ 1020;(function(window, document) { 1021/*jshint evil:true */ 1022 /** version */ 1023 var version = '3.7.3'; 1024 1025 /** Preset options */ 1026 var options = window.html5 || {}; 1027 1028 /** Used to skip problem elements */ 1029 var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; 1030 1031 /** Not all elements can be cloned in IE **/ 1032 var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; 1033 1034 /** Detect whether the browser supports default html5 styles */ 1035 var supportsHtml5Styles; 1036 1037 /** Name of the expando, to work with multiple documents or to re-shiv one document */ 1038 var expando = '_html5shiv'; 1039 1040 /** The id for the the documents expando */ 1041 var expanID = 0; 1042 1043 /** Cached data for each document */ 1044 var expandoData = {}; 1045 1046 /** Detect whether the browser supports unknown elements */ 1047 var supportsUnknownElements; 1048 1049 (function() { 1050 try { 1051 var a = document.createElement('a'); 1052 a.innerHTML = '<xyz></xyz>'; 1053 //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles 1054 supportsHtml5Styles = ('hidden' in a); 1055 1056 supportsUnknownElements = a.childNodes.length == 1 || (function() { 1057 // assign a false positive if unable to shiv 1058 (document.createElement)('a'); 1059 var frag = document.createDocumentFragment(); 1060 return ( 1061 typeof frag.cloneNode == 'undefined' || 1062 typeof frag.createDocumentFragment == 'undefined' || 1063 typeof frag.createElement == 'undefined' 1064 ); 1065 }()); 1066 } catch(e) { 1067 // assign a false positive if detection fails => unable to shiv 1068 supportsHtml5Styles = true; 1069 supportsUnknownElements = true; 1070 } 1071 1072 }()); 1073 1074 /*--------------------------------------------------------------------------*/ 1075 1076 /** 1077 * Creates a style sheet with the given CSS text and adds it to the document. 1078 * @private 1079 * @param {Document} ownerDocument The document. 1080 * @param {String} cssText The CSS text. 1081 * @returns {StyleSheet} The style element. 1082 */ 1083 function addStyleSheet(ownerDocument, cssText) { 1084 var p = ownerDocument.createElement('p'), 1085 parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; 1086 1087 p.innerHTML = 'x<style>' + cssText + '</style>'; 1088 return parent.insertBefore(p.lastChild, parent.firstChild); 1089 } 1090 1091 /** 1092 * Returns the value of `html5.elements` as an array.
1093 * @private 1094 * @returns {Array} An array of shived element node names. 1095 */ 1096 function getElements() { 1097 var elements = html5.elements; 1098 return typeof elements == 'string' ? elements.split(' ') : elements; 1099 } 1100 1101 /** 1102 * Extends the built-in list of html5 elements 1103 * @memberOf html5 1104 * @param {String|Array} newElements whitespace separated list or array of new element names to shiv 1105 * @param {Document} ownerDocument The context document. 1106 */ 1107 function addElements(newElements, ownerDocument) { 1108 var elements = html5.elements; 1109 if(typeof elements != 'string'){ 1110 elements = elements.join(' '); 1111 } 1112 if(typeof newElements != 'string'){ 1113 newElements = newElements.join(' '); 1114 } 1115 html5.elements = elements +' '+ newElements; 1116 shivDocument(ownerDocument); 1117 } 1118 1119 /** 1120 * Returns the data associated to the given document 1121 * @private 1122 * @param {Document} ownerDocument The document. 1123 * @returns {Object} An object of data. 1124 */ 1125 function getExpandoData(ownerDocument) { 1126 var data = expandoData[ownerDocument[expando]]; 1127 if (!data) { 1128 data = {}; 1129 expanID++; 1130 ownerDocument[expando] = expanID; 1131 expandoData[expanID] = data; 1132 } 1133 return data; 1134 } 1135 1136 /** 1137 * returns a shived element for the given nodeName and document 1138 * @memberOf html5 1139 * @param {String} nodeName name of the element 1140 * @param {Document|DocumentFrag
vendor: 6,335 bytes, lines 1140-1342
1140ment} ownerDocument The context document. 1141 * @returns {Object} The shived element. 1142 */ 1143 function createElement(nodeName, ownerDocument, data){ 1144 if (!ownerDocument) { 1145 ownerDocument = document; 1146 } 1147 if(supportsUnknownElements){ 1148 return ownerDocument.createElement(nodeName); 1149 } 1150 if (!data) { 1151 data = getExpandoData(ownerDocument); 1152 } 1153 var node; 1154 1155 if (data.cache[nodeName]) { 1156 node = data.cache[nodeName].cloneNode(); 1157 } else if (saveClones.test(nodeName)) { 1158 node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); 1159 } else { 1160 node = data.createElem(nodeName); 1161 } 1162 1163 // Avoid adding some elements to fragments in IE < 9 because 1164 // * Attributes like `name` or `type` cannot be set/changed once an element 1165 // is inserted into a document/fragment 1166 // * Link elements with `src` attributes that are inaccessible, as with 1167 // a 403 response, will cause the tab/window to crash 1168 // * Script elements appended to fragments will execute when their `src` 1169 // or `text` property is set 1170 return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; 1171 } 1172 1173 /** 1174 * returns a shived DocumentFragment for the given document 1175 * @memberOf html5 1176 * @param {Document} ownerDocument The context document. 1177 * @returns {Object} The shived DocumentFragment. 1178 */ 1179 function createDocumentFragment(ownerDocument, data){ 1180 if (!ownerDocument) { 1181 ownerDocument = document; 1182 } 1183 if(supportsUnknownElements){ 1184 return ownerDocument.createDocumentFragment(); 1185 } 1186 data = data || getExpandoData(ownerDocument); 1187 var clone = data.frag.cloneNode(), 1188 i = 0, 1189 elems = getElements(), 1190 l = elems.length; 1191 for(;i<l;i++){ 1192 clone.createElement(elems[i]); 1193 } 1194 return clone; 1195 } 1196 1197 /** 1198 * Shivs the `createElement` and `createDocumentFragment` methods of the document. 1199 * @private 1200 * @param {Document|DocumentFragment} ownerDocument The document. 1201 * @param {Object} data of the document. 1202 */ 1203 function shivMethods(ownerDocument, data) { 1204 if (!data.cache) { 1205 data.cache = {}; 1206 data.createElem = ownerDocument.createElement; 1207 data.createFrag = ownerDocument.createDocumentFragment; 1208 data.frag = data.createFrag(); 1209 } 1210 1211 1212 ownerDocument.createElement = function(nodeName) { 1213 //abort shiv 1214 if (!html5.shivMethods) { 1215 return data.createElem(nodeName); 1216 } 1217 return createElement(nodeName, ownerDocument, data); 1218 }; 1219 1220 ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 1221 'var n=f.cloneNode(),c=n.createElement;' + 1222 'h.shivMethods&&(' + 1223 // unroll the `createElement` calls 1224 getElements().join().replace(/[\w\-:]+/g, function(nodeName) { 1225 data.createElem(nodeName); 1226 data.frag.createElement(nodeName); 1227 return 'c("' + nodeName + '")'; 1228 }) + 1229 ');return n}' 1230 )(html5, data.frag); 1231 } 1232 1233 /*--------------------------------------------------------------------------*/ 1234 1235 /** 1236 * Shivs the given document. 1237 * @memberOf html5 1238 * @param {Document} ownerDocument The document to shiv. 1239 * @returns {Document} The shived document. 1240 */ 1241 function shivDocument(ownerDocument) { 1242 if (!ownerDocument) { 1243 ownerDocument = document; 1244 } 1245 var data = getExpandoData(ownerDocument); 1246 1247 if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { 1248 data.hasCSS = !!addStyleSheet(ownerDocument, 1249 // corrects block display not defined in IE6/7/8/9 1250 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' + 1251 // adds styling not present in IE6/7/8/9 1252 'mark{background:#FF0;color:#000}' + 1253 // hides non-rendered elements 1254 'template{display:none}' 1255 ); 1256 } 1257 if (!supportsUnknownElements) { 1258 shivMethods(ownerDocument, data); 1259 } 1260 return ownerDocument; 1261 } 1262 1263 /*--------------------------------------------------------------------------*/ 1264 1265 /** 1266 * The `html5` object is exposed so that more elements can be shived and 1267 * existing shiving can be detected on iframes. 1268 * @type Object 1269 * @example 1270 * 1271 * // options can be changed before the script is included 1272 * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; 1273 */ 1274 var html5 = { 1275 1276 /** 1277 * An array or space separated string of node names of the elements to shiv. 1278 * @memberOf html5 1279 * @type Array|String 1280 */ 1281 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video', 1282 1283 /** 1284 * current version of html5shiv 1285 */ 1286 'version': version, 1287 1288 /** 1289 * A flag to indicate that the HTML5 style sheet should be inserted. 1290 * @memberOf html5 1291 * @type Boolean 1292 */ 1293 'shivCSS': (options.shivCSS !== false), 1294 1295 /** 1296 * Is equal to true if a browser supports creating unknown/HTML5 elements 1297 * @memberOf html5 1298 * @type boolean 1299 */ 1300 'supportsUnknownElements': supportsUnknownElements, 1301 1302 /** 1303 * A flag to indicate that the document's `createElement` and `createDocumentFragment` 1304 * methods should be overwritten. 1305 * @memberOf html5 1306 * @type Boolean 1307 */ 1308 'shivMethods': (options.shivMethods !== false), 1309 1310 /** 1311 * A string to describe the type of `html5` object ("default" or "default print"). 1312 * @memberOf html5 1313 * @type String 1314 */ 1315 'type': 'default', 1316 1317 // shivs the document according to the specified `html5` object options 1318 'shivDocument': shivDocument, 1319 1320 //creates a shived element 1321 createElement: createElement, 1322 1323 //creates a shived documentFragment 1324 createDocumentFragment: createDocumentFragment, 1325 1326 //extends list of elements 1327 addElements: addElements 1328 }; 1329 1330 /*--------------------------------------------------------------------------*/ 1331 1332 // expose html5 1333 window.html5 = html5; 1334 1335 // shiv the document 1336 shivDocument(document); 1337 1338 if(typeof module == 'object' && module.exports){ 1339 module.exports = html5; 1340 } 1341 1342}(typeof window !== "undefined" ? window : this, document));
1343/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ 1344 1345window.matchMedia || (window.matchMedia = function() { 1346 "use strict"; 1347 1348 // For browsers that support matchMedium api such as IE 9 and webkit 1349 var styleMedia = (window.styleMedia || window.media); 1350 1351 // For those that don't support matchMedium 1352 if (!styleMedia) { 1353 var style = document.createElement('style'), 1354 script = document.getElementsByTagName('script')[0], 1355 info = null; 1356 1357 style.type = 'text/css'; 1358 style.id = 'matchmediajs-test'; 1359 1360 script.parentNode.insertBefore(style, script); 1361 1362 // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers 1363 info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; 1364 1365 styleMedia = { 1366 matchMedium: function(media) { 1367 var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; 1368 1369 // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers 1370 if (style.styleSheet) { 1371 style.styleSheet.cssText = text; 1372 } else { 1373 style.textContent = text; 1374 } 1375 1376 // Test if media query is true or false 1377 return info.width === '1px'; 1378 } 1379 }; 1380 } 1381 1382 return function(media) { 1383 return { 1384 matches: styleMedia.matchMedium(media || 'all'), 1385 media: media || 'all' 1386 }; 1387 }; 1388}()); 1389 1390/*! 1391 * The MIT License 1392 * 1393 * Copyright (c) 2012 James Allardice 1394 * 1395 * Permission is hereby granted, free of charge, to any person obtaining a copy 1396 * of this software and associated documentation files (the "Software"), to 1397 * deal in the Software without restriction, including without limitation the 1398 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 1399 * sell copies of the Software, and to permit persons to whom the Software is 1400 * furnished to do so, subject to the following conditions: 1401 * 1402 * The above copyright notice and this permission notice shall be included in 1403 * all copies or substantial portions of the Software. 1404 * 1405 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1406 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1407 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1408 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1409 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1410 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 1411 * IN THE SOFTWARE. 1412 */ 1413 1414( function ( global ) { 1415 1416 'use strict'; 1417 1418 // 1419 // Test for support. We do this as early as possible to optimise for browsers 1420 // that have native support for the attribute. 1421 // 1422 1423 var test = document.createElement('input'); 1424 var nativeSupport = test.placeholder !== void 0; 1425 1426 global.Placeholders = { 1427 nativeSupport: nativeSupport, 1428 disable: nativeSupport ? noop : disablePlaceholders, 1429 enable: nativeSupport ? noop : enablePlaceholders 1430 }; 1431 1432 if ( nativeSupport ) { 1433 return; 1434 } 1435 1436 // 1437 // If we reach this point then the browser does not have native support for 1438 // the attribute. 1439 // 1440 1441 // The list of input element types that support the placeholder attribute.
1442 var validTypes = [ 1443 'text', 1444 'search', 1445 'url', 1446 'tel', 1447 'email', 1448 'password', 1449 'number', 1450 'textarea' 1451 ]; 1452 1453 // The list of keycodes that are not allowed when the polyfill is configured 1454 // to hide-on-input. 1455 var badKeys = [ 1456 1457 // The following keys all cause the caret to jump to the end of the input 1458 // value. 1459 1460 27, // Escape 1461 33, // Page up 1462 34, // Page down 1463 35, // End 1464 36, // Home 1465 1466 // Arrow keys allow you to move the caret manually, which should be 1467 // prevented when the placeholder is visible. 1468 1469 37, // Left 1470 38, // Up 1471 39, // Right 1472 40, // Down 1473 1474 // The following keys allow you to modify the placeholder text by removing 1475 // characters, which should be prevented when the placeholder is visible. 1476 1477 8, // Backspace 1478 46 // Delete 1479 ]; 1480 1481 // Styling variables. 1482 var placeholderStyleColor = '#ccc'; 1483 var placeholderClassName = 'placeholdersjs'; 1484 var classNameRegExp = new RegExp('(?:^|\\s)' + placeholderClassName + '(?!\\S)'); 1485 1486 // The various data-* attributes used by the polyfill. 1487 var ATTR_CURRENT_VAL = 'data-placeholder-value'; 1488 var ATTR_ACTIVE = 'data-placeholder-active'; 1489 var ATTR_INPUT_TYPE = 'data-placeholder-type'; 1490 var ATTR_FORM_HANDLED = 'data-placeholder-submit'; 1491 var ATTR_EVENTS_BOUND = 'data-placeholder-bound'; 1492 var ATTR_OPTION_FOCUS = 'data-placeholder-focus'; 1493 var ATTR_OPTION_LIVE = 'data-placeholder-live'; 1494 var ATTR_MAXLENGTH = 'data-placeholder-maxlength'; 1495 1496 // Various other variables used throughout the rest of the script. 1497 var UPDATE_INTERVAL = 100; 1498 var head = document.getElementsByTagName('head')[ 0 ]; 1499 var root = document.documentElement; 1500 var Placeholders = global.Placeholders; 1501 var keydownVal; 1502 1503 // Get references to all the input and textarea elements currently in the DOM 1504 // (live NodeList objects to we only need to do this once). 1505 var inputs = document.getElementsByTagName('input'); 1506 var textareas = document.getElementsByTagName('textarea'); 1507 1508 // Get any settings declared as data-* attributes on the root element. 1509 // Currently the only options are whether to hide the placeholder on focus 1510 // or input and whether to auto-update. 1511 var hideOnInput = root.getAttribute(ATTR_OPTION_FOCUS) === 'false'; 1512 var liveUpdates = root.getAttribute(ATTR_OPTION_LIVE) !== 'false'; 1513 1514 // Create style element for placeholder styles (instead of directly setting 1515 // style properties on elements - allows for better flexibility alongside 1516 // user-defined styles). 1517 var styleElem = document.createElement('style'); 1518 styleElem.type = 'text/css'; 1519 1520 // Create style rules as text node. 1521 var styleRules = document.createTextNode( 1522 '.' + placeholderClassName + ' {' + 1523 'color:' + placeholderStyleColor + ';' + 1524 '}' 1525 ); 1526 1527 // Append style rules to newly created stylesheet. 1528 if ( styleElem.styleSheet ) { 1529 styleElem.styleSheet.cssText = styleRules.nodeValue; 1530 } else { 1531 styleElem.appendChild(styleRules); 1532 } 1533 1534 // Prepend new style element to the head (before any existing stylesheets, 1535 // so user-defined rules take precedence). 1536 head.insertBefore(styleElem, head.firstChild); 1537 1538 // Set up the placeholders. 1539 var placeholder; 1540 var elem; 1541 1542 for ( var i = 0, len = inputs.length + textareas.length; i < len; i++ ) { 1543 1544 // Find the next element. If we've already done all the inputs we move on 1545 // to the textareas. 1546 elem = i < inputs.length ? inputs[ i ] : textareas[ i - inputs.length ]; 1547 1548 // Get the value of the placeholder attribute, if any. IE10 emulating IE7 1549 // fails with getAttribute, hence the use of the attributes node. 1550 placeholder = elem.attributes.placeholder; 1551 1552 // If the element has a placeholder attribute we need to modify it. 1553 if ( placeholder ) { 1554 1555 // IE returns an empty object instead of undefined if the attribute is 1556 // not present. 1557 placeholder = placeholder.nodeValue; 1558 1559 // Only apply the polyfill if this element is of a type that supports 1560 // placeholders and has a placeholder attribute with a non-empty value. 1561 if ( placeholder && inArray(validTypes, elem.type) ) { 1562 newElement(elem); 1563 } 1564 } 1565 } 1566 1567 // If enabled, the polyfill will repeatedly check for changed/added elements 1568 // and apply to those as well. 1569 var timer = setInterval(function () {
1570 for ( var i = 0, len = inputs.length + textareas.length; i < len; i++ ) { 1571 elem = i < inputs.length ? inputs[ i ] : textareas[ i - inputs.length ]; 1572 1573 // Only apply the polyfill if this element is of a type that supports 1574 // placeholders, and has a placeholder attribute with a non-empty value. 1575 placeholder = elem.attributes.placeholder; 1576 1577 if ( placeholder ) { 1578 1579 placeholder = placeholder.nodeValue; 1580 1581 if ( placeholder && inArray(validTypes, elem.type) ) { 1582 1583 // If the element hasn't had event handlers bound to it then add 1584 // them. 1585 if ( !elem.getAttribute(ATTR_EVENTS_BOUND) ) { 1586 newElement(elem); 1587 } 1588 1589 // If the placeholder value has changed or not been initialised yet 1590 // we need to update the display. 1591 if ( 1592 placeholder !== elem.getAttribute(ATTR_CURRENT_VAL) || 1593 ( elem.type === 'password' && !elem.getAttribute(ATTR_INPUT_TYPE) ) 1594 ) { 1595 1596 // Attempt to change the type of password inputs (fails in IE < 9). 1597 if ( 1598 elem.type === 'password' && 1599 !elem.getAttribute(ATTR_INPUT_TYPE) && 1600 changeType(elem, 'text') 1601 ) { 1602 elem.setAttribute(ATTR_INPUT_TYPE, 'password'); 1603 } 1604 1605 // If the placeholder value has changed and the placeholder is 1606 // currently on display we need to change it. 1607 if ( elem.value === elem.getAttribute(ATTR_CURRENT_VAL) ) { 1608 elem.value = placeholder; 1609 } 1610 1611 // Keep a reference to the current placeholder value in case it 1612 // changes via another script. 1613 elem.setAttribute(ATTR_CURRENT_VAL, placeholder); 1614 } 1615 } 1616 } else if ( elem.getAttribute(ATTR_ACTIVE) ) { 1617 hidePlaceholder(elem); 1618 elem.removeAttribute(ATTR_CURRENT_VAL); 1619 } 1620 } 1621 1622 // If live updates are not enabled cancel the timer. 1623 if ( !liveUpdates ) { 1624 clearInterval(timer); 1625 } 1626 }, UPDATE_INTERVAL); 1627 1628 // Disabling placeholders before unloading the page prevents flash of 1629 // unstyled placeholders on load if the page was refreshed. 1630 addEventListener(global, 'beforeunload', function () { 1631 Placeholders.disable(); 1632 }); 1633 1634 // 1635 // Utility functions 1636 // 1637 1638 // No-op (used in place of public methods when native support is detected). 1639 function noop() {} 1640 1641 // Avoid IE9 activeElement of death when an iframe is used. 1642 // 1643 // More info: 1644 // - http://bugs.jquery.com/ticket/13393 1645 // - https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408 1646 function safeActiveElement() { 1647 try { 1648 return document.activeElement; 1649 } catch ( err ) {} 1650 } 1651 1652 // Check whether an item is in an array. We don't use Array.prototype.indexOf 1653 // so we don't clobber any existing polyfills. This is a really simple 1654 // alternative. 1655 function inArray( arr, item ) { 1656 for ( var i = 0, len = arr.length; i < len; i++ ) { 1657 if ( arr[ i ] === item ) { 1658 return true; 1659 } 1660 } 1661 return false; 1662 } 1663 1664 // Cross-browser DOM event binding 1665 function addEventListener( elem, event, fn ) { 1666 if ( elem.addEventListener ) { 1667 return elem.addEventListener(event, fn, false); 1668 } 1669 if ( elem.attachEvent ) { 1670 return elem.attachEvent('on' + event, fn); 1671 } 1672 } 1673 1674 // Move the caret to the index position specified. Assumes that the element 1675 // has focus. 1676 function moveCaret( elem, index ) { 1677 var range; 1678 if ( elem.createTextRange ) { 1679 range = elem.createTextRange(); 1680 range.move('character', index); 1681 range.select(); 1682 } else if ( elem.selectionStart ) { 1683 elem.focus(); 1684 elem.setSelectionRange(index, index); 1685 } 1686 } 1687 1688 // Attempt to change the type property of an input element. 1689 function changeType( elem, type ) { 1690 try { 1691 elem.type = type; 1692 return true; 1693 } catch ( e ) { 1694 // You can't change input type in IE8 and below. 1695 return false; 1696 } 1697 } 1698 1699 function handleElem( node, callback ) { 1700 1701 // Check if the passed in node is an input/textarea (in which case it can't 1702 // have any affected descendants). 1703 if ( node && node.getAttribute(ATTR_CURRENT_VAL) ) { 1704 callback(node); 1705 } else { 1706 1707 // If an element was passed in, get all affected descendants. Otherwise, 1708 // get all affected elements in document. 1709 var handleInputs = node ? node.getElementsByTagName('input') : input
1709s; 1710 var handleTextareas = node ? node.getElementsByTagName('textarea') : textareas; 1711 1712 var handleInputsLength = handleInputs ? handleInputs.length : 0; 1713 var handleTextareasLength = handleTextareas ? handleTextareas.length : 0; 1714 1715 // Run the callback for each element. 1716 var len = handleInputsLength + handleTextareasLength; 1717 var elem; 1718 for ( var i = 0; i < len; i++ ) { 1719 1720 elem = i < handleInputsLength ? 1721 handleInputs[ i ] : 1722 handleTextareas[ i - handleInputsLength ]; 1723 1724 callback(elem); 1725 } 1726 } 1727 } 1728 1729 // Return all affected elements to their normal state (remove placeholder 1730 // value if present). 1731 function disablePlaceholders( node ) { 1732 handleElem(node, hidePlaceholder); 1733 } 1734 1735 // Show the placeholder value on all appropriate elements. 1736 function enablePlaceholders( node ) { 1737 handleElem(node, showPlaceholder); 1738 } 1739 1740 // Hide the placeholder value on a single element. Returns true if the 1741 // placeholder was hidden and false if it was not (because it wasn't visible 1742 // in the first place). 1743 function hidePlaceholder( elem, keydownValue ) { 1744 1745 var valueChanged = !!keydownValue && elem.value !== keydownValue; 1746 var isPlaceholderValue = elem.value === elem.getAttribute(ATTR_CURRENT_VAL); 1747 1748 if ( 1749 ( valueChanged || isPlaceholderValue ) && 1750 elem.getAttribute(ATTR_ACTIVE) === 'true' 1751 ) { 1752 1753 elem.removeAttribute(ATTR_ACTIVE); 1754 elem.value = elem.value.replace(elem.getAttribute(ATTR_CURRENT_VAL), ''); 1755 elem.className = elem.className.replace(classNameRegExp, ''); 1756 1757 // Restore the maxlength value. Old FF returns -1 if attribute not set. 1758 // See GH-56. 1759 var maxLength = elem.getAttribute(ATTR_MAXLENGTH); 1760 if ( parseInt(maxLength, 10) >= 0 ) { 1761 elem.setAttribute('maxLength', maxLength); 1762 elem.removeAttribute(ATTR_MAXLENGTH); 1763 } 1764 1765 // If the polyfill has changed the type of the element we need to change 1766 // it back. 1767 var type = elem.getAttribute(ATTR_INPUT_TYPE); 1768 if ( type ) { 1769 elem.type = type; 1770 } 1771 1772 return true; 1773 } 1774 1775 return false; 1776 } 1777 1778 // Show the placeholder value on a single element. Returns true if the 1779 // placeholder was shown and false if it was not (because it was already 1780 // visible). 1781 function showPlaceholder( elem ) { 1782 1783 var val = elem.getAttribute(ATTR_CURRENT_VAL); 1784 1785 if ( elem.value === '' && val ) { 1786 1787 elem.setAttribute(ATTR_ACTIVE, 'true'); 1788 elem.value = val; 1789 elem.className += ' ' + placeholderClassName; 1790 1791 // Store and remove the maxlength value. 1792 var maxLength = elem.getAttribute(ATTR_MAXLENGTH); 1793 if ( !maxLength ) { 1794 elem.setAttribute(ATTR_MAXLENGTH, elem.maxLength); 1795 elem.removeAttribute('maxLength'); 1796 } 1797 1798 // If the type of element needs to change, change it (e.g. password 1799 // inputs). 1800 var type = elem.getAttribute(ATTR_INPUT_TYPE); 1801 if ( type ) { 1802 elem.type = 'text'; 1803 } else if ( elem.type === 'password' && changeType(elem, 'text') ) { 1804 elem.setAttribute(ATTR_INPUT_TYPE, 'password'); 1805 } 1806 1807 return true; 1808 } 1809 1810 return false; 1811 } 1812 1813 // Returns a function that is used as a focus event handler. 1814 function makeFocusHandler( elem ) { 1815 return function () { 1816 1817 // Only hide the placeholder value if the (default) hide-on-focus 1818 // behaviour is enabled. 1819 if ( 1820 hideOnInput && 1821 elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && 1822 elem.getAttribute(ATTR_ACTIVE) === 'true' 1823 ) { 1824 1825 // Move the caret to the start of the input (this mimics the behaviour 1826 // of all browsers that do not hide the placeholder on focus). 1827 moveCaret(elem, 0); 1828 } else { 1829 1830 // Remove the placeholder. 1831 hidePlaceholder(elem); 1832 } 1833 }; 1834 } 1835 1836 // Returns a function that is used as a blur event handler. 1837 function makeBlurHandler( elem ) { 1838 return function () { 1839 showPlaceholder(elem); 1840 }; 1841 } 1842 1843 // Returns a function that is used as a submit event handler on form elements 1844 // that have children affected by this polyfill. 1845 function makeSubmitHandler( form ) { 1846 return function () { 1847 1848 // Turn off placeholders on all appropriate descendant elements. 1849 disablePlaceholders(form); 1850 }; 1851 } 1852 1853 // Functions that are used as a event handlers when the hide-on-input 1854 // behaviour has been activated - very basic implementation of the 'input' 1855 // event. 1856 function makeKeydownHandler( elem ) { 1857 return function ( e ) { 1858 keydownVal = elem.value; 1859 1860 // Prevent the use of the arrow keys (try to keep the cursor before the 1861 // placeholder). 1862 if ( 1863 elem.getAttribute(ATTR_ACTIVE) === 'true' && 1864 keydownVal === elem.getAttribute(ATTR_CURRENT_VAL) && 1865 inArray(badKeys, e.keyCode) 1866 ) { 1867 if ( e.preventDefault ) { 1868 e.preventDefault(); 1869 } 1870 return false;
1871 } 1872 }; 1873 } 1874 1875 function makeKeyupHandler(elem) { 1876 return function () { 1877 hidePlaceholder(elem, keydownVal); 1878 1879 // If the element is now empty we need to show the placeholder 1880 if ( elem.value === '' ) { 1881 elem.blur(); 1882 moveCaret(elem, 0); 1883 } 1884 }; 1885 } 1886 1887 function makeClickHandler(elem) { 1888 return function () { 1889 if ( 1890 elem === safeActiveElement() && 1891 elem.value === elem.getAttribute(ATTR_CURRENT_VAL) && 1892 elem.getAttribute(ATTR_ACTIVE) === 'true' 1893 ) { 1894 moveCaret(elem, 0); 1895 } 1896 }; 1897 } 1898 1899 // Bind event handlers to an element that we need to affect with the 1900 // polyfill. 1901 function newElement( elem ) { 1902 1903 // If the element is part of a form, make sure the placeholder string is 1904 // not submitted as a value. 1905 var form = elem.form; 1906 if ( form && typeof form === 'string' ) { 1907 1908 // Get the real form. 1909 form = document.getElementById(form); 1910 1911 // Set a flag on the form so we know it's been handled (forms can contain 1912 // multiple inputs). 1913 if ( !form.getAttribute(ATTR_FORM_HANDLED) ) { 1914 addEventListener(form, 'submit', makeSubmitHandler(form)); 1915 form.setAttribute(ATTR_FORM_HANDLED, 'true'); 1916 } 1917 } 1918 1919 // Bind event handlers to the element so we can hide/show the placeholder 1920 // as appropriate. 1921 addEventListener(elem, 'focus', makeFocusHandler(elem)); 1922 addEventListener(elem, 'blur', makeBlurHandler(elem)); 1923 1924 // If the placeholder should hide on input rather than on focus we need 1925 // additional event handlers 1926 if (hideOnInput) { 1927 addEventListener(elem, 'keydown', makeKeydownHandler(elem)); 1928 addEventListener(elem, 'keyup', makeKeyupHandler(elem)); 1929 addEventListener(elem, 'click', makeClickHandler(elem)); 1930 } 1931 1932 // Remember that we've bound event handlers to this element. 1933 elem.setAttribute(ATTR_EVENTS_BOUND, 'true'); 1934 elem.setAttribute(ATTR_CURRENT_VAL, placeholder); 1935 1936 // If the element doesn't have a value and is not focussed, set it to the 1937 // placeholder string. 1938 if ( hideOnInput || elem !== safeActiveElement() ) { 1939 showPlaceholder(elem); 1940 } 1941 } 1942 1943}(this) ); 1944// IE spupport comes in IE10 1945(function rAFPolyfill() { 1946 var lastTime, vendors, x; 1947 lastTime = 0; 1948 vendors = ["webkit", "moz"]; 1949 x = 0; 1950 while (x < vendors.length && !window.requestAnimationFrame) { 1951 window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"]; 1952 window.cancelAnimationFrame = window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"]; 1953 ++x; 1954 } 1955 if (!window.requestAnimationFrame) { 1956 window.requestAnimationFrame = function(callback, element) { 1957 var currTime, id, timeToCall; 1958 currTime = new Date().getTime(); 1959 timeToCall = Math.max(0, 16 - (currTime - lastTime)); 1960 id = window.setTimeout(function() { 1961 callback(currTime + timeToCall); 1962 }, timeToCall); 1963 lastTime = currTime + timeToCall; 1964 return id; 1965 }; 1966 } 1967 if (!window.cancelAnimationFrame) { 1968 window.cancelAnimationFrame = function(id) { 1969 clearTimeout(id); 1970 }; 1971 } 1972})(); 1973 1974 1975 1976(function($) { 1977 'use strict'; 1978 1979 var MK = window.MK || {}; 1980 1981 /** 1982 * MK.core holds most important methods that bootstraps whole application 1983 * 1984 * @type {Object} 1985 */ 1986 MK.core = {}; 1987 1988 1989 1990 /** 1991 * State for referance of already loaded script files 1992 * @type {Array} 1993 */ 1994 var _loadedDependencies = []; 1995 1996 /** 1997 * State of queue represented as pairs of script ref => callback 1998 * @type {Object} 1999 */ 2000 var _inQueue = {}; 2001 2002 /** 2003 * Initializes all components in given scope (object or DOM reference) based on data attribute and 'pointer' css class '.js-el'. 2004 * DOM work is reduced by single traversing for pointer class and later filtering through cached object. It expects init() method 2005 * on every component. Component itself should be defined in MK.component namespace and assign to DOM element via data-mk-component. 2006 * Use it once on DOM ready with document as a scope. For partial initialization after aja
2006x operations pass as a scope element 2007 * where new DOM was inserted. 2008 * 2009 * @param {string|object} 2010 */ 2011 MK.core.initAll = function( scope ) { 2012 var $el = $( scope ).find( '.js-el' ), // single traversing 2013 $components = $el.filter( '[data-mk-component]' ), 2014 component = null; 2015 2016 2017 // initialize component 2018 var init = function init(name, el) { 2019 var $el = $(el); 2020 2021 if ( $el.data('init-' + name) ) return; // do not initialize the same module twice 2022 2023 if ( typeof MK.component[ name ] !== 'function' ) console.log('Component init error: ', name); 2024 else { 2025 component = new MK.component[ name ]( el ); 2026 component.init(); 2027 $el.data('init-' + name, true); // mark as initialised 2028 // TODO add name 2029 MK.utils.eventManager.publish('component-inited'); 2030 } 2031 }; 2032 2033 $components.each( function() { 2034 var self = this, 2035 $this = $( this ), 2036 names = $this.data( 'mk-component' ); 2037 2038 if( typeof names === 'string' ) { 2039 var name = names; // containes only single name. Keep it transparent. 2040 init(name, self); 2041 } else { 2042 names.forEach( function( name ) { 2043 init(name, self); 2044 }); 2045 } 2046 }); 2047 }; 2048 2049 /** 2050 * Async loader for 3rd party plugins available from within theme or external CDNs / APIs. 2051 * Take one argument as callback which is run when loading is finished. Also keeps track of already loaded scripts 2052 * and prevent duplication. Holds in queue multiple callbacks that where defined in different places but depend on the 2053 * same plugin. 2054 * 2055 * TODO: heavy test for multiple dependencies and crosssharing one dependency and different one dependency in queue, 2056 * bulletproof with single dependency 2057 * 2058 * @example MK.core.loadDependencies([MK.core.path.plugins + 'plugin.js'], function() { 2059 * // do something when plugin is loaded 2060 * }) 2061 * 2062 * @param {array} 2063 * @param {function} 2064 */ 2065 MK.core.loadDependencies = function( dependencies, callback ) { 2066 var _callback = callback || function() {}; 2067 2068 if( !dependencies ) { 2069 // If no dependencies defined then run _callback imidietelly 2070 _callback(); 2071 return; 2072 } 2073 2074 // Check for new dependencies 2075 var newDeps = dependencies.map( function( dep ) { 2076 if( _loadedDependencies.indexOf( dep ) === -1 ) { 2077 if( typeof _inQueue[ dep ] === 'undefined' ) { 2078 // console.log( dep ); 2079 return dep; 2080 } else { 2081 _inQueue[ dep ].push( _callback ); 2082 return true; 2083 } 2084 } else { 2085 return false; 2086 } 2087 }); 2088 2089 // The dependency is not new but it's not resolved yet 2090 // Callback is added to queue that will be run after the script is loaded 2091 // Don't run callback just yet. 2092 if( newDeps[0] === true ) {
2093 // console.log('Waiting for ' + dependencies[0]); 2094 return; 2095 } 2096 2097 // Dependency was loaded previously. We can run callback safely 2098 if( newDeps[0] === false ) { 2099 _callback(); 2100 return; 2101 } 2102 2103 // Create queue and relationship script -> callback array to track 2104 // all callbacks that waits for ths script 2105 var queue = newDeps.map( function( script ) { 2106 // console.log( script ); 2107 _inQueue[ script ] = [ _callback ]; 2108 return $.getCachedScript( script ); 2109 }); 2110 2111 // Callbacks invoking 2112 var onLoad = function onLoad() { 2113 var index; 2114 newDeps.map( function( loaded ) { 2115 _inQueue[ loaded ].forEach( function( callback ) { 2116 callback(); 2117 }); 2118 delete _inQueue[ loaded ]; 2119 _loadedDependencies.push( loaded ); 2120 }); 2121 }; 2122 2123 // Run callbacks when promise is resolved 2124 $.when.apply( null, queue ).done( onLoad ); 2125 }; 2126 2127 /** 2128 * Single namespace for all paths recuired in application. 2129 * @type {Object} 2130 */ 2131 MK.core.path = { 2132 theme : mk_theme_dir, 2133 plugins : mk_theme_js_path + '/plugins/async/min/', 2134 ajaxUrl : window.PHP.ajax 2135 }; 2136 2137 2138})(jQuery); 2139(function($) { 2140 'use strict'; 2141 2142 var MK = window.MK || {}; 2143 MK.utils = window.MK.utils || {}; 2144 2145 /** 2146 * Enables to evaluate common methods through DOM JSON references by invoking from object with bracket notation MK.utils[var][var] 2147 * @type {Object} 2148 */ 2149 MK.utils.actions = {}; 2150 2151 MK.utils.actions.activate = function (el) { 2152 $(el).addClass('is-active'); 2153 }; 2154 2155 MK.utils.actions.deactivate = function (el) { 2156 $(el).removeClass('is-active'); 2157 }; 2158 2159}(jQuery)); 2160(function($) { 2161 'use strict'; 2162 2163 var MK = window.MK || {}; 2164 MK.utils = window.MK.utils || {}; 2165 2166 /** 2167 * Gets user browser and its version 2168 * @return {Object} => {name, version} 2169 */ 2170 MK.utils.browser = (function() { 2171 var dataBrowser = [ 2172 {string: navigator.userAgent, subString: "Edge", identity: "Edge"}, 2173 {string: navigator.userAgent, subString: "Chrome", identity: "Chrome"}, 2174 {string: navigator.userAgent, subString: "MSIE", identity: "IE"}, 2175 {string: navigator.userAgent, subString: "Trident", identity: "IE"}, 2176 {string: navigator.userAgent, subString: "Firefox", identity: "Firefox"}, 2177 {string: navigator.userAgent, subString: "Safari", identity: "Safari"}, 2178 {string: navigator.userAgent, subString: "Opera", identity: "Opera"} 2179 ]; 2180 2181 var versionSearchString = null; 2182 var searchString = function (data) { 2183 for (var i = 0; i < data.length; i++) { 2184 var dataString = data[i].string; 2185 versionSearchString = data[i].subString; 2186 2187 if (dataString.indexOf(data[i].subString) !== -1) { 2188 return data[i].identity; 2189 } 2190 } 2191 }; 2192 2193 var searchVersion = function (dataString) { 2194 var index = dataString.indexOf(versionSearchString); 2195 if (index === -1) { 2196 return; 2197 } 2198 2199 var rv = dataString.indexOf("rv:"); 2200 if (versionSearchString === "Trident" && rv !== -1) { 2201 return parseFloat(dataString.substring(rv + 3)); 2202 } else { 2203 return parseFloat(dataString.substring(index + versionSearchString.length + 1)); 2204 } 2205 }; 2206 2207 var name = searchString(dataBrowser) || "Other"; 2208 var version = searchVersion(navigator.userAgent) || searchVersion(navigator.appVersion) || "Unknown"; 2209 2210 // Expose for css 2211 $('html').addClass(name).addClass(name + version); 2212 2213 2214 return { 2215 name : name, 2216 version : version 2217 }; 2218 2219 })(); 2220 2221 /** 2222 * Gets user operating system 2223 * @return {String} 2224 */ 2225 MK.utils.OS = (function() { 2226 if (navigator.appVersion.indexOf("Win")!=-1) return "Windows"; 2227 if (navigator.appVersion.indexOf("Mac")!=-1) return "OSX"; 2228 if (navigator.appVersion.indexOf("X11")!=-1) return "UNIX"; 2229 if (navigator.appVersion.indexOf("Linux")!=-1) return "Linux"; 2230 })(); 2231 2232 /** 2233 * Check if mobile device. 2234 * @return {Boolean} 2235 */ 2236 MK.utils.isMobile = function() { 2237 // Problems with bigger tablets as users raport differences with behaviour. Switch to navigator sniffing 2238 // return ('ontouchstart' in document.documentElement) && matchMedia( '(max-width: 1024px)' ).matches; 2239 2240 // http://www.abeautifulsite.net/detecting-mobile-devices-with-javascript/ 2241 // if it still brings problem try to move to more sophisticated solution like 2242 // apachemobilefilter.org 2243 // detectright.com 2244 // web.wurfl.io 2245 // 2246 // Seems as best solution here: 2247 // hgoebl.github.io/mobile-detect.js 2248 2249 function android() { 2250 return navigator.userAgent.match(/Android/i); 2251 } 2252 2253 function blackBerry() { 2254 return navigator.userAgent.match(/BlackBerry/i); 2255 } 2256 2257 function iOS() { 2258 return navigator.userAgent.match(/iPhone|iPad|iPod/i); 2259 } 2260 2261 function opera() { 2262 return navigator.userAgent.match(/Opera Mini/i); 2263 } 2264 2265 function windows() { 2266 return navigator.userAgent.match(/IEMobile/i); 2267 } 2268 2269 return (android() || blackBerry() || iOS() || opera() || windows() || matchMedia( '(max-width: 1024px)' ).matches); 2270 2271 }; 2272 2273 /** 2274 * Check if menu is switched to responsive state based on user width settings 2275 * @return {Boolean} 2276 */ 2277 MK.utils.isResponsiveMenuState = function() { 2278 return window.matchMedia( '(max-width: '+ mk_responsive_nav_width +'px)').matches; 2279 }; 2280 2281 2282 2283 MK.utils.getUrlParameter = function getUrlParameter(sParam) { 2284 var sPageURL = decodeURIComponent(window.location.search.substring(1)), 2285 sURLVariables = sPageURL.split('&'), 2286 sParameterName, 2287 i; 2288 2289 for (i = 0; i < sURLVariables.length; i++) { 2290 sParameterName = sURLVariables[i].split('='); 2291 2292 if (sParameterName[0] === sParam) { 2293 return sParameterName[1] === undefined ? true : sParameterName[1]; 2294 } 2295 } 2296 }; 2297 2298 2299 MK.utils.isSmoothScroll = (function() { 2300 var isUserChoice = (mk_smooth_scroll === 'true'); 2301 2302 // We notify our app about smooth scroll option when user choose it from admin panel. 2303 return isUserChoice; 2304 }()); 2305 2306}(jQuery)); 2307(function($) { 2308 'use strict'; 2309 2310 var MK = window.MK || {}; 2311 MK.utils = window.MK.utils || {}; 2312 2313 /** 2314 * Basic implementation of pub / sub pattern to avoid tight coupling with direct module communication 2315 * @type {Object} 2316 */ 2317 MK.utils.eventManager = {}; 2318 2319 /** 2320 * Subscribe to custom event and run callbacks 2321 * @param {String} 2322 * @param {Function} 2323 * 2324 * @usage MK.utils.eventManager.subscribe('event', function(e, params) {} ) 2325 */ 2326 MK.utils.eventManager.subscribe = function(evt, func) { 2327 $(this).on(evt, func); 2328 }; 2329 2330 /** 2331 * Unsubscribe from custom event 2332 * @param {String} 2333 * @param {Function} 2334 */ 2335 MK.utils.eventManager.unsubscribe = function(evt, func) { 2336 $(this).off(evt, func); 2337 }; 2338 2339 /** 2340 * Publish custom event to notify appliaction about state change 2341 * @param {String} 2342 * 2343 * @usage MK.utils.eventManager.publish('event', { 2344 * param: val 2345 * }) 2346 */ 2347 MK.utils.eventManager.publish = function(evt, params) { 2348 $(this).trigger(evt, [params]); 2349 }; 2350 2351}(jQuery)); 2352(function($) { 2353 'use strict'; 2354 2355 var MK = window.MK || {}; 2356 MK.utils = window.MK.utils || {}; 2357 2358 /** 2359 * Control browser fullscreen mode 2360 * @type {Object} 2361 */ 2362 MK.utils.fullscreen = {}; 2363 2364 // TODO: move to namespace 2365 MK.utils.launchIntoFullscreen = function ( element ) { 2366 if(element.requestFullscreen) { 2367 element.requestFullscreen(); 2368 } else if(element.mozRequestFullScreen) { 2369 element.mozRequestFullScreen(); 2370 } else if(element.webkitRequestFullscreen) { 2371 element.webkitRequestFullscreen(); 2372 } else if(element.msRequestFullscreen) { 2373 element.msRequestFullscreen(); 2374 } 2375 }; 2376 2377 MK.utils.exitFullscreen = function () { 2378 if(document.exitFullscreen) { 2379 document.exitFullscreen(); 2380 } else if(document.mozCancelFullScreen) { 2381 document.mozCancelFullScreen(); 2382 } else if(document.webkitExitFullscreen) { 2383 document.webkitExitFullscreen(); 2384 } 2385 }; 2386 2387}(jQuery)); 2388(function($) { 2389 'use strict'; 2390 2391 var MK = window.MK || {}; 2392 MK.utils = window.MK.utils || {}; 2393 2394 MK.utils.misc = {}; 2395 // TODO: move to namespace 2396 2397 /** 2398 * Get all top offsets from jQuery collection 2399 * 2400 * @param {$Objects} 2401 * @return {Aray} 2402 */ 2403 MK.utils.offsets = function( $els ) { 2404 return $.map( $els, function( el ) { 2405 return $( el ).offset().top; 2406 }); 2407 }; 2408 2409 /** 2410 * Retrive from array of numbers first number that is higher than given parameter 2411 * 2412 * @param {Number} 2413 * @param {Array} 2414 * @return {Number} 2415 */ 2416 MK.utils.nextHigherVal = function( val, arr ) { 2417 var i = 0, 2418 higher = null; 2419 2420 var check = function() { 2421 if( val > arr[ i ]) { 2422 i += 1; 2423 check(); 2424 } else { 2425 higher = arr[ i ]; 2426 } 2427 }; 2428 check(); 2429 2430 return higher; 2431 }; 2432 2433 2434 MK.utils.throttle = function( delay, fn ) { 2435 var last; 2436 var deferTimer; 2437 2438 return function() { 2439 var context = this; 2440 var args = arguments; 2441 var now = +new Date; 2442 if( last && now < last + delay ) { 2443 clearTimeout( deferTimer ); 2444 deferTimer = setTimeout( function() { 2445 last = now; fn.apply( context, args ); 2446 }, delay ); 2447 } else { 2448 last = now; 2449 fn.apply( context, args ); 2450 } 2451 }; 2452 }; 2453 2454 MK.utils.isElementInViewport = function( el ) { 2455 var elemTop = el.getBoundingClientRect().top; 2456 var isVisible = (elemTop < window.innerHeight); 2457 return isVisible; 2458 }; 2459 2460})(jQuery); 2461(function($) { 2462 'use strict'; 2463 2464 var MK = window.MK || {}; 2465 MK.utils = window.MK.utils || {}; 2466 2467 /** 2468 * Scrolls page to static pixel offset 2469 * @param {Number} 2470 */ 2471 MK.utils.scrollTo = function( offset ) { 2472 $('html, body').stop().animate({ 2473 scrollTop: offset 2474 }, { 2475 duration: 1200, 2476 easing: "easeInOutExpo" 2477 }); 2478 }; 2479 2480 /** 2481 * Scrolls to element passed in as object or DOM reference 2482 * @param {String|Object} 2483 */ 2484 MK.utils.scrollToAnchor = function( hash ) { 2485 // Escape meta-chars from hash name only. 2486 hash = hash.substring(1).replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, "\\$&"); 2487 hash = "#" + hash; 2488 var $target = $( hash ); 2489 // console.log( hash ); 2490 2491 if( ! $target.length ) return; 2492 2493 var offset = $target.offset().top; 2494 offset = offset - MK.val.offsetHeaderHeight( offset ); 2495 2496 if( hash === '#top-of-page' ) window.history.replaceState( undefined, undefined, ' ' ); 2497 else window.history.replaceState( undefined, undefined, hash ); 2498 2499 MK.utils.scrollTo( offset ); 2500 }; 2501 2502 /** 2503 * Controls native scroll behaviour 2504 * @return {Object} => {disable, enable} 2505 */ 2506 MK.utils.scroll = (function() { 2507 // 37 - left arror, 38 - up arrow, 39 right arrow, 40 down arrow 2508 var keys = [38, 40]; 2509 2510 function preventDefault(e) { 2511 e = e || window.event; 2512 e.preventDefault(); 2513 e.returnValue = false; 2514 } 2515 2516 function wheel(e) { 2517 preventDefault(e); 2518 } 2519 2520 function keydown(e) { 2521 for (var i = keys.length; i--;) { 2522 if (e.keyCode === keys[i]) { 2523 preventDefault(e); 2524 return; 2525 } 2526 } 2527 } 2528 2529 function disableScroll() { 2530 if (window.addEventListener) { 2531 window.addEventListener('DOMMouseScroll', wheel, false); 2532 } 2533 window.onmousewheel = document.onmousewheel = wheel; 2534 document.onkeydown = keydown; 2535 } 2536 2537 function enableScroll() { 2538 if (window.removeEventListener) { 2539 window.removeEventListener('DOMMouseScroll', wheel, false); 2540 } 2541 window.onmousewheel = document.onmousewheel = document.onkeydown = null; 2542 } 2543 2544 return { 2545 disable : disableScroll, 2546 enable : enableScroll 2547 }; 2548 2549 })(); 2550 2551 /** 2552 * Checks if passed link element has anchor inside current page. Returns string like '#anchor' if so or false 2553 * @param {String|Object} 2554 * @return {String|Boolean} 2555 */ 2556 MK.utils.detectAnchor = function( el ) { 2557 var $this = $( el ), 2558 loc = window.location, 2559 currentPage = loc.origin + loc.pathname, 2560 href = $this.attr( 'href' ), 2561 linkSplit = (href) ? href.split( '#' ) : '', 2562 hrefPage = linkSplit[0] ? linkSplit[0] : '', 2563 hrefHash = linkSplit[1] ? linkSplit[1] : ''; 2564 2565 if( typeof hrefHash !== 'undefined' && hrefHash !== '' ) { 2566 return '#' + hrefHash; 2567 } else { 2568 return false;
2569 } 2570 }; 2571 2572 /** 2573 * This should be invoked only on page load. 2574 * Scrolls to anchor from address bar 2575 */ 2576 MK.utils.scrollToURLHash = function() { 2577 var loc = window.location, 2578 hash = loc.hash; 2579 2580 if ( hash.length && hash.substring(1).length ) { 2581 // !loading is added early after DOM is ready to prevent native jump to anchor 2582 hash = hash.replace( '!loading', '' ); 2583 2584 // Wait for one second before animating 2585 // Most of UI animations should be done by then and async operations complited 2586 setTimeout( function() { 2587 MK.utils.scrollToAnchor( hash ); 2588 }, 1000 ); 2589 2590 // Right after reset back address bar 2591 setTimeout( function() { 2592 window.history.replaceState(undefined, undefined, hash); 2593 }, 1001); 2594 } 2595 }; 2596 2597 /** 2598 * Scroll Spy implementation. Spy dynamic offsets of elements or static pixel offset 2599 * @param {Number|Element} 2600 * @param {Object} => callback object {before, active, after} 2601 */ 2602 MK.utils.scrollSpy = function( toSpy, config ) { 2603 var $window = $( window ), 2604 container = document.getElementById( 'mk-theme-container' ), 2605 isObj = ( typeof toSpy === 'object' ), 2606 offset = (isObj) ? MK.val.dynamicOffset( toSpy, config.position, config.threshold ) : function() { return toSpy; }, 2607 height = (isObj) ? MK.val.dynamicHeight( toSpy ) : function() { return 0; }, 2608 cacheVals = {}, 2609 _p = 'before'; // current position 2610 2611 var checkPosition = function() { 2612 var s = MK.val.scroll(), 2613 o = offset(), 2614 h = height(); 2615 2616 if( s < o && _p !== 'before' ) { 2617 // console.log( toSpy, 'before' ); 2618 if( config.before ) config.before(); 2619 _p = 'before'; 2620 } 2621 else if( s >= o && s <= o + h && _p !== 'active' ) { 2622 // console.log( toSpy, 'active' ); 2623 if( config.active ) config.active( o ); 2624 _p = 'active'; 2625 } 2626 else if( s > o + h && _p !== 'after' ) { 2627 // console.log( toSpy, 'after' ); 2628 if( config.after) config.after( o + h ); 2629 _p = 'after'; 2630 } 2631 }; 2632 2633 var rAF = function() { 2634 window.requestAnimationFrame( checkPosition ); 2635 }; 2636 2637 var exportVals = function() { 2638 return cacheVals; 2639 }; 2640 2641 var updateCache = function() { 2642 var o = offset(), 2643 h = height(); 2644 2645 cacheVals = { 2646 before : o - $window.height(), 2647 active : o, 2648 after : o + h 2649 }; 2650 }; 2651 2652 if( config.cache ) { 2653 config.cache( exportVals ); 2654 } 2655 2656 checkPosition(); 2657 $window.on( 'load', checkPosition ); 2658 $window.on( 'resize', checkPosition ); 2659 $window.on( 'mouseup', checkPosition ); 2660 window.addResizeListener( container, checkPosition ); 2661 2662 $window.on( 'scroll', rAF ); 2663 2664 updateCache(); 2665 $window.on( 'load', updateCache ); 2666 $window.on( 'resize', updateCache ); 2667 window.addResizeListener( container, updateCache ); 2668 }; 2669 2670}(jQuery)); 2671(function($) { 2672 'use strict'; 2673 2674 // Create delagation event handler to behave as "live" listener. We may provide new elements with ajax etc later 2675 // Just add js-taphover class whatever element you'd like to immidietely bring hover on touch devices 2676 $("body").on("click touchend", '.js-taphover', function (e) { 2677 var $link = $(e.currentTarget); // grab target 2678 var $target = $(e.target); 2679 2680 // Rather than ":hover" state we operate on ".hover" class which gives us more control and chance to emulate it on click 2681 // yet it is easy to reason about in our CSS 2682 if ($link.hasClass('hover')) { 2683 return true; 2684 } else if ( MK.utils.isMobile() ) { 2685 if ( ($target.hasClass('hover-icon') || $target.closest('.hover-icon').length) && !$target.closest('.js-taphover').hasClass('hover') ) { 2686 e.preventDefault(); 2687 } 2688 $link.addClass('hover'); 2689 $('.js-taphover').not(e.currentTarget).removeClass('hover'); // remove it from previous element 2690 e.stopPropagation(); // do not leak to document root if expected element was touched 2691 } 2692 }); 2693 2694 // Whenever click leaks to the root romve all hover classes 2695 $(document).on("click", function(e) { 2696 $('.js-taphover').removeClass('hover'); 2697 }); 2698 2699}(jQuery)); 2700// (function() { 2701// 'use strict'; 2702 2703// // Make sure the video behaves like background-size: cover 2704// window.videoCover = function( holderSelector, videoSelector ) { 2705// var videos = document.querySelectorAll( videoSelector ), 2706// holder = document.querySelectorAll( holderSelector )[0]; 2707 2708// [].forEach.call(videos, function(video) { 2709 2710// var videoAspectRatio; 2711
2712// resizeBackground(); 2713 2714// video.onloadedmetadata = function() { 2715// // get images aspect ratio 2716// videoAspectRatio = this.height / this.width; 2717// // attach resize event and fire it once 2718// window.onresize = resizeBackground; 2719// resizeBackground(); 2720// }; 2721 2722// function resizeBackground() { 2723// // get window size and aspect ratio 2724// var holderWidth = holder.innerWidth, 2725// holderHeight = holder.innerHeight, 2726// holderAspectRatio = holderHeight / holderWidth; 2727 2728// //compare holder ratio to image ratio so you know which way the image should fill 2729// if ( holderAspectRatio < videoAspectRatio ) { 2730// // we are fill width 2731// video.style.width = holderWidth + "px"; 2732// // and applying the correct aspect to the height now 2733// video.style.height = (holderWidth * videoAspectRatio) + "px"; // this can be margin if your element is not positioned relatively, absolutely or fixed 2734// // make sure image is always centered 2735// video.style.left = "0px";
2736// video.style.top = (holderHeight - (holderWidth * videoAspectRatio)) / 2 + "px"; 2737// } else { // same thing as above but filling height instead 2738// video.style.height = holderHeight + "px"; 2739// video.style.width = (holderHeight / videoAspectRatio) + "px"; 2740// video.style.left = (holderWidth - (holderHeight / videoAspectRatio)) / 2 + "px"; 2741// video.style.top = "0px"; 2742// } 2743// } 2744 2745// }); 2746// }; 2747 2748// }()); 2749// 2750// 2751// 2752// TODO it is temp only. make it as a plugin 2753 2754(function($) { 2755 'use strict'; 2756 2757 var $videoHolder = $('.mk-center-video'), 2758 $wrapper = $videoHolder.parent(), 2759 baseAspectRatio = 56.25; 2760 2761 var wrapperHeight, 2762 wrapperWidth, 2763 wrapperAspectRatio; 2764 2765 function calc() { 2766 wrapperHeight = $wrapper.height(); 2767 wrapperWidth = $wrapper.width(); 2768 wrapperAspectRatio = (wrapperHeight / wrapperWidth) * 100; 2769 } 2770 2771 function apply() { 2772 var width = (wrapperAspectRatio / baseAspectRatio) * 100, 2773 widthOverflow = (width - 100); 2774 2775 $videoHolder.css({ 2776 'padding-top': wrapperAspectRatio + '%', 2777 'width': width + '%', 2778 'left': -(widthOverflow / 2) + '%' 2779 }); 2780 } 2781 2782 function reset() { 2783 $videoHolder.css({ 2784 'padding-top': baseAspectRatio + '%', 2785 'width': 100 + '%', 2786 'left': 0 2787 }); 2788 } 2789 2790 function setCover() { 2791 reset(); 2792 calc(); 2793 if(wrapperAspectRatio > baseAspectRatio) apply(); 2794 } 2795 2796 $(window).on('load', setCover); 2797 $(window).on('resize', setCover); 2798 2799 2800}(jQuery)); 2801(function($) { 2802 'use strict'; 2803 2804 var MK = window.MK || {}; 2805 2806 /** 2807 * MK.val is collection of Lambdas responsible for returning up to date values of method type like scrollY or el offset. 2808 * The Lambda is responsible for keeping track of value of a particular property, usually takes as argument an object 2809 * (or DOM reference) and internally creates and updates data that is returned as primitive value - through variable reference. 2810 * 2811 * Benefits of this approach: 2812 * - reduced DOM reads 2813 * - auto-updating values without need for additional logic where methods are called 2814 * - updating values when needed to be updated not read 2815 * 2816 * Downsides: 2817 * - Memory overhead with closures and keeping state in memory ( still beter than read state from DOM, but use wisely - 2818 * do not use it when you really need static value on runtime ) 2819 */ 2820 MK.val = {}; 2821 2822 /** 2823 * Current window offsetY position 2824 * 2825 * @uses MK.val.scroll() 2826 * @return {number} 2827 */ 2828 MK.val.scroll = (function() { 2829 var offset = 0, 2830 $window = $(window), 2831 hasPageYOffset = (window.pageYOffset !== undefined), 2832 body = (document.documentElement || document.body.parentNode || document.body); // cross browser handling 2833 2834 var update = function() { 2835 offset = hasPageYOffset ? window.pageYOffset : body.scrollTop; 2836 }; 2837 2838 var rAF = function() { 2839 window.requestAnimationFrame(update); 2840 }; 2841 2842 update(); 2843 $window.on('load', update); 2844 $window.on('resize', update); 2845 $window.on('scroll', rAF); 2846 2847 return function() { 2848 return offset; 2849 }; 2850 })(); 2851 2852 2853 /** 2854 * Changes number of percent to pixels based on viewport height 2855 * 2856 * @uses MK.val.viewportPercentHeight({percent val}) 2857 * @param {number} 2858 * @return {number} 2859 */ 2860 MK.val.viewportPercentHeight = function(percent) { 2861 return $(window).height() * (percent / 100); 2862 }; 2863 2864 2865 /** 2866 * Wordpress adminbar height based on wp media queries 2867 * @return {Number} 2868 */ 2869 MK.val.adminbarHeight = function() { 2870 if (php.hasAdminbar) { 2871 // apply WP native media-query and sizes 2872 return (window.matchMedia('( max-width: 782px )').matches) ? 46 : 32; 2873 } else { 2874 return 0; 2875 } 2876 }; 2877 2878 2879 /** 2880 * Offset when header becomes sticky. Evaluates viewport % and header height to pixels for according options 2881 * @return {Number} 2882 */ 2883 MK.val.stickyOffset = (function() { 2884 var $header = $('.mk-header').not('.js-header-shortcode').first(); 2885 2886 // We need to have returning function even when header is disabled 2887 if (!$header.length) { 2888 return function() { 2889 return 0; 2890 }; 2891 } 2892 2893 2894 2895 var $toolbar = $header.find('.mk-header-toolbar'), 2896 config = $header.data(), 2897 hasToolbar = $toolbar.length, 2898 toolbarHeight = (hasToolbar) ? $toolbar.height() : 0, 2899 isVertical = (config.headerStyle === 4), 2900 headerHeight = (isVertical) ? 0 : config.height; 2901 2902 var type = ((typeof config.stickyOffset === 'number') ? 'number' : false) || 2903 ((config.stickyOffset === 'header') ? 'header' : false) || 2904 'percent'; 2905 2906 var stickyOffset = 0; 2907 var setOffset = function() { 2908 2909 //we calculate toolbar height for When the device is changed Size 2910 //Toolbar height in responsive state is 0 2911 toolbarHeight = (hasToolbar) ? $toolbar.height() : 0; 2912 2913 if (MK.utils.isResponsiveMenuState()) { 2914 headerHeight = config.responsiveHeight; 2915 2916 if (hasToolbar) { 2917 if ($toolbar.is(':hidden')) { 2918 toolbarHeight = 0; 2919 } 2920 } 2921 } 2922 2923 if (type === 'number') { 2924 stickyOffset = config.stickyOffset; 2925 } else if (type === 'header') { 2926 2927 stickyOffset = headerHeight + toolbarHeight + MK.val.adminbarHeight(); // add all header components here, make them 0 if needed 2928 2929 } else if (type === 'percent') { 2930 stickyOffset = MK.val.viewportPercentHeight(parseInt(config.stickyOffset)); 2931 } 2932 }; 2933 2934 setOffset(); 2935 $(window).on('resize', setOffset); 2936 2937 return function() { 2938 return stickyOffset; 2939 }; 2940 }()); 2941 2942 2943 2944 /** 2945 * Gets header height on particular offsetY position. Use to determine logic for fullHeight, smooth scroll etc. 2946 * Takes one parameter which is offset position we're interested in. 2947 * 2948 * @uses MK.val.offsetHeaderHeight({offset val}) 2949 * @param {number} 2950 * @return {number} 2951 */ 2952 MK.val.offsetHeaderHeight = (function() { // Closure avoids multiple DOM reads. We need to fetch header config only once. 2953 var $header = $('.mk-header').not('.js-header-shortcode').first(); 2954 2955 // We need to have returning function even when header is disabled 2956 if (!$header.length) { 2957 return function() { 2958 return 0; 2959 }; 2960 } 2961 2962 var $toolbar = $header.find('.mk-header-toolbar'), 2963 config = $header.data(), 2964 stickyHeight = config.stickyHeight, 2965 desktopHeight = config.height, 2966 mobileHeight = config.responsiveHeight, 2967 isTransparent = $header.hasClass('transparent-header'), 2968 isSticky = config.stickyStyle.length, 2969 isStickyLazy = config.stickyStyle === 'lazy', 2970 isVertical = config.headerStyle === 4, 2971 hasToolbar = $toolbar.length, 2972 toolbarHeight = hasToolbar ? $toolbar.height() : 0, 2973 bufor = 5; 2974 2975 /**
2976 * The sticky section of header style 2 has fixed height. 2977 * The stickey height option does not affect this header style. 2978 */ 2979 if ( config.headerStyle === 2 ) { 2980 stickyHeight = $header.find( '.mk-header-nav-container' ).outerHeight(); 2981 } 2982 2983 // if header has border bottom we can calculate that (for responsive state) 2984 var $innerHeader = $header.find('.mk-header-inner'); 2985 var hasInnerHeader = $innerHeader.length; 2986 2987 var headerHeight = function(offset) { 2988 2989 toolbarHeight = hasToolbar ? $toolbar.height() : 0 2990 var stickyOffset = MK.val.stickyOffset(); 2991 2992 2993 if (MK.utils.isResponsiveMenuState()) { // Header avaible only on top for mobile 2994 2995 if (hasToolbar && $toolbar.is(':hidden')) { 2996 toolbarHeight = 0; 2997 } 2998 2999 //in responsive state , .mk-header-holder position's changed to "relative" 3000 //and header's border affected to offset,so borders must be calculated 3001 var headerBorder = 0; 3002 headerBorder = parseInt($innerHeader.css('border-bottom-width')); 3003 3004 var totalHeight = mobileHeight + MK.val.adminbarHeight() + toolbarHeight + headerBorder; 3005 3006 if (offset <= totalHeight) return totalHeight; 3007 else return MK.val.adminbarHeight(); 3008 } else { 3009 if (offset <= stickyOffset) { 3010 if (isVertical) { 3011 if (hasToolbar) { 3012 return toolbarHeight + MK.val.adminbarHeight(); 3013 } else { 3014 return MK.val.adminbarHeight(); 3015 } 3016 } else if (isTransparent) { 3017 return MK.val.adminbarHeight(); 3018 } else { 3019 return desktopHeight + toolbarHeight + MK.val.adminbarHeight(); 3020 } // For any other return regular desktop height 3021 } else if (offset > stickyOffset) { 3022 if (isVertical) { 3023 return MK.val.adminbarHeight(); 3024 } else if (!isSticky) { 3025 return MK.val.adminbarHeight(); 3026 } else if (isStickyLazy) { 3027 return MK.val.adminbarHeight(); 3028 } else if (isSticky) { 3029 return stickyHeight + MK.val.adminbarHeight(); 3030 } 3031 } 3032 } 3033 // default to 0 to prevent errors ( need to return number ) 3034 // Anyway make sure all scenarios are covered in IFs 3035 return 0; 3036 }; 3037 3038 return function(offset) { 3039 return headerHeight(offset - MK.val.adminbarHeight()); 3040 }; 3041 })(); 3042 3043 3044 /** 3045 * Gets current offset of given element (passed as object or DOM reference) from top or bottom (default to top) 3046 * of screen with possible threshold (default to 0) 3047 * 3048 * @uses MK.val.dynamicOffset({obj reference}, {'top'|'bottom'}, {threshold val}) 3049 * @param {string|object} 3050 * @param {string} 3051 * @param {number} 3052 * @return {number} 3053 */ 3054 MK.val.dynamicOffset = function(el, position, threshold) { 3055 var $window = $(window), 3056 $el = $(el), 3057 pos = position || 'top', 3058 thr = threshold || 0, 3059 container = document.getElementById('mk-theme-container'), 3060 currentPos = 0; 3061 3062 var offset = 0, 3063 winH = 0, 3064 rect = 0, 3065 x = 0; 3066 3067 var update = function() { 3068 winH = $window.height(); 3069 rect = $el[0].getBoundingClientRect(); 3070 offset = (rect.top + MK.val.scroll()); 3071 x = (pos === 'top') ? MK.val.offsetHeaderHeight(offset) : winH + (rect.height - thr); 3072 currentPos = offset - x - 1; 3073 }; 3074 3075 update(); 3076 $window.on('load', update); 3077 $window.on('resize', update); 3078 window.addResizeListener(container, update); 3079 3080 return function() { 3081 return currentPos; 3082 }; 3083 }; 3084 3085 /** 3086 * Gets current height of given element (passed as object or DOM reference) 3087 * 3088 * @uses MK.val.dynamicHeight({obj reference}) 3089 * @param {string|object} 3090 * @return {number} 3091 */ 3092 MK.val.dynamicHeight = function(el) { 3093 var $window = $(window), 3094 $el = $(el), 3095 container = document.getElementById('mk-theme-container'), 3096 currentHeight = 0; 3097 3098 var update = function() { 3099 currentHeight = $el.outerHeight(); 3100 }; 3101 3102 update(); 3103 $window.on('load', update); 3104 $window.on('resize', update); 3105 window.addResizeListener(container, update); 3106 3107 return function() { 3108 return currentHeight; 3109 }; 3110 }; 3111 3112})(jQuery); 3113 3114/* 3115 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ 3116 * 3117 */ 3118jQuery.easing["jswing"] = jQuery.easing["swing"]; 3119jQuery.extend(jQuery.easing, { 3120 def: "easeOutQuad", 3121 swing: function (a, b, c, d, e) { 3122 return jQuery.easing[jQuery.easing.def](a, b, c, d, e) 3123 }, 3124 easeInQuad: function (a, b, c, d, e) { 3125 return d * (b /= e) * b + c 3126 }, 3127 easeOutQuad: function (a, b, c, d, e) { 3128 return -d * (b /= e) * (b - 2) + c 3129 }, 3130 easeInOutQuad: function (a, b, c, d, e) { 3131 if ((b /= e / 2) < 1) return d / 2 * b * b + c; 3132 return -d / 2 * (--b * (b - 2) - 1) + c 3133 }, 3134 easeInCubic: function (a, b, c, d, e) { 3135 return d * (b /= e) * b * b + c 3136 }, 3137 easeOutCubic: function (a, b, c, d, e) { 3138 return d * ((b = b / e - 1) * b * b + 1) + c 3139 }, 3140 easeInOutCubic: function (a, b, c, d, e) { 3141 if ((b /= e / 2) < 1) return d / 2 * b * b * b + c; 3142 return d / 2 * ((b -= 2) * b * b + 2) + c 3143 }, 3144 easeInQuart: function (a, b, c, d, e) { 3145 return d * (b /= e) * b * b * b + c 3146 }, 3147 easeOutQuart: function (a, b, c, d, e) { 3148 return -d * ((b = b / e - 1) * b * b * b - 1) + c 3149 }, 3150 easeInOutQuart: function (a, b, c, d, e) { 3151 if ((b /= e / 2) < 1) return d / 2 * b * b * b * b + c; 3152 return -d / 2 * ((b -= 2) * b * b * b - 2) + c 3153 }, 3154 easeInQuint: function (a, b, c, d, e) { 3155 return d * (b /= e) * b * b * b * b + c 3156 }, 3157 easeOutQuint: function (a, b, c, d, e) { 3158 return d * ((b = b / e - 1) * b * b * b * b + 1) + c 3159 }, 3160 easeInOutQuint: function (a, b, c, d, e) { 3161 if ((b /= e / 2) < 1) return d / 2 * b * b * b * b * b + c; 3162 return d / 2 * ((b -= 2) * b * b * b * b + 2) + c 3163 }, 3164 easeInSine: function (a, b, c, d, e) {
3165 return -d * Math.cos(b / e * (Math.PI / 2)) + d + c 3166 }, 3167 easeOutSine: function (a, b, c, d, e) { 3168 return d * Math.sin(b / e * (Math.PI / 2)) + c 3169 }, 3170 easeInOutSine: function (a, b, c, d, e) { 3171 return -d / 2 * (Math.cos(Math.PI * b / e) - 1) + c 3172 }, 3173 easeInExpo: function (a, b, c, d, e) { 3174 return b == 0 ? c : d * Math.pow(2, 10 * (b / e - 1)) + c 3175 }, 3176 easeOutExpo: function (a, b, c, d, e) { 3177 return b == e ? c + d : d * (-Math.pow(2, -10 * b / e) + 1) + c 3178 }, 3179 easeInOutExpo: function (a, b, c, d, e) { 3180 if (b == 0) return c; 3181 if (b == e) return c + d; 3182 if ((b /= e / 2) < 1) return d / 2 * Math.pow(2, 10 * (b - 1)) + c; 3183 return d / 2 * (-Math.pow(2, -10 * --b) + 2) + c 3184 }, 3185 easeInCirc: function (a, b, c, d, e) { 3186 return -d * (Math.sqrt(1 - (b /= e) * b) - 1) + c 3187 }, 3188 easeOutCirc: function (a, b, c, d, e) { 3189 return d * Math.sqrt(1 - (b = b / e - 1) * b) + c 3190 }, 3191 easeInOutCirc: function (a, b, c, d, e) { 3192 if ((b /= e / 2) < 1) return -d / 2 * (Math.sqrt(1 - b * b) - 1) + c; 3193 return d / 2 * (Math.sqrt(1 - (b -= 2) * b) + 1) + c 3194 }, 3195 easeInElastic: function (a, b, c, d, e) { 3196 var f = 1.70158; 3197 var g = 0; 3198 var h = d; 3199 if (b == 0) return c; 3200 if ((b /= e) == 1) return c + d; 3201 if (!g) g = e * .3; 3202 if (h < Math.abs(d)) { 3203 h = d; 3204 var f = g / 4 3205 } else var f = g / (2 * Math.PI) * Math.asin(d / h); 3206 return -(h * Math.pow(2, 10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g)) + c 3207 }, 3208 easeOutElastic: function (a, b, c, d, e) { 3209 var f = 1.70158; 3210 var g = 0; 3211 var h = d; 3212 if (b == 0) return c; 3213 if ((b /= e) == 1) return c + d; 3214 if (!g) g = e * .3; 3215 if (h < Math.abs(d)) { 3216 h = d; 3217 var f = g / 4 3218 } else var f = g / (2 * Math.PI) * Math.asin(d / h); 3219 return h * Math.pow(2, -10 * b) * Math.sin((b * e - f) * 2 * Math.PI / g) + d + c 3220 }, 3221 easeInOutElastic: function (a, b, c, d, e) { 3222 var f = 1.70158; 3223 var g = 0; 3224 var h = d; 3225 if (b == 0) return c; 3226 if ((b /= e / 2) == 2) return c + d; 3227 if (!g) g = e * .3 * 1.5; 3228 if (h < Math.abs(d)) { 3229 h = d; 3230 var f = g / 4 3231 } else var f = g / (2 * Math.PI) * Math.asin(d / h); 3232 if (b < 1) return -.5 * h * Math.pow(2, 10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g) + c; 3233 return h * Math.pow(2, -10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g) * .5 + d + c 3234 }, 3235 easeInBack: function (a, b, c, d, e, f) { 3236 if (f == undefined) f = 1.70158; 3237 return d * (b /= e) * b * ((f + 1) * b - f) + c 3238 }, 3239 easeOutBack: function (a, b, c, d, e, f) { 3240 if (f == undefined) f = 1.70158; 3241 return d * ((b = b / e - 1) * b * ((f + 1) * b + f) + 1) + c 3242 }, 3243 easeInOutBack: function (a, b, c, d, e, f) { 3244 if (f == undefined) f = 1.70158; 3245 if ((b /= e / 2) < 1) return d / 2 * b * b * (((f *= 1.525) + 1) * b - f) + c; 3246 return d / 2 * ((b -= 2) * b * (((f *= 1.525) + 1) * b + f) + 2) + c 3247 }, 3248 easeInBounce: function (a, b, c, d, e) { 3249 return d - jQuery.easing.easeOutBounce(a, e - b, 0, d, e) + c 3250 }, 3251 easeOutBounce: function (a, b, c, d, e) { 3252 if ((b /= e) < 1 / 2.75) { 3253 return d * 7.5625 * b * b + c 3254 } else if (b < 2 / 2.75) { 3255 return d * (7.5625 * (b -= 1.5 / 2.75) * b + .75) + c 3256 } else if (b < 2.5 / 2.75) { 3257 return d * (7.5625 * (b -= 2.25 / 2.75) * b + .9375) + c 3258 } else { 3259 return d * (7.5625 * (b -= 2.625 / 2.75) * b + .984375) + c 3260 } 3261 }, 3262 easeInOutBounce: function (a, b, c, d, e) { 3263 if (b < e / 2) return jQuery.easing.easeInBounce(a, b * 2, 0, d, e) * .5 + c; 3264 return jQuery.easing.easeOutBounce(a, b * 2 - e, 0, d, e) * .5 + d * .5 + c 3265 } 3266}); 3267 3268/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ 3269(function(s, H, f, w) { 3270 var K = f("html"), 3271 q = f(s), 3272 p = f(H), 3273 b = f.fancybox = function() { 3274 b.open.apply(this, arguments) 3275 }, 3276 J = navigator.userAgent.match(/msie/i), 3277 C = null, 3278 t = H.createTouch !== w, 3279 u = function(a) { 3280 return a && a.hasOwnProperty && a instanceof f 3281 }, 3282 r = function(a) { 3283 return a && "string" === f.type(a) 3284 }, 3285 F = function(a) { 3286 return r(a) && 0 < a.indexOf("%") 3287 }, 3288 m = function(a, d) { 3289 var e = parseInt(a, 10) || 0; 3290 d && F(a) && (e *= b.getViewport()[d] / 100); 3291 return Math.ceil(e) 3292 }, 3293 x = function(a, b) { 3294 return m(a, b) + "px" 3295 }; 3296 f.extend(b, { 3297 version: "2.1.5", 3298 defaults: { 3299 padding: 15, 3300 margin: 20, 3301 width: 800, 3302 height: 600, 3303 minWidth: 100, 3304 minHeight: 100, 3305 maxWidth: 9999, 3306 maxHeight: 9999, 3307 pixelRatio: 1, 3308 autoSize: !0, 3309 autoHeight: !1, 3310 autoWidth: !1, 3311 autoResize: !0, 3312 autoCenter: !t, 3313 fitToView: !0, 3314 aspectRatio: !1, 3315 topRatio: 0.5, 3316 leftRatio: 0.5, 3317 scrolling: "auto", 3318 wrapCSS: "", 3319 arrows: !0, 3320 closeBtn: !0, 3321 closeClick: !1, 3322 nextClick: !1, 3323 mouseWheel: !0, 3324 autoPlay: !1, 3325 playSpeed: 3E3, 3326 preload: 3, 3327 modal: !1, 3328 loop: !0, 3329 ajax: { 3330 dataType: "html", 3331 headers: { 3332 "X-fancyBox": !0 3333 } 3334 }, 3335 iframe: { 3336 scrolling: "auto", 3337 preload: !0 3338 }, 3339 swf: { 3340 wmode: "transparent", 3341 allowfullscreen: "true", 3342 allowscriptaccess: "always" 3343 }, 3344 keys: { 3345 next: { 3346 13: "left", 3347 34: "up", 3348 39: "left", 3349 40: "up" 3350 }, 3351 prev: { 3352 8: "right", 3353 33: "down", 3354 37: "right", 3355 38: "down" 3356 }, 3357 close: [27], 3358 play: [32], 3359 toggle: [70] 3360 }, 3361 direction: { 3362 next: "left", 3363 prev: "right" 3364 }, 3365 scrollOutside: !0, 3366 index: 0, 3367 type: null, 3368 href: null, 3369 content: null, 3370 title: null, 3371 tpl: { 3372 wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 3373 image: '<img class="fancybox-image" src="{href}" alt="" />', 3374 iframe: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + 3375 (J ? ' allowtransparency="true"' : "") + "></iframe>", 3376 error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 3377 closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', 3378 next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', 3379 prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>' 3380 }, 3381 openEffect: "fade", 3382 openSpeed: 250, 3383 openEasing: "swing", 3384 openOpacity: !0, 3385 openMethod: "zoomIn", 3386 closeEffect: "fade", 3387 closeSpeed: 250, 3388 closeEasing: "swing", 3389 closeOpacity: !0, 3390 closeMethod: "zoomOut", 3391 nextEffect: "elastic", 3392 nextSpeed: 250, 3393 nextEasing: "swing", 3394 nextMethod: "changeIn", 3395 prevEffect: "elastic", 3396 prevSpeed: 250, 3397 prevEasing: "swing", 3398 prevMethod: "changeOut", 3399 helpers: { 3400 overlay: !0, 3401 title: !0 3402 }, 3403 onCancel: f.noop, 3404 beforeLoad: f.noop, 3405 afterLoad: f.noop, 3406 beforeShow: f.noop, 3407 afterShow: f.noop, 3408 beforeChange: f.noop, 3409 beforeClose: f.noop, 3410 afterClose: f.noop 3411 }, 3412 group: {}, 3413 opts: {}, 3414 previous: null, 3415 coming: null, 3416 current: null, 3417 isActive: !1, 3418 isOpen: !1, 3419 isOpened: !1, 3420 wrap: null, 3421 skin: null, 3422 outer: null, 3423 inner: null, 3424 player: { 3425 timer: null, 3426 isActive: !1 3427 }, 3428 ajaxLoad: null, 3429 imgPreload: null, 3430 transitions: {}, 3431 helpers: {}, 3432 open: function(a, d) { 3433 if (a && (f.isPlainObject(d) || (d = {}), !1 !== b.close(!0))) return f.isArray(a) || (a = u(a) ? f(a).get() : [a]), f.each(a, function(e,
vendor: 34,462 bytes, lines 3433-4183
3433c) { 3434 var l = {}, 3435 g, h, k, n, m; 3436 "object" === f.type(c) && (c.nodeType && (c = f(c)), u(c) ? (l = { 3437 href: c.data("fancybox-href") || c.attr("href"), 3438 title: f("<div/>").text(c.data("fancybox-title") || c.attr("title")).html(), 3439 isDom: !0, 3440 element: c 3441 }, 3442 f.metadata && f.extend(!0, l, c.metadata())) : l = c); 3443 g = d.href || l.href || (r(c) ? c : null); 3444 h = d.title !== w ? d.title : l.title || ""; 3445 n = (k = d.content || l.content) ? "html" : d.type || l.type; 3446 !n && l.isDom && (n = c.data("fancybox-type"), n || (n = (n = c.prop("class").match(/fancybox\.(\w+)/)) ? n[1] : null)); 3447 r(g) && (n || (b.isImage(g) ? n = "image" : b.isSWF(g) ? n = "swf" : "#" === g.charAt(0) ? n = "inline" : r(c) && (n = "html", k = c)), "ajax" === n && (m = g.split(/\s+/, 2), g = m.shift(), m = m.shift())); 3448 k || ("inline" === n ? g ? k = f(r(g) ? g.replace(/.*(?=#[^\s]+$)/, "") : g) : l.isDom && (k = c) : 3449 "html" === n ? k = g : n || g || !l.isDom || (n = "inline", k = c)); 3450 f.extend(l, { 3451 href: g, 3452 type: n, 3453 content: k, 3454 title: h, 3455 selector: m 3456 }); 3457 a[e] = l 3458 }), b.opts = f.extend(!0, {}, b.defaults, d), d.keys !== w && (b.opts.keys = d.keys ? f.extend({}, b.defaults.keys, d.keys) : !1), b.group = a, b._start(b.opts.index) 3459 }, 3460 cancel: function() { 3461 var a = b.coming; 3462 a && !1 === b.trigger("onCancel") || (b.hideLoading(), a && (b.ajaxLoad && b.ajaxLoad.abort(), b.ajaxLoad = null, b.imgPreload && (b.imgPreload.onload = b.imgPreload.onerror = null), a.wrap && a.wrap.stop(!0, !0).trigger("onReset").remove(), 3463 b.coming = null, b.current || b._afterZoomOut(a))) 3464 }, 3465 close: function(a) { 3466 b.cancel(); 3467 !1 !== b.trigger("beforeClose") && (b.unbindEvents(), b.isActive && (b.isOpen && !0 !== a ? (b.isOpen = b.isOpened = !1, b.isClosing = !0, f(".fancybox-item, .fancybox-nav").remove(), b.wrap.stop(!0, !0).removeClass("fancybox-opened"), b.transitions[b.current.closeMethod]()) : (f(".fancybox-wrap").stop(!0).trigger("onReset").remove(), b._afterZoomOut()))) 3468 }, 3469 play: function(a) { 3470 var d = function() { 3471 clearTimeout(b.player.timer) 3472 }, 3473 e = function() { 3474 d(); 3475 b.current && b.player.isActive && 3476 (b.player.timer = setTimeout(b.next, b.current.playSpeed)) 3477 }, 3478 c = function() { 3479 d(); 3480 p.unbind(".player"); 3481 b.player.isActive = !1; 3482 b.trigger("onPlayEnd") 3483 }; 3484 !0 === a || !b.player.isActive && !1 !== a ? b.current && (b.current.loop || b.current.index < b.group.length - 1) && (b.player.isActive = !0, p.bind({ 3485 "onCancel.player beforeClose.player": c, 3486 "onUpdate.player": e, 3487 "beforeLoad.player": d 3488 }), e(), b.trigger("onPlayStart")) : c() 3489 }, 3490 next: function(a) { 3491 var d = b.current; 3492 d && (r(a) || (a = d.direction.next), b.jumpto(d.index + 1, a, "next")) 3493 }, 3494 prev: function(a) { 3495 var d = 3496 b.current; 3497 d && (r(a) || (a = d.direction.prev), b.jumpto(d.index - 1, a, "prev")) 3498 }, 3499 jumpto: function(a, d, e) { 3500 var c = b.current; 3501 c && (a = m(a), b.direction = d || c.direction[a >= c.index ? "next" : "prev"], b.router = e || "jumpto", c.loop && (0 > a && (a = c.group.length + a % c.group.length), a %= c.group.length), c.group[a] !== w && (b.cancel(), b._start(a))) 3502 }, 3503 reposition: function(a, d) { 3504 var e = b.current, 3505 c = e ? e.wrap : null, 3506 l; 3507 c && (l = b._getPosition(d), a && "scroll" === a.type ? (delete l.position, c.stop(!0, !0).animate(l, 200)) : (c.css(l), e.pos = f.extend({}, e.dim, l))) 3508 }, 3509 update: function(a) { 3510 var d = a && a.originalEvent && a.originalEvent.type, 3511 e = !d || "orientationchange" === d; 3512 e && (clearTimeout(C), C = null); 3513 b.isOpen && !C && (C = setTimeout(function() { 3514 var c = b.current; 3515 c && !b.isClosing && (b.wrap.removeClass("fancybox-tmp"), (e || "load" === d || "resize" === d && c.autoResize) && b._setDimension(), "scroll" === d && c.canShrink || b.reposition(a), b.trigger("onUpdate"), C = null) 3516 }, e && !t ? 0 : 300)) 3517 }, 3518 toggle: function(a) { 3519 b.isOpen && (b.current.fitToView = "boolean" === f.type(a) ? a : !b.current.fitToView, t && (b.wrap.removeAttr("style").addClass("fancybox-tmp"), 3520 b.trigger("onUpdate")), b.update()) 3521 }, 3522 hideLoading: function() { 3523 p.unbind(".loading"); 3524 f("#fancybox-loading").remove() 3525 }, 3526 showLoading: function() { 3527 var a, d; 3528 b.hideLoading(); 3529 a = f('<div id="fancybox-loading"><div></div></div>').click(b.cancel).appendTo("body"); 3530 p.bind("keydown.loading", function(a) { 3531 27 === (a.which || a.keyCode) && (a.preventDefault(), b.cancel()) 3532 }); 3533 b.defaults.fixed || (d = b.getViewport(), a.css({ 3534 position: "absolute", 3535 top: 0.5 * d.h + d.y, 3536 left: 0.5 * d.w + d.x 3537 })); 3538 b.trigger("onLoading") 3539 }, 3540 getViewport: function() { 3541 var a = b.current && 3542 b.current.locked || !1, 3543 d = { 3544 x: q.scrollLeft(), 3545 y: q.scrollTop() 3546 }; 3547 a && a.length ? (d.w = a[0].clientWidth, d.h = a[0].clientHeight) : (d.w = t && s.innerWidth ? s.innerWidth : q.width(), d.h = t && s.innerHeight ? s.innerHeight : q.height()); 3548 return d 3549 }, 3550 unbindEvents: function() { 3551 b.wrap && u(b.wrap) && b.wrap.unbind(".fb"); 3552 p.unbind(".fb"); 3553 q.unbind(".fb") 3554 }, 3555 bindEvents: function() { 3556 var a = b.current, 3557 d; 3558 a && (q.bind("orientationchange.fb" + (t ? "" : " resize.fb") + (a.autoCenter && !a.locked ? " scroll.fb" : ""), b.update), (d = a.keys) && p.bind("keydown.fb", function(e) { 3559 var c = 3560 e.which || e.keyCode, 3561 l = e.target || e.srcElement; 3562 if (27 === c && b.coming) return !1; 3563 e.ctrlKey || e.altKey || e.shiftKey || e.metaKey || l && (l.type || f(l).is("[contenteditable]")) || f.each(d, function(d, l) { 3564 if (1 < a.group.length && l[c] !== w) return b[d](l[c]), e.preventDefault(), !1; 3565 if (-1 < f.inArray(c, l)) return b[d](), e.preventDefault(), !1 3566 }) 3567 }), f.fn.mousewheel && a.mouseWheel && b.wrap.bind("mousewheel.fb", function(d, c, l, g) { 3568 for (var h = f(d.target || null), k = !1; h.length && !(k || h.is(".fancybox-skin") || h.is(".fancybox-wrap"));) k = h[0] && !(h[0].style.overflow && 3569 "hidden" === h[0].style.overflow) && (h[0].clientWidth && h[0].scrollWidth > h[0].clientWidth || h[0].clientHeight && h[0].scrollHeight > h[0].clientHeight), h = f(h).parent(); 3570 0 !== c && !k && 1 < b.group.length && !a.canShrink && (0 < g || 0 < l ? b.prev(0 < g ? "down" : "left") : (0 > g || 0 > l) && b.next(0 > g ? "up" : "right"), d.preventDefault()) 3571 })) 3572 }, 3573 trigger: function(a, d) { 3574 var e, c = d || b.coming || b.current; 3575 if (c) { 3576 f.isFunction(c[a]) && (e = c[a].apply(c, Array.prototype.slice.call(arguments, 1))); 3577 if (!1 === e) return !1; 3578 c.helpers && f.each(c.helpers, function(d, e) { 3579 if (e && 3580 b.helpers[d] && f.isFunction(b.helpers[d][a])) b.helpers[d][a](f.extend(!0, {}, b.helpers[d].defaults, e), c) 3581 }) 3582 } 3583 p.trigger(a) 3584 }, 3585 isImage: function(a) { 3586 return r(a) && a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i) 3587 }, 3588 isSWF: function(a) { 3589 return r(a) && a.match(/\.(swf)((\?|#).*)?$/i) 3590 }, 3591 _start: function(a) { 3592 var d = {}, 3593 e, c; 3594 a = m(a); 3595 e = b.group[a] || null; 3596 if (!e) return !1; 3597 d = f.extend(!0, {}, b.opts, e); 3598 e = d.margin; 3599 c = d.padding; 3600 "number" === f.type(e) && (d.margin = [e, e, e, e]); 3601 "number" === f.type(c) && (d.padding = [c, c, 3602 c, c 3603 ]); 3604 d.modal && f.extend(!0, d, { 3605 closeBtn: !1, 3606 closeClick: !1, 3607 nextClick: !1, 3608 arrows: !1, 3609 mouseWheel: !1, 3610 keys: null, 3611 helpers: { 3612 overlay: { 3613 closeClick: !1 3614 } 3615 } 3616 }); 3617 d.autoSize && (d.autoWidth = d.autoHeight = !0); 3618 "auto" === d.width && (d.autoWidth = !0); 3619 "auto" === d.height && (d.autoHeight = !0); 3620 d.group = b.group; 3621 d.index = a; 3622 b.coming = d; 3623 if (!1 === b.trigger("beforeLoad")) b.coming = null; 3624 else { 3625 c = d.type; 3626 e = d.href; 3627 if (!c) return b.coming = null, b.current && b.router && "jumpto" !== b.router ? (b.current.index = a, b[b.router](b.direction)) : !1; 3628 b.isActive = !0; 3629 if ("image" === 3630 c || "swf" === c) d.autoHeight = d.autoWidth = !1, d.scrolling = "visible"; 3631 "image" === c && (d.aspectRatio = !0); 3632 "iframe" === c && t && (d.scrolling = "scroll"); 3633 d.wrap = f(d.tpl.wrap).addClass("fancybox-" + (t ? "mobile" : "desktop") + " fancybox-type-" + c + " fancybox-tmp " + d.wrapCSS).appendTo(d.parent || "body"); 3634 f.extend(d, { 3635 skin: f(".fancybox-skin", d.wrap), 3636 outer: f(".fancybox-outer", d.wrap), 3637 inner: f(".fancybox-inner", d.wrap) 3638 }); 3639 f.each(["Top", "Right", "Bottom", "Left"], function(a, b) { 3640 d.skin.css("padding" + b, x(d.padding[a])) 3641 }); 3642 b.trigger("onReady"); 3643 if ("inline" === c || "html" === c) { 3644 if (!d.content || !d.content.length) return b._error("content") 3645 } else if (!e) return b._error("href"); 3646 "image" === c ? b._loadImage() : "ajax" === c ? b._loadAjax() : "iframe" === c ? b._loadIframe() : b._afterLoad() 3647 } 3648 }, 3649 _error: function(a) { 3650 f.extend(b.coming, { 3651 type: "html", 3652 autoWidth: !0, 3653 autoHeight: !0, 3654 minWidth: 0, 3655 minHeight: 0, 3656 scrolling: "no", 3657 hasError: a, 3658 content: b.coming.tpl.error 3659 }); 3660 b._afterLoad() 3661 }, 3662 _loadImage: function() { 3663 var a = b.imgPreload = new Image; 3664 a.onload = function() { 3665 this.onload = this.onerror = null; 3666 b.coming.width = 3667 this.width / b.opts.pixelRatio; 3668 b.coming.height = this.height / b.opts.pixelRatio; 3669 b._afterLoad() 3670 }; 3671 a.onerror = function() { 3672 this.onload = this.onerror = null; 3673 b._error("image") 3674 }; 3675 a.src = b.coming.href; 3676 !0 !== a.complete && b.showLoading() 3677 }, 3678 _loadAjax: function() { 3679 var a = b.coming; 3680 b.showLoading(); 3681 b.ajaxLoad = f.ajax(f.extend({}, a.ajax, { 3682 url: a.href, 3683 error: function(a, e) { 3684 b.coming && "abort" !== e ? b._error("ajax", a) : b.hideLoading() 3685 }, 3686 success: function(d, e) { 3687 "success" === e && (a.content = d, b._afterLoad()) 3688 } 3689 })) 3690 }, 3691 _loadIframe: function() { 3692 var a = b.coming, 3693 d = f(a.tpl.iframe.replace(/\{rnd\}/g, (new Date).getTime())).attr("scrolling", t ? "auto" : a.iframe.scrolling).attr("src", a.href); 3694 f(a.wrap).bind("onReset", function() { 3695 try { 3696 f(this).find("iframe").hide().attr("src", "//about:blank").end().empty() 3697 } catch (a) {} 3698 }); 3699 a.iframe.preload && (b.showLoading(), d.one("load", function() { 3700 f(this).data("ready", 1); 3701 t || f(this).bind("load.fb", b.update); 3702 f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show(); 3703 b._afterLoad() 3704 })); 3705 a.content = d.appendTo(a.inner); 3706 a.iframe.preload || 3707 b._afterLoad() 3708 }, 3709 _preloadImages: function() { 3710 var a = b.group, 3711 d = b.current, 3712 e = a.length, 3713 c = d.preload ? Math.min(d.preload, e - 1) : 0, 3714 f, g; 3715 for (g = 1; g <= c; g += 1) f = a[(d.index + g) % e], "image" === f.type && f.href && ((new Image).src = f.href) 3716 }, 3717 _afterLoad: function() { 3718 var a = b.coming, 3719 d = b.current, 3720 e, c, l, g, h; 3721 b.hideLoading(); 3722 if (a && !1 !== b.isActive) 3723 if (!1 === b.trigger("afterLoad", a, d)) a.wrap.stop(!0).trigger("onReset").remove(), b.coming = null; 3724 else { 3725 d && (b.trigger("beforeChange", d), d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove()); 3726 b.unbindEvents(); 3727 e = a.content; 3728 c = a.type; 3729 l = a.scrolling; 3730 f.extend(b, { 3731 wrap: a.wrap, 3732 skin: a.skin, 3733 outer: a.outer, 3734 inner: a.inner, 3735 current: a, 3736 previous: d 3737 }); 3738 g = a.href; 3739 switch (c) { 3740 case "inline": 3741 case "ajax": 3742 case "html": 3743 a.selector ? e = f("<div>").html(e).find(a.selector) : u(e) && (e.data("fancybox-placeholder") || e.data("fancybox-placeholder", f('<div class="fancybox-placeholder"></div>').insertAfter(e).hide()), e = e.show().detach(), a.wrap.bind("onReset", function() { 3744 f(this).find(e).length && e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder", !1) 3745 })); 3746 break; 3747 case "image": 3748 e = a.tpl.image.replace(/\{href\}/g, g); 3749 break; 3750 case "swf": 3751 e = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + g + '"></param>', h = "", f.each(a.swf, function(a, b) { 3752 e += '<param name="' + a + '" value="' + b + '"></param>'; 3753 h += " " + a + '="' + b + '"' 3754 }), e += '<embed src="' + g + '" type="application/x-shockwave-flash" width="100%" height="100%"' + h + "></embed></object>" 3755 } 3756 u(e) && e.parent().is(a.inner) || a.inner.append(e); 3757 b.trigger("beforeShow"); 3758 a.inner.css("overflow", "yes" === l ? "scroll" : "no" === l ? "hidden" : l); 3759 b._setDimension(); 3760 b.reposition(); 3761 b.isOpen = !1; 3762 b.coming = null; 3763 b.bindEvents(); 3764 if (!b.isOpened) f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove(); 3765 else if (d.prevMethod) b.transitions[d.prevMethod](); 3766 b.transitions[b.isOpened ? a.nextMethod : a.openMethod](); 3767 b._preloadImages() 3768 } 3769 }, 3770 _setDimension: function() { 3771 var a = b.getViewport(), 3772 d = 0, 3773 e = !1, 3774 c = !1, 3775 e = b.wrap, 3776 l = b.skin, 3777 g = b.inner, 3778 h = b.current, 3779 c = h.width, 3780 k = h.height, 3781 n = h.minWidth, 3782 v = h.minHeight, 3783 p = h.maxWidth, 3784 q = h.maxHeight, 3785 t = h.scrolling, 3786 r = h.scrollOutside ? h.scrollbarWidth : 0, 3787 y = h.margin, 3788 z = m(y[1] + y[3]), 3789 s = m(y[0] + y[2]), 3790 w, A, u, D, B, G, C, E, I; 3791 e.add(l).add(g).width("auto").height("auto").removeClass("fancybox-tmp"); 3792 y = m(l.outerWidth(!0) - l.width()); 3793 w = m(l.outerHeight(!0) - l.height()); 3794 A = z + y; 3795 u = s + w; 3796 D = F(c) ? (a.w - A) * m(c) / 100 : c; 3797 B = F(k) ? (a.h - u) * m(k) / 100 : k; 3798 if ("iframe" === h.type) { 3799 if (I = h.content, h.autoHeight && 1 === I.data("ready")) try { 3800 I[0].contentWindow.document.location && (g.width(D).height(9999), G = I.contents().find("body"), r && G.css("overflow-x", 3801 "hidden"), B = G.outerHeight(!0)) 3802 } catch (H) {} 3803 } else if (h.autoWidth || h.autoHeight) g.addClass("fancybox-tmp"), h.autoWidth || g.width(D), h.autoHeight || g.height(B), h.autoWidth && (D = g.width()), h.autoHeight && (B = g.height()), g.removeClass("fancybox-tmp"); 3804 c = m(D); 3805 k = m(B); 3806 E = D / B; 3807 n = m(F(n) ? m(n, "w") - A : n); 3808 p = m(F(p) ? m(p, "w") - A : p); 3809 v = m(F(v) ? m(v, "h") - u : v); 3810 q = m(F(q) ? m(q, "h") - u : q); 3811 G = p; 3812 C = q; 3813 h.fitToView && (p = Math.min(a.w - A, p), q = Math.min(a.h - u, q)); 3814 A = a.w - z; 3815 s = a.h - s; 3816 h.aspectRatio ? (c > p && (c = p, k = m(c / E)), k > q && (k = q, c = m(k * E)), c < n && (c = n, k = m(c / 3817 E)), k < v && (k = v, c = m(k * E))) : (c = Math.max(n, Math.min(c, p)), h.autoHeight && "iframe" !== h.type && (g.width(c), k = g.height()), k = Math.max(v, Math.min(k, q))); 3818 if (h.fitToView) 3819 if (g.width(c).height(k), e.width(c + y), a = e.width(), z = e.height(), h.aspectRatio) 3820 for (; 3821 (a > A || z > s) && c > n && k > v && !(19 < d++);) k = Math.max(v, Math.min(q, k - 10)), c = m(k * E), c < n && (c = n, k = m(c / E)), c > p && (c = p, k = m(c / E)), g.width(c).height(k), e.width(c + y), a = e.width(), z = e.height(); 3822 else c = Math.max(n, Math.min(c, c - (a - A))), k = Math.max(v, Math.min(k, k - (z - s))); 3823 r && "auto" === t && k < B && 3824 c + y + r < A && (c += r); 3825 g.width(c).height(k); 3826 e.width(c + y); 3827 a = e.width(); 3828 z = e.height(); 3829 e = (a > A || z > s) && c > n && k > v; 3830 c = h.aspectRatio ? c < G && k < C && c < D && k < B : (c < G || k < C) && (c < D || k < B); 3831 f.extend(h, { 3832 dim: { 3833 width: x(a), 3834 height: x(z) 3835 }, 3836 origWidth: D, 3837 origHeight: B, 3838 canShrink: e, 3839 canExpand: c, 3840 wPadding: y, 3841 hPadding: w, 3842 wrapSpace: z - l.outerHeight(!0), 3843 skinSpace: l.height() - k 3844 }); 3845 !I && h.autoHeight && k > v && k < q && !c && g.height("auto") 3846 }, 3847 _getPosition: function(a) { 3848 var d = b.current, 3849 e = b.getViewport(), 3850 c = d.margin, 3851 f = b.wrap.width() + c[1] + c[3], 3852 g = b.wrap.height() + c[0] + c[2], 3853 c = { 3854 position: "absolute", 3855 top: c[0], 3856 left: c[3] 3857 }; 3858 d.autoCenter && d.fixed && !a && g <= e.h && f <= e.w ? c.position = "fixed" : d.locked || (c.top += e.y, c.left += e.x); 3859 c.top = x(Math.max(c.top, c.top + (e.h - g) * d.topRatio)); 3860 c.left = x(Math.max(c.left, c.left + (e.w - f) * d.leftRatio)); 3861 return c 3862 }, 3863 _afterZoomIn: function() { 3864 var a = b.current; 3865 a && ((b.isOpen = b.isOpened = !0, b.wrap.css("overflow", "visible").addClass("fancybox-opened"), b.update(), (a.closeClick || a.nextClick && 1 < b.group.length) && b.inner.css("cursor", "pointer").bind("click.fb", function(d) { 3866 f(d.target).is("a") || f(d.target).parent().is("a") || 3867 (d.preventDefault(), b[a.closeClick ? "close" : "next"]()) 3868 }), a.closeBtn && f(a.tpl.closeBtn).appendTo(b.skin).bind("click.fb", function(a) { 3869 a.preventDefault(); 3870 b.close() 3871 }), a.arrows && 1 < b.group.length && ((a.loop || 0 < a.index) && f(a.tpl.prev).appendTo(b.outer).bind("click.fb", b.prev), (a.loop || a.index < b.group.length - 1) && f(a.tpl.next).appendTo(b.outer).bind("click.fb", b.next)), b.trigger("afterShow"), a.loop || a.index !== a.group.length - 1) ? b.opts.autoPlay && !b.player.isActive && (b.opts.autoPlay = !1, b.play(!0)) : b.play(!1)) 3872 }, 3873 _afterZoomOut: function(a) { 3874 a = a || b.current; 3875 f(".fancybox-wrap").trigger("onReset").remove(); 3876 f.extend(b, { 3877 group: {}, 3878 opts: {}, 3879 router: !1, 3880 current: null, 3881 isActive: !1, 3882 isOpened: !1, 3883 isOpen: !1, 3884 isClosing: !1, 3885 wrap: null, 3886 skin: null, 3887 outer: null, 3888 inner: null 3889 }); 3890 b.trigger("afterClose", a) 3891 } 3892 }); 3893 b.transitions = { 3894 getOrigPosition: function() { 3895 var a = b.current, 3896 d = a.element, 3897 e = a.orig, 3898 c = {}, 3899 f = 50, 3900 g = 50, 3901 h = a.hPadding, 3902 k = a.wPadding, 3903 n = b.getViewport(); 3904 !e && a.isDom && d.is(":visible") && (e = d.find("img:first"), e.length || (e = d)); 3905 u(e) ? (c = e.offset(), e.is("img") && 3906 (f = e.outerWidth(), g = e.outerHeight())) : (c.top = n.y + (n.h - g) * a.topRatio, c.left = n.x + (n.w - f) * a.leftRatio); 3907 if ("fixed" === b.wrap.css("position") || a.locked) c.top -= n.y, c.left -= n.x; 3908 return c = { 3909 top: x(c.top - h * a.topRatio), 3910 left: x(c.left - k * a.leftRatio), 3911 width: x(f + k), 3912 height: x(g + h) 3913 } 3914 }, 3915 step: function(a, d) { 3916 var e, c, f = d.prop; 3917 c = b.current; 3918 var g = c.wrapSpace, 3919 h = c.skinSpace; 3920 if ("width" === f || "height" === f) e = d.end === d.start ? 1 : (a - d.start) / (d.end - d.start), b.isClosing && (e = 1 - e), c = "width" === f ? c.wPadding : c.hPadding, c = a - c, b.skin[f](m("width" === 3921 f ? c : c - g * e)), b.inner[f](m("width" === f ? c : c - g * e - h * e)) 3922 }, 3923 zoomIn: function() { 3924 var a = b.current, 3925 d = a.pos, 3926 e = a.openEffect, 3927 c = "elastic" === e, 3928 l = f.extend({ 3929 opacity: 1 3930 }, d); 3931 delete l.position; 3932 c ? (d = this.getOrigPosition(), a.openOpacity && (d.opacity = 0.1)) : "fade" === e && (d.opacity = 0.1); 3933 b.wrap.css(d).animate(l, { 3934 duration: "none" === e ? 0 : a.openSpeed, 3935 easing: a.openEasing, 3936 step: c ? this.step : null, 3937 complete: b._afterZoomIn 3938 }) 3939 }, 3940 zoomOut: function() { 3941 var a = b.current, 3942 d = a.closeEffect, 3943 e = "elastic" === d, 3944 c = { 3945 opacity: 0.1 3946 }; 3947 e && (c = this.getOrigPosition(), a.closeOpacity && 3948 (c.opacity = 0.1)); 3949 b.wrap.animate(c, { 3950 duration: "none" === d ? 0 : a.closeSpeed, 3951 easing: a.closeEasing, 3952 step: e ? this.step : null, 3953 complete: b._afterZoomOut 3954 }) 3955 }, 3956 changeIn: function() { 3957 var a = b.current, 3958 d = a.nextEffect, 3959 e = a.pos, 3960 c = { 3961 opacity: 1 3962 }, 3963 f = b.direction, 3964 g; 3965 e.opacity = 0.1; 3966 "elastic" === d && (g = "down" === f || "up" === f ? "top" : "left", "down" === f || "right" === f ? (e[g] = x(m(e[g]) - 200), c[g] = "+=200px") : (e[g] = x(m(e[g]) + 200), c[g] = "-=200px")); 3967 "none" === d ? b._afterZoomIn() : b.wrap.css(e).animate(c, { 3968 duration: a.nextSpeed, 3969 easing: a.nextEasing, 3970 complete: b._afterZoomIn 3971 }) 3972 }, 3973 changeOut: function() { 3974 var a = b.previous, 3975 d = a.prevEffect, 3976 e = { 3977 opacity: 0.1 3978 }, 3979 c = b.direction; 3980 "elastic" === d && (e["down" === c || "up" === c ? "top" : "left"] = ("up" === c || "left" === c ? "-" : "+") + "=200px"); 3981 a.wrap.animate(e, { 3982 duration: "none" === d ? 0 : a.prevSpeed, 3983 easing: a.prevEasing, 3984 complete: function() { 3985 f(this).trigger("onReset").remove() 3986 } 3987 }) 3988 } 3989 }; 3990 b.helpers.overlay = { 3991 defaults: { 3992 closeClick: !0, 3993 speedOut: 200, 3994 showEarly: !0, 3995 css: {}, 3996 locked: !t, 3997 fixed: !0 3998 }, 3999 overlay: null, 4000 fixed: !1, 4001 el: f("html"), 4002 create: function(a) { 4003 var d; 4004 a = f.extend({}, this.defaults, a); 4005 this.overlay && 4006 this.close(); 4007 d = b.coming ? b.coming.parent : a.parent; 4008 this.overlay = f('<div class="fancybox-overlay"></div>').appendTo(d && d.lenth ? d : "body"); 4009 this.fixed = !1; 4010 a.fixed && b.defaults.fixed && (this.overlay.addClass("fancybox-overlay-fixed"), this.fixed = !0) 4011 }, 4012 open: function(a) { 4013 var d = this; 4014 a = f.extend({}, this.defaults, a); 4015 this.overlay ? this.overlay.unbind(".overlay").width("auto").height("auto") : this.create(a); 4016 this.fixed || (q.bind("resize.overlay", f.proxy(this.update, this)), this.update()); 4017 a.closeClick && this.overlay.bind("click.overlay", 4018 function(a) { 4019 if (f(a.target).hasClass("fancybox-overlay")) return b.isActive ? b.close() : d.close(), !1 4020 }); 4021 this.overlay.css(a.css).show() 4022 }, 4023 close: function() { 4024 q.unbind("resize.overlay"); 4025 this.el.hasClass("fancybox-lock") && (f(".fancybox-margin").removeClass("fancybox-margin"), this.el.removeClass("fancybox-lock"), q.scrollTop(this.scrollV).scrollLeft(this.scrollH)); 4026 f(".fancybox-overlay").remove().hide(); 4027 f.extend(this, { 4028 overlay: null, 4029 fixed: !1 4030 }) 4031 }, 4032 update: function() { 4033 var a = "100%", 4034 b; 4035 this.overlay.width(a).height("100%"); 4036 J ? (b = Math.max(H.documentElement.offsetWidth, H.body.offsetWidth), p.width() > b && (a = p.width())) : p.width() > q.width() && (a = p.width()); 4037 this.overlay.width(a).height(p.height()) 4038 }, 4039 onReady: function(a, b) { 4040 var e = this.overlay; 4041 f(".fancybox-overlay").stop(!0, !0); 4042 e || this.create(a); 4043 a.locked && this.fixed && b.fixed && (b.locked = this.overlay.append(b.wrap), b.fixed = !1); 4044 !0 === a.showEarly && this.beforeShow.apply(this, arguments) 4045 }, 4046 beforeShow: function(a, b) { 4047 b.locked && !this.el.hasClass("fancybox-lock") && (!1 !== this.fixPosition && f("*").filter(function() { 4048 return "fixed" === 4049 f(this).css("position") && !f(this).hasClass("fancybox-overlay") && !f(this).hasClass("fancybox-wrap") 4050 }).addClass("fancybox-margin"), this.el.addClass("fancybox-margin"), this.scrollV = q.scrollTop(), this.scrollH = q.scrollLeft(), this.el.addClass("fancybox-lock"), q.scrollTop(this.scrollV).scrollLeft(this.scrollH)); 4051 this.open(a) 4052 }, 4053 onUpdate: function() { 4054 this.fixed || this.update() 4055 }, 4056 afterClose: function(a) { 4057 this.overlay && !b.coming && this.overlay.fadeOut(a.speedOut, f.proxy(this.close, this)) 4058 } 4059 }; 4060 b.helpers.title = { 4061 defaults: { 4062 type: "float", 4063 position: "bottom" 4064 }, 4065 beforeShow: function(a) { 4066 var d = b.current, 4067 e = d.title, 4068 c = a.type; 4069 f.isFunction(e) && (e = e.call(d.element, d)); 4070 if (r(e) && "" !== f.trim(e)) { 4071 d = f('<div class="fancybox-title fancybox-title-' + c + '-wrap">' + e + "</div>"); 4072 switch (c) { 4073 case "inside": 4074 c = b.skin; 4075 break; 4076 case "outside": 4077 c = b.wrap; 4078 break; 4079 case "over": 4080 c = b.inner; 4081 break; 4082 default: 4083 c = b.skin, d.appendTo("body"), J && d.width(d.width()), d.wrapInner('<span class="child"></span>'), b.current.margin[2] += Math.abs(m(d.css("margin-bottom"))) 4084 } 4085 d["top" === a.position ? "prependTo" : 4086 "appendTo"](c) 4087 } 4088 } 4089 }; 4090 f.fn.fancybox = function(a) { 4091 var d, e = f(this), 4092 c = this.selector || "", 4093 l = function(g) { 4094 var h = f(this).blur(), 4095 k = d, 4096 l, m; 4097 g.ctrlKey || g.altKey || g.shiftKey || g.metaKey || h.is(".fancybox-wrap") || (l = a.groupAttr || "data-fancybox-group", m = h.attr(l), m || (l = "rel", m = h.get(0)[l]), m && "" !== m && "nofollow" !== m && (h = c.length ? f(c) : e, h = h.filter("[" + l + '="' + m + '"]'), k = h.index(this)), a.index = k, !1 !== b.open(h, a) && g.preventDefault()) 4098 }; 4099 a = a || {}; 4100 d = a.index || 0; 4101 c && !1 !== a.live ? p.undelegate(c, "click.fb-start").delegate(c + ":not('.fancybox-item, .fancybox-nav')", 4102 "click.fb-start", l) : e.unbind("click.fb-start").bind("click.fb-start", l); 4103 this.filter("[data-fancybox-start=1]").trigger("click"); 4104 return this 4105 }; 4106 p.ready(function() { 4107 var a, d; 4108 f.scrollbarWidth === w && (f.scrollbarWidth = function() { 4109 var a = f('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"), 4110 b = a.children(), 4111 b = b.innerWidth() - b.height(99).innerWidth(); 4112 a.remove(); 4113 return b 4114 }); 4115 f.support.fixedPosition === w && (f.support.fixedPosition = function() { 4116 var a = f('<div style="position:fixed;top:20px;"></div>').appendTo("body"), 4117 b = 20 === a[0].offsetTop || 15 === a[0].offsetTop; 4118 a.remove(); 4119 return b 4120 }()); 4121 f.extend(b.defaults, { 4122 scrollbarWidth: f.scrollbarWidth(), 4123 fixed: f.support.fixedPosition, 4124 parent: f("body") 4125 }); 4126 a = f(s).width(); 4127 K.addClass("fancybox-lock-test"); 4128 d = f(s).width(); 4129 K.removeClass("fancybox-lock-test"); 4130 f("<style type='text/css'>.fancybox-margin{margin-right:" + (d - a) + "px;}</style>").appendTo("head") 4131 }) 4132})(window, document, jQuery); 4133 4134 4135 4136 4137 4138 4139/*! 4140 * Media helper for fancyBox 4141 * version: 1.0.6 (Fri, 14 Jun 2013) 4142 * @requires fancyBox v2.0 or later 4143 * 4144 * Usage: 4145 * $(".fancybox").fancybox({ 4146 * helpers : { 4147 * media: true 4148 * } 4149 * }); 4150 * 4151 * Set custom URL parameters: 4152 * $(".fancybox").fancybox({ 4153 * helpers : { 4154 * media: { 4155 * youtube : { 4156 * params : { 4157 * autoplay : 0 4158 * } 4159 * } 4160 * } 4161 * } 4162 * }); 4163 * 4164 * Or: 4165 * $(".fancybox").fancybox({, 4166 * helpers : { 4167 * media: true 4168 * }, 4169 * youtube : { 4170 * autoplay: 0 4171 * } 4172 * }); 4173 * 4174 * Supports: 4175 * 4176 * Youtube 4177 * http://www.youtube.com/watch?v=opj24KnzrWo 4178 * http://www.youtube.com/embed/opj24KnzrWo 4179 * http://youtu.be/opj24KnzrWo 4180 * http://www.youtube-nocookie.com/embed/opj24KnzrWo 4181 * Vimeo 4182 * http://vimeo.com/40648169 4183 * http://vimeo.com/channels/staffpicks/38843628
vendor: 5,535 bytes, lines 4184-4332
4184 * http://vimeo.com/groups/surrealism/videos/36516384 4185 * http://player.vimeo.com/video/45074303 4186 * Metacafe 4187 * http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/ 4188 * http://www.metacafe.com/watch/7635964/ 4189 * Dailymotion 4190 * http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people 4191 * Twitvid 4192 * http://twitvid.com/QY7MD 4193 * Twitpic 4194 * http://twitpic.com/7p93st 4195 * Instagram 4196 * http://instagr.am/p/IejkuUGxQn/ 4197 * http://instagram.com/p/IejkuUGxQn/ 4198 * Google maps 4199 * http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17 4200 * http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16 4201 * http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56 4202 */ 4203(function ($) { 4204 "use strict"; 4205 4206 //Shortcut for fancyBox object 4207 var F = $.fancybox, 4208 format = function( url, rez, params ) { 4209 params = params || ''; 4210 4211 if ( $.type( params ) === "object" ) { 4212 params = $.param(params, true); 4213 } 4214 4215 $.each(rez, function(key, value) { 4216 url = url.replace( '$' + key, value || '' ); 4217 }); 4218 4219 if (params.length) { 4220 url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params; 4221 } 4222 4223 return url; 4224 }; 4225 4226 //Add helper object 4227 F.helpers.media = { 4228 defaults : { 4229 youtube : { 4230 matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i, 4231 params : { 4232 autoplay : 1, 4233 autohide : 1, 4234 fs : 1, 4235 rel : 0, 4236 hd : 1, 4237 wmode : 'opaque', 4238 enablejsapi : 1 4239 }, 4240 type : 'iframe', 4241 url : '//www.youtube.com/embed/$3' 4242 }, 4243 vimeo : { 4244 matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/, 4245 params : { 4246 autoplay : 1, 4247 hd : 1, 4248 show_title : 1, 4249 show_byline : 1, 4250 show_portrait : 0, 4251 fullscreen : 1 4252 }, 4253 type : 'iframe', 4254 url : '//player.vimeo.com/video/$1' 4255 }, 4256 metacafe : { 4257 matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/, 4258 params : { 4259 autoPlay : 'yes' 4260 }, 4261 type : 'swf', 4262 url : function( rez, params, obj ) { 4263 obj.swf.flashVars = 'playerVars=' + $.param( params, true ); 4264 4265 return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf'; 4266 } 4267 }, 4268 dailymotion : { 4269 matcher : /dailymotion.com\/video\/(.*)\/?(.*)/, 4270 params : { 4271 additionalInfos : 0, 4272 autoStart : 1 4273 }, 4274 type : 'swf', 4275 url : '//www.dailymotion.com/swf/video/$1' 4276 }, 4277 twitvid : { 4278 matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i, 4279 params : { 4280 autoplay : 0 4281 }, 4282 type : 'iframe', 4283 url : '//www.twitvid.com/embed.php?guid=$1' 4284 }, 4285 twitpic : { 4286 matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i, 4287 type : 'image', 4288 url : '//twitpic.com/show/full/$1/' 4289 }, 4290 instagram : { 4291 matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i, 4292 type : 'image', 4293 url : '//$1/p/$2/media/?size=l' 4294 }, 4295 google_maps : { 4296 matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i, 4297 type : 'iframe', 4298 url : function( rez ) { 4299 return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed'); 4300 } 4301 } 4302 }, 4303 4304 beforeLoad : function(opts, obj) { 4305 var url = obj.href || '', 4306 type = false, 4307 what, 4308 item, 4309 rez, 4310 params; 4311 4312 for (what in opts) { 4313 if (opts.hasOwnProperty(what)) { 4314 item = opts[ what ]; 4315 rez = url.match( item.matcher ); 4316 4317 if (rez) { 4318 type = item.type; 4319 params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null)); 4320 4321 url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params ); 4322 4323 break; 4324 } 4325 } 4326 } 4327 4328 if (type) { 4329 obj.href = url; 4330 obj.type = type; 4331 4332 obj.autoHeight = false;
4333 } 4334 } 4335 }; 4336 4337}(jQuery)); 4338; 4339(function ($, window, document, undefined) { 4340 4341 var pluginName = "MegaMenu", 4342 defaults = { 4343 propertyName: "value" 4344 }; 4345 4346 // Set delay time for mouseout 4347 var delayOut = 400; // Default delay time is 200 4348 4349 // the list of menus 4350 var menus = []; 4351 4352 function CustomMenu(element, options) { 4353 this.element = element; 4354 4355 this.options = $.extend({}, defaults, options); 4356 4357 this._defaults = defaults; 4358 this._name = pluginName; 4359 4360 this.init(); 4361 } 4362 4363 CustomMenu.prototype = { 4364 isOpen: false, 4365 timeout: null, 4366 init: function () { 4367 4368 var that = this; 4369 4370 $(this).each(function(index, menu) { 4371 that.node = menu.element; 4372 that.addListeners(menu.element); 4373 4374 var $menu = $(menu.element); 4375 $menu.addClass("dropdownJavascript"); 4376 menus.push(menu.element); 4377 4378 $menu.find('ul > li').each(function(index, submenu) { 4379 if ($(submenu).find('ul').length > 0 ) { 4380 $(submenu).addClass('with-menu'); 4381 } 4382 }); 4383 }); 4384 }, 4385 addListeners: function(menu) { 4386 var that = this; 4387 $(menu).mouseover(function(e) { 4388 that.handleMouseOver.call(that, e); 4389 }).mouseout(function(e) { 4390 that.handleMouseOut.call(that, e); 4391 }); 4392 }, 4393 handleMouseOver: function (e) { 4394 var that = this; 4395 // clear the timeout 4396 this.clearTimeout(); 4397 4398 // find the parent list item 4399 //var item = ('target' in e ? e.target : e.srcElement); 4400 var item = e.target || e.srcElement; 4401 while (item.nodeName != 'LI' && item != this.node) { 4402 item = item.parentNode; 4403 } 4404 4405 // if the target is within a list item, set the timeout 4406 if (item.nodeName == 'LI') { 4407 this.toOpen = item; 4408 this.timeout = setTimeout(function() { 4409 that.open.call(that); 4410 }, this.options.delay); 4411 } 4412 4413 }, 4414 handleMouseOut: function () { 4415 var that = this; 4416 // clear the timeout 4417 this.clearTimeout(); 4418 4419 // Check mouseout delay overriding 4420 var _delayOut = this.options.delay; 4421 if ( delayOut ) { 4422 _delayOut = delayOut; 4423 } 4424 4425 this.timeout = setTimeout(function() { 4426 that.close.call(that); 4427 }, _delayOut ); 4428 4429 }, 4430 clearTimeout: function () { 4431 4432 // clear the timeout 4433 if (this.timeout) { 4434 clearTimeout(this.timeout); 4435 this.timeout = null; 4436 } 4437 4438 }, 4439 open: function () { 4440 4441 var that = this; 4442 // store that the menu is open 4443 this.isOpen = true; 4444 4445 // loop over the list items with the same parent 4446 var items = $(this.toOpen).parent().children('li'); 4447 $(items).each(function(index, item) { 4448 $(item).find("ul").each(function(index, submenu) { 4449 if (item != that.toOpen) { 4450 // close the submenu 4451 $(item).removeClass("dropdownOpen"); 4452 that.close(item); 4453 4454 } else if (!$(item).hasClass('dropdownOpen')) { 4455 4456 // open the submenu 4457 //if ( !$(item).parents('li').hasClass('has-mega-menu') ) { 4458 $(item).addClass("dropdownOpen"); 4459 //} 4460 4461 4462 // determine the location of the edges of the submenu 4463 var left = 0; 4464 var node = submenu; 4465 while (node) { 4466 //abs is because when you make menus right to left 4467 //the offsetLeft would be negative 4468 left += Math.abs(node.offsetLeft); 4469 node = node.offsetParent; 4470 } 4471 var right = left + submenu.offsetWidth; 4472 4473 4474 //We should refactor this code to execute only when menu is vertical 4475 var menuHeight = $(submenu).outerHeight(); 4476 var parentTop = $(submenu).offset().top - $(window).scrollTop(); 4477 var totalHeight = menuHeight + parentTop; 4478 var windowHeight = window.innerHeight; 4479 4480 /* if (totalHeight > windowHeight) { 4481 var bestTop = (windowHeight - totalHeight) - 20; 4482 $(submenu).css('margin-top', bestTop + "px"); 4483 }*/ 4484 4485 //remove any previous classes 4486 $(item).removeClass('dropdownRightToLeft'); 4487 4488 // move the submenu to the right of the item if appropriate 4489 if (left < 0) $(item).addClass('dropdownLeftToRight'); 4490 4491 // move the submenu to the left of the item if appropriate 4492 if (right > document.body.clientWidth) { 4493 $(item).addClass('dropdownRightToLeft'); 4494 } 4495 4496 } 4497 }); 4498 }); 4499 4500 }, 4501 4502 4503 close: function (node) { 4504 4505 // if no node was specified, close all menus 4506 if (!node) { 4507 this.isOpen = false;
4508 node = this.node; 4509 } 4510 4511 // loop over the items, closing their submenus 4512 $(node).find('li').each(function(index, item) { 4513 $(item).removeClass('dropdownOpen'); 4514 }); 4515 4516 } 4517 }; 4518 4519 $.fn[pluginName] = function (options) { 4520 return this.each(function () { 4521 if (!$.data(this, "plugin_" + pluginName)) { 4522 $.data(this, "plugin_" + pluginName, 4523 new CustomMenu(this, options)); 4524 } 4525 }); 4526 }; 4527 4528})(jQuery, window, document); 4529 4530/*! 4531 * modernizr v3.3.1 4532 * Build https://modernizr.com/download?-cssanimations-csstransitions-touchevents-domprefixes-prefixed-prefixes-setclasses-shiv-testallprops-testprop-teststyles-dontmin 4533 * 4534 * Copyright (c) 4535 * Faruk Ates 4536 * Paul Irish 4537 * Alex Sexton 4538 * Ryan Seddon 4539 * Patrick Kettner 4540 * Stu Cox 4541 * Richard Herrera 4542 4543 * MIT License 4544 */ 4545 4546/* 4547 * Modernizr tests which native CSS3 and HTML5 features are available in the 4548 * current UA and makes the results available to you in two ways: as properties on 4549 * a global `Modernizr` object, and as classes on the `<html>` element. This 4550 * information allows you to progressively enhance your pages with a granular level 4551 * of control over the experience. 4552*/ 4553 4554;(function(window, document, undefined){ 4555 var classes = []; 4556 4557 4558 var tests = []; 4559 4560 4561 /** 4562 * 4563 * ModernizrProto is the constructor for Modernizr 4564 * 4565 * @class 4566 * @access public 4567 */ 4568 4569 var ModernizrProto = { 4570 // The current version, dummy 4571 _version: '3.3.1', 4572 4573 // Any settings that don't work as separate modules 4574 // can go in here as configuration. 4575 _config: { 4576 'classPrefix': '', 4577 'enableClasses': true, 4578 'enableJSClass': true, 4579 'usePrefixes': true 4580 }, 4581 4582 // Queue of tests 4583 _q: [], 4584 4585 // Stub these for people who are listening 4586 on: function(test, cb) { 4587 // I don't really think people should do this, but we can 4588 // safe guard it a bit. 4589 // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests. 4590 // This is in case people listen to synchronous tests. I would leave it out, 4591 // but the code to *disallow* sync tests in the real version of this 4592 // function is actually larger than this. 4593 var self = this; 4594 setTimeout(function() { 4595 cb(self[test]); 4596 }, 0); 4597 }, 4598 4599 addTest: function(name, fn, options) { 4600 tests.push({name: name, fn: fn, options: options}); 4601 }, 4602 4603 addAsyncTest: function(fn) { 4604 tests.push({name: null, fn: fn}); 4605 } 4606 }; 4607 4608 4609 4610 // Fake some of Object.create so we can force non test results to be non "own" properties. 4611 var Modernizr = function() {}; 4612 Modernizr.prototype = ModernizrProto; 4613 4614 // Leak modernizr globally when you `require` it rather than force it here. 4615 // Overwrite name so constructor name is nicer :D 4616 Modernizr = new Modernizr(); 4617 4618 4619 4620 /** 4621 * List of property values to set for css tests. See ticket #21 4622 * http://git.io/vUGl4 4623 * 4624 * @memberof Modernizr 4625 * @name Modernizr._prefixes 4626 * @optionName Modernizr._prefixes 4627 * @optionProp prefixes 4628 * @access public 4629 * @example 4630 * 4631 * Modernizr._prefixes is the internal list of prefixes that we test against 4632 * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply 4633 * an array of kebab-case vendor prefixes you can use within your code. 4634 * 4635 * Some common use cases include 4636 * 4637 * Generating all possible prefixed version of a CSS property 4638 * ```js 4639 * var rule = Modernizr._prefixes.join('transform: rotate(20deg); '); 4640 * 4641 * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);' 4642 * ``` 4643 * 4644 * Generating all possible prefixed version of a CSS value 4645 * ```js 4646 * rule = 'display:' + Modernizr._prefixes.join('flex; display:') + 'flex'; 4647 * 4648 * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex' 4649 * ``` 4650 */ 4651 4652 // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test 4653 // values in feature detects to continue to work 4654 var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['','']); 4655 4656 // expose these for the plugin API. Look in the source for how to join() them against your input 4657 ModernizrProto._prefixes = prefixes; 4658 4659 4660 4661 /** 4662 * is returns a boolean if the typeof an obj is exactly type. 4663 * 4664 * @access private 4665 * @function is 4666 * @param {*} obj - A thing we want to check the type of 4667 * @param {string} type - A string to compare the typeof against 4668 * @returns {boolean} 4669 */ 4670 4671 function is(obj, type) { 4672 return typeof obj === type; 4673 } 4674 ; 4675 4676 /** 4677 * Run through all tests and detect their support in the current UA. 4678 * 4679 * @access private 4680 */ 4681 4682 function testRunner() { 4683 var featureNames; 4684 var feature; 4685 var aliasIdx; 4686 var result; 4687 var nameIdx; 4688 var featureName; 4689 var featureNameSplit; 4690 4691 for (var featureIdx in tests) { 4692 if (tests.hasOwnProperty(featureIdx)) { 4693 featureNames = []; 4694 feature = tests[featureIdx]; 4695 // run the test, throw the return value into the Modernizr, 4696 // then based on that boolean, define an appropriate className 4697 // and push it into an array of classes we'll join later. 4698 // 4699 // If there is no name, it's an 'async' test that is run, 4700 // but not directly added to the object. That should 4701 // be done with a post-run addTest call. 4702 if (feature.name) { 4703 featureNames.push(feature.name.toLowerCase()); 4704 4705 if (feature.options && feature.options.aliases && feature.options.aliases.length) { 4706 // Add all the aliases into the names list 4707 for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) { 4708 featureNames.push(feature.options.aliases[aliasIdx].toLowerCase()); 4709 } 4710 } 4711 } 4712 4713 // Run the test, or use the raw value if it's not a function 4714 result = is(feature.fn, 'function') ? feature.fn() : feature.fn; 4715 4716 4717 // Set each of the names on the Modernizr object 4718 for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) { 4719 featureName = featureNames[nameIdx];
4720 // Support dot properties as sub tests. We don't do checking to make sure 4721 // that the implied parent tests have been added. You must call them in 4722 // order (either in the test, or make the parent test a dependency). 4723 // 4724 // Cap it to TWO to make the logic simple and because who needs that kind of subtesting 4725 // hashtag famous last words 4726 featureNameSplit = featureName.split('.'); 4727 4728 if (featureNameSplit.length === 1) { 4729 Modernizr[featureNameSplit[0]] = result; 4730 } else { 4731 // cast to a Boolean, if not one already 4732 /* jshint -W053 */ 4733 if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { 4734 Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); 4735 } 4736 4737 Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result; 4738 } 4739 4740 classes.push((result ? '' : 'no-') + featureNameSplit.join('-')); 4741 } 4742 } 4743 } 4744 } 4745 ; 4746 4747 /** 4748 * docElement is a convenience wrapper to grab the root element of the document 4749 * 4750 * @access private 4751 * @returns {HTMLElement|SVGElement} The root element of the document 4752 */ 4753 4754 var docElement = document.documentElement; 4755 4756 4757 /** 4758 * A convenience helper to check if the document we are running in is an SVG document 4759 * 4760 * @access private 4761 * @returns {boolean} 4762 */ 4763 4764 var isSVG = docElement.nodeName.toLowerCase() === 'svg'; 4765 4766 4767 /** 4768 * setClasses takes an array of class names and adds them to the root element 4769 * 4770 * @access private 4771 * @function setClasses 4772 * @param {string[]} classes - Array of class names 4773 */ 4774 4775 // Pass in an and array of class names, e.g.:
4776 // ['no-webp', 'borderradius', ...] 4777 function setClasses(classes) { 4778 var className = docElement.className; 4779 var classPrefix = Modernizr._config.classPrefix || ''; 4780 4781 if (isSVG) { 4782 className = className.baseVal; 4783 } 4784 4785 // Change `no-js` to `js` (independently of the `enableClasses` option) 4786 // Handle classPrefix on this too 4787 if (Modernizr._config.enableJSClass) { 4788 var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)'); 4789 className = className.replace(reJS, '$1' + classPrefix + 'js$2'); 4790 } 4791 4792 if (Modernizr._config.enableClasses) { 4793 // Add the new classes 4794 className += ' ' + classPrefix + classes.join(' ' + classPrefix); 4795 isSVG ? docElement.className.baseVal = className : docElement.className = className; 4796 } 4797 4798 } 4799 4800 ; 4801 4802/** 4803 * @optionName html5shiv 4804 * @optionProp html5shiv 4805 */ 4806 4807 // Take the html5 variable out of the html5shiv scope so we can return it. 4808 var html5; 4809 if (!isSVG) { 4810 /** 4811 * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 4812 */ 4813 ;(function(window, document) { 4814 /*jshint evil:true */ 4815 /** version */ 4816 var version = '3.7.3'; 4817 4818 /** Preset options */ 4819 var options = window.html5 || {}; 4820 4821 /** Used to skip problem elements */ 4822 var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; 4823 4824 /** Not all elements can be cloned in IE **/ 4825 var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; 4826 4827 /** Detect whether the browser supports default html5 styles */ 4828 var supportsHtml5Styles; 4829 4830 /** Name of the expando, to work with multiple documents or to re-shiv one document */ 4831 var expando = '_html5shiv'; 4832 4833 /** The id for the the documents expando */ 4834 var expanID = 0; 4835 4836 /** Cached data for each document */ 4837 var expandoData = {}; 4838 4839 /** Detect whether the browser supports unknown elements */ 4840 var supportsUnknownElements; 4841 4842 (function() { 4843 try { 4844 var a = document.createElement('a'); 4845 a.innerHTML = '<xyz></xyz>'; 4846 //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles 4847 supportsHtml5Styles = ('hidden' in a); 4848 4849 supportsUnknownElements = a.childNodes.length == 1 || (function() { 4850 // assign a false positive if unable to shiv 4851 (document.createElement)('a'); 4852 var frag = document.createDocumentFragment(); 4853 return ( 4854 typeof frag.cloneNode == 'undefined' || 4855 typeof frag.createDocumentFragment == 'undefined' || 4856 typeof frag.createElement == 'undefined' 4857 ); 4858 }()); 4859 } catch(e) { 4860 // assign a false positive if detection fails => unable to shiv 4861 supportsHtml5Styles = true; 4862 supportsUnknownElements = true; 4863 } 4864 4865 }()); 4866 4867 /*--------------------------------------------------------------------------*/ 4868 4869 /** 4870 * Creates a style sheet with the given CSS text and adds it to the document. 4871 * @private 4872 * @param {Document} ownerDocument The document. 4873 * @param {String} cssText The CSS text. 4874 * @returns {StyleSheet} The style element. 4875 */ 4876 function addStyleSheet(ownerDocument, cssText) { 4877 var p = ownerDocument.createElement('p'), 4878 parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; 4879 4880 p.innerHTML = 'x<style>' + cssText + '</style>'; 4881 return parent.insertBefore(p.lastChild, parent.firstChild); 4882 } 4883 4884 /** 4885 * Returns the value of `html5.elements` as an array. 4886 * @private 4887 * @returns {Array} An array of shived element node names. 4888 */ 4889 function getElements() { 4890 var elements = html5.elements; 4891 return typeof elements == 'string' ? elements.split(' ') : elements; 4892 } 4893 4894 /** 4895 * Extends the built-in list of html5 elements 4896 * @memberOf html5 4897 * @param {String|Array} newElements whitespace separated list or array of new element names to shiv 4898 * @param {Document} ownerDocument The context document. 4899 */ 4900 function addElements(newElements, ownerDocument) { 4901 var elements = html5.elements; 4902 if(typeof elements != 'string'){ 4903 elements = elements.join(' '); 4904 } 4905 if(typeof newElements != 'string'){ 4906 newElements = newElements.join(' '); 4907 } 4908 html5.elements = elements +' '+ newElements; 4909 shivDocument(ownerDocument); 4910 } 4911 4912 /** 4913 * Returns the data associated to the given document 4914 * @private 4915 * @param {Document} ownerDocument The document. 4916 * @returns {Object} An object of data. 4917 */ 4918 function getExpandoData(ownerDocument) { 4919 var data = expandoData[ownerDocument[expando]]; 4920 if (!data) { 4921 data = {}; 4922 expanID++; 4923 ownerDocument[expando] = expanID; 4924 expandoData[expanID] = data; 4925 } 4926 return data; 4927 } 4928 4929 /** 4930 * returns a shived element for the given nodeName and document 4931 * @memberOf html5 4932 * @param {String}
vendor: 4,418 bytes, lines 4932-5043
4932 nodeName name of the element 4933 * @param {Document|DocumentFragment} ownerDocument The context document. 4934 * @returns {Object} The shived element. 4935 */ 4936 function createElement(nodeName, ownerDocument, data){ 4937 if (!ownerDocument) { 4938 ownerDocument = document; 4939 } 4940 if(supportsUnknownElements){ 4941 return ownerDocument.createElement(nodeName); 4942 } 4943 if (!data) { 4944 data = getExpandoData(ownerDocument); 4945 } 4946 var node; 4947 4948 if (data.cache[nodeName]) { 4949 node = data.cache[nodeName].cloneNode(); 4950 } else if (saveClones.test(nodeName)) { 4951 node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); 4952 } else { 4953 node = data.createElem(nodeName); 4954 } 4955 4956 // Avoid adding some elements to fragments in IE < 9 because 4957 // * Attributes like `name` or `type` cannot be set/changed once an element 4958 // is inserted into a document/fragment 4959 // * Link elements with `src` attributes that are inaccessible, as with 4960 // a 403 response, will cause the tab/window to crash 4961 // * Script elements appended to fragments will execute when their `src` 4962 // or `text` property is set 4963 return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; 4964 } 4965 4966 /** 4967 * returns a shived DocumentFragment for the given document 4968 * @memberOf html5 4969 * @param {Document} ownerDocument The context document. 4970 * @returns {Object} The shived DocumentFragment. 4971 */ 4972 function createDocumentFragment(ownerDocument, data){ 4973 if (!ownerDocument) { 4974 ownerDocument = document; 4975 } 4976 if(supportsUnknownElements){ 4977 return ownerDocument.createDocumentFragment(); 4978 } 4979 data = data || getExpandoData(ownerDocument); 4980 var clone = data.frag.cloneNode(), 4981 i = 0, 4982 elems = getElements(), 4983 l = elems.length; 4984 for(;i<l;i++){ 4985 clone.createElement(elems[i]); 4986 } 4987 return clone; 4988 } 4989 4990 /** 4991 * Shivs the `createElement` and `createDocumentFragment` methods of the document. 4992 * @private 4993 * @param {Document|DocumentFragment} ownerDocument The document. 4994 * @param {Object} data of the document. 4995 */ 4996 function shivMethods(ownerDocument, data) { 4997 if (!data.cache) { 4998 data.cache = {}; 4999 data.createElem = ownerDocument.createElement; 5000 data.createFrag = ownerDocument.createDocumentFragment; 5001 data.frag = data.createFrag(); 5002 } 5003 5004 5005 ownerDocument.createElement = function(nodeName) { 5006 //abort shiv 5007 if (!html5.shivMethods) { 5008 return data.createElem(nodeName); 5009 } 5010 return createElement(nodeName, ownerDocument, data); 5011 }; 5012 5013 ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 5014 'var n=f.cloneNode(),c=n.createElement;' + 5015 'h.shivMethods&&(' + 5016 // unroll the `createElement` calls 5017 getElements().join().replace(/[\w\-:]+/g, function(nodeName) { 5018 data.createElem(nodeName); 5019 data.frag.createElement(nodeName); 5020 return 'c("' + nodeName + '")'; 5021 }) + 5022 ');return n}' 5023 )(html5, data.frag); 5024 } 5025 5026 /*--------------------------------------------------------------------------*/ 5027 5028 /** 5029 * Shivs the given document. 5030 * @memberOf html5 5031 * @param {Document} ownerDocument The document to shiv. 5032 * @returns {Document} The shived document. 5033 */ 5034 function shivDocument(ownerDocument) { 5035 if (!ownerDocument) { 5036 ownerDocument = document; 5037 } 5038 var data = getExpandoData(ownerDocument); 5039 5040 if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { 5041 data.hasCSS = !!addStyleSheet(ownerDocument, 5042 // corrects block display not defined in IE6/7/8/9 5043 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
5043play:block}' + 5044 // adds styling not present in IE6/7/8/9 5045 'mark{background:#FF0;color:#000}' + 5046 // hides non-rendered elements 5047 'template{display:none}' 5048 ); 5049 } 5050 if (!supportsUnknownElements) { 5051 shivMethods(ownerDocument, data); 5052 } 5053 return ownerDocument; 5054 } 5055 5056 /*--------------------------------------------------------------------------*/ 5057 5058 /** 5059 * The `html5` object is exposed so that more elements can be shived and 5060 * existing shiving can be detected on iframes. 5061 * @type Object 5062 * @example 5063 * 5064 * // options can be changed before the script is included 5065 * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; 5066 */ 5067 var html5 = { 5068 5069 /** 5070 * An array or space separated string of node names of the elements to shiv. 5071 * @memberOf html5 5072 * @type Array|String 5073 */ 5074 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video', 5075 5076 /** 5077 * current version of html5shiv 5078 */ 5079 'version': version, 5080 5081 /** 5082 * A flag to indicate that the HTML5 style sheet should be inserted. 5083 * @memberOf html5 5084 * @type Boolean 5085 */ 5086 'shivCSS': (options.shivCSS !== false), 5087 5088 /** 5089 * Is equal to true if a browser supports creating unknown/HTML5 elements 5090 * @memberOf html5 5091 * @type boolean 5092 */ 5093 'supportsUnknownElements': supportsUnknownElements, 5094 5095 /** 5096 * A flag to indicate that the document's `createElement` and `createDocumentFragment` 5097 * methods should be overwritten. 5098 * @memberOf html5 5099 * @type Boolean 5100 */ 5101 'shivMethods': (options.shivMethods !== false), 5102 5103 /** 5104 * A string to describe the type of `html5` object ("default" or "default print"). 5105 * @memberOf html5
5106 * @type String 5107 */ 5108 'type': 'default', 5109 5110 // shivs the document according to the specified `html5` object options 5111 'shivDocument': shivDocument, 5112 5113 //creates a shived element 5114 createElement: createElement, 5115 5116 //creates a shived documentFragment 5117 createDocumentFragment: createDocumentFragment, 5118 5119 //extends list of elements 5120 addElements: addElements 5121 }; 5122 5123 /*--------------------------------------------------------------------------*/ 5124 5125 // expose html5 5126 window.html5 = html5; 5127 5128 // shiv the document 5129 shivDocument(document); 5130 5131 if(typeof module == 'object' && module.exports){ 5132 module.exports = html5; 5133 } 5134 5135 }(typeof window !== "undefined" ? window : this, document)); 5136 } 5137; 5138 5139 /** 5140 * If the browsers follow the spec, then they would expose vendor-specific style as: 5141 * elem.style.WebkitBorderRadius 5142 * instead of something like the following, which would be technically incorrect: 5143 * elem.style.webkitBorderRadius 5144 5145 * Webkit ghosts their properties in lowercase but Opera & Moz do not. 5146 * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ 5147 * erik.eae.net/archives/2008/03/10/21.48.10/ 5148 5149 * More here: github.com/Modernizr/Modernizr/issues/issue/21 5150 * 5151 * @access private 5152 * @returns {string} The string representing the vendor-specific style properties 5153 */ 5154 5155 var omPrefixes = 'Moz O ms Webkit'; 5156 5157 5158 /** 5159 * List of JavaScript DOM values used for tests 5160 * 5161 * @memberof Modernizr 5162 * @name Modernizr._domPrefixes 5163 * @optionName Modernizr._domPrefixes 5164 * @optionProp domPrefixes 5165 * @access public 5166 * @example 5167 * 5168 * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather 5169 * than kebab-case properties, all properties are their Capitalized variant 5170 * 5171 * ```js 5172 * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ]; 5173 * ``` 5174 */ 5175 5176 var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []); 5177 ModernizrProto._domPrefixes = domPrefixes; 5178 5179 5180 /** 5181 * cssToDOM takes a kebab-case string and converts it to camelCase 5182 * e.g. box-sizing -> boxSizing 5183 * 5184 * @access private 5185 * @function cssToDOM 5186 * @param {string} name - String name of kebab-case prop we want to convert 5187 * @returns {string} The camelCase version of the supplied name 5188 */ 5189 5190 function cssToDOM(name) { 5191 return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) { 5192 return m1 + m2.toUpperCase(); 5193 }).replace(/^-/, ''); 5194 } 5195 ; 5196 5197 var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []); 5198 ModernizrProto._cssomPrefixes = cssomPrefixes; 5199 5200 5201 /** 5202 * atRule returns a given CSS property at-rule (eg @keyframes), possibly in 5203 * some prefixed form, or false, in the case of an unsupported rule 5204 * 5205 * @memberof Modernizr 5206 * @name Modernizr.atRule 5207 * @optionName Modernizr.atRule() 5208 * @optionProp atRule 5209 * @access public 5210 * @function atRule 5211 * @param {string} prop - String name of the @-rule to test for 5212 * @returns {string|boolean} The string representing the (possibly prefixed) 5213 * valid version of the @-rule, or `false` when it is unsupported. 5214 * @example 5215 * ```js 5216 * var keyframes = Modernizr.atRule('@keyframes'); 5217 * 5218 * if (keyframes) { 5219 * // keyframes are supported 5220 * // could be `@-webkit-keyframes` or `@keyframes` 5221 * } else { 5222 * // keyframes === `false` 5223 * } 5224 * ``` 5225 * 5226 */ 5227 5228 var atRule = function(prop) { 5229 var length = prefixes.length; 5230 var cssrule = window.CSSRule; 5231 var rule; 5232 5233 if (typeof cssrule === 'undefined') { 5234 return undefined; 5235 } 5236 5237 if (!prop) { 5238 return false; 5239 } 5240 5241 // remove literal @ from beginning of provided property 5242 prop = prop.replace(/^@/, ''); 5243 5244 // CSSRules use underscores instead of dashes 5245 rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE'; 5246 5247 if (rule in cssrule) { 5248 return '@' + prop; 5249 } 5250 5251 for (var i = 0; i < length; i++) { 5252 // prefixes gives us something like -o-, and we want O_ 5253 var prefix = prefixes[i]; 5254 var thisRule = prefix.toUpperCase() + '_' + rule; 5255 5256 if (thisRule in cssrule) { 5257 return '@-' + prefix.toLowerCase() + '-' + prop; 5258 } 5259 } 5260 5261 return false;
5262 }; 5263 5264 ModernizrProto.atRule = atRule; 5265 5266 5267 5268 5269 /** 5270 * contains checks to see if a string contains another string 5271 * 5272 * @access private 5273 * @function contains 5274 * @param {string} str - The string we want to check for substrings 5275 * @param {string} substr - The substring we want to search the first string for 5276 * @returns {boolean} 5277 */ 5278 5279 function contains(str, substr) { 5280 return !!~('' + str).indexOf(substr); 5281 } 5282 5283 ; 5284 5285 /** 5286 * createElement is a convenience wrapper around document.createElement. Since we 5287 * use createElement all over the place, this allows for (slightly) smaller code 5288 * as well as abstracting away issues with creating elements in contexts other than 5289 * HTML documents (e.g. SVG documents). 5290 * 5291 * @access private 5292 * @function createElement 5293 * @returns {HTMLElement|SVGElement} An HTML or SVG element 5294 */ 5295 5296 function createElement() { 5297 if (typeof document.createElement !== 'function') { 5298 // This is the case in IE7, where the type of createElement is "object". 5299 // For this reason, we cannot call apply() as Object is not a Function. 5300 return document.createElement(arguments[0]); 5301 } else if (isSVG) { 5302 return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]); 5303 } else { 5304 return document.createElement.apply(document, arguments); 5305 } 5306 } 5307 5308 ; 5309 5310 /** 5311 * getBody returns the body of a document, or an element that can stand in for 5312 * the body if a real body does not exist 5313 * 5314 * @access private 5315 * @function getBody 5316 * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an 5317 * artificially created element that stands in for the body 5318 */ 5319 5320 function getBody() { 5321 // After page load injecting a fake body doesn't work so check if body exists 5322 var body = document.body; 5323 5324 if (!body) { 5325 // Can't use the real body create a fake one. 5326 body = createElement(isSVG ? 'svg' : 'body'); 5327 body.fake = true; 5328 } 5329 5330 return body; 5331 } 5332 5333 ; 5334 5335 /** 5336 * injectElementWithStyles injects an element with style element and some CSS rules 5337 * 5338 * @access private 5339 * @function injectElementWithStyles 5340 * @param {string} rule - String representing a css rule 5341 * @param {function} callback - A function that is used to test the injected element 5342 * @param {number} [nodes] - An integer representing the number of additional nodes you want injected 5343 * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes 5344 * @returns {boolean} 5345 */ 5346 5347 function injectElementWithStyles(rule, callback, nodes, testnames) { 5348 var mod = 'modernizr'; 5349 var style; 5350 var ret; 5351 var node; 5352 var docOverflow; 5353 var div = createElement('div'); 5354 var body = getBody(); 5355 5356 if (parseInt(nodes, 10)) { 5357 // In order not to give false positives we create a node for each test 5358 // This also allows the method to scale for unspecified uses 5359 while (nodes--) { 5360 node = createElement('div'); 5361 node.id = testnames ? testnames[nodes] : mod + (nodes + 1); 5362 div.appendChild(node); 5363 } 5364 } 5365 5366 style = createElement('style'); 5367 style.type = 'text/css'; 5368 style.id = 's' + mod; 5369 5370 // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. 5371 // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 5372 (!body.fake ? div : body).appendChild(style); 5373 body.appendChild(div); 5374 5375 if (style.styleSheet) { 5376 style.styleSheet.cssText = rule; 5377 } else { 5378 style.appendChild(document.createTextNode(rule)); 5379 } 5380 div.id = mod; 5381 5382 if (body.fake) { 5383 //avoid crashing IE8, if background image is used 5384 body.style.background = ''; 5385 //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible 5386 body.style.overflow = 'hidden'; 5387 docOverflow = docElement.style.overflow; 5388 docElement.style.overflow = 'hidden'; 5389 docElement.appendChild(body); 5390 } 5391 5392 ret = callback(div, rule); 5393 // If this is done after page load we don't want to remove the body so check if body exists 5394 if (body.fake) { 5395 body.parentNode.removeChild(body); 5396 docElement.style.overflow = docOverflow; 5397 // Trigger layout so kinetic scrolling isn't disabled in iOS6+ 5398 docElement.offsetHeight; 5399 } else { 5400 div.parentNode.removeChild(div); 5401 } 5402 5403 return !!ret; 5404 5405 } 5406 5407 ; 5408 5409 /** 5410 * testStyles injects an element with style element and some CSS rules 5411 * 5412 * @memberof Modernizr 5413 * @name Modernizr.testStyles 5414 * @optionName Modernizr.testStyles() 5415 * @optionProp testStyles 5416 * @access public 5417 * @function testStyles 5418 * @param {string} rule - String representing a css rule 5419 * @param {function} callback - A function that is used to test the injected element 5420 * @param {number} [nodes] - An integer representing the number of additional nodes you want injected 5421 * @param {string[]}
5421 [testnames] - An array of strings that are used as ids for the additional nodes 5422 * @returns {boolean} 5423 * @example 5424 * 5425 * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page 5426 * along with (possibly multiple) DOM elements. This lets you check for features 5427 * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules). 5428 * 5429 * ```js 5430 * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) { 5431 * // elem is the first DOM node in the page (by default #modernizr) 5432 * // rule is the first argument you supplied - the CSS rule in string form 5433 * 5434 * addTest('widthworks', elem.style.width === '9px') 5435 * }); 5436 * ``` 5437 * 5438 * If your test requires multiple nodes, you can include a third argument 5439 * indicating how many additional div elements to include on the page. The 5440 * additional nodes are injected as children of the `elem` that is returned as 5441 * the first argument to the callback. 5442 * 5443 * ```js 5444 * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) { 5445 * document.getElementById('modernizr').style.width === '1px'; // true 5446 * document.getElementById('modernizr2').style.width === '2px'; // true 5447 * elem.firstChild === document.getElementById('modernizr2'); // true 5448 * }, 1); 5449 * ``` 5450 * 5451 * By default, all of the additional elements have an ID of `modernizr[n]`, where 5452 * `n` is its index (e.g. the first additional, second overall is `#modernizr2`, 5453 * the second additional is `#modernizr3`, etc.). 5454 * If you want to have more meaningful IDs for your function, you can provide 5455 * them as the fourth argument, as an array of strings 5456 * 5457 * ```js 5458 * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) { 5459 * elem.firstChild === document.getElementById('foo'); // true 5460 * elem.lastChild === document.getElementById('bar'); // true 5461 * }, 2, ['foo', 'bar']); 5462 * ``` 5463 * 5464 */ 5465 5466 var testStyles = ModernizrProto.testStyles = injectElementWithStyles; 5467 5468 5469 /** 5470 * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill. 5471 * 5472 * @access private 5473 * @function fnBind 5474 * @param {function} fn - a function you want to change `this` reference to 5475 * @param {object} that - the `this` you want to call the function with 5476 * @returns {function} The wrapped version of the supplied function 5477 */ 5478 5479 function fnBind(fn, that) { 5480 return function() { 5481 return fn.apply(that, arguments); 5482 }; 5483 } 5484 5485 ; 5486 5487 /** 5488 * testDOMProps is a generic DOM property test; if a browser supports 5489 * a certain property, it won't return undefined for it. 5490 * 5491 * @access private 5492 * @function testDOMProps 5493 * @param {array.<string>} props - An array of properties to test for 5494 * @param {object} obj - An object or Element you want to use to test the parameters again 5495 * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check 5496 */ 5497 function testDOMProps(props, obj, elem) { 5498 var item; 5499 5500 for (var i in props) { 5501 if (props[i] in obj) { 5502 5503 // return the property name as a string 5504 if (elem === false) { 5505 return props[i]; 5506 } 5507 5508 item = obj[props[i]]; 5509 5510 // let's bind a function 5511 if (is(item, 'function')) { 5512 // bind to obj unless overriden 5513 return fnBind(item, elem || obj); 5514 } 5515 5516 // return the unbound function or obj or value 5517 return item; 5518 } 5519 } 5520 return false; 5521 } 5522 5523 ; 5524 5525 /** 5526 * Create our "modernizr" element that we do most feature tests on. 5527 * 5528 * @access private 5529 */ 5530 5531 var modElem = { 5532 elem: createElement('modernizr') 5533 }; 5534 5535 // Clean up this element 5536 Modernizr._q.push(function() { 5537 delete modElem.elem; 5538 }); 5539 5540 5541 5542 var mStyle = { 5543 style: modElem.elem.style 5544 }; 5545 5546 // kill ref for gc, must happen before mod.elem is removed, so we unshift on to 5547 // the front of the queue. 5548 Modernizr._q.unshift(function() { 5549 delete mStyle.style; 5550 }); 5551 5552 5553 5554 /** 5555 * domToCSS takes a camelCase string and converts it to kebab-case 5556 * e.g. boxSizing -> box-sizing 5557 * 5558 * @access private 5559 * @function domToCSS 5560 * @param {string} name - String name of camelCase prop we want to convert 5561 * @returns {string} The kebab-case version of the supplied name 5562 */ 5563 5564 function domToCSS(name) { 5565 return name.replace(/([A-Z])/g, function(str, m1) { 5566 return '-' + m1.toLowerCase(); 5567 }).replace(/^ms-/, '-ms-'); 5568 } 5569 ; 5570 5571 /** 5572 * nativeTestProps allows for us to use native feature detection functionality if available. 5573 * some prefixed form, or false, in the case of an unsupported rule 5574 * 5575 * @access private 5576 * @function nativeTestProps 5577 * @param {array} props - An array of property names 5578 * @param {string} value - A string representing the value we want to check via @supports 5579 * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise 5580 */ 5581 5582 // Accepts a list of property names and a single value 5583 // Returns `undefined` if native detection not available 5584 function nativeTestProps(props, value) { 5585 var i = props.length; 5586 // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface 5587 if ('CSS' in window && 'supports' in window.CSS) { 5588 // Try every prefixed variant of the property 5589 while (i--) { 5590 if (window.CSS.supports(domToCSS(props[i]), value)) { 5591 return true; 5592 } 5593 } 5594 return false;
5595 } 5596 // Otherwise fall back to at-rule (for Opera 12.x) 5597 else if ('CSSSupportsRule' in window) { 5598 // Build a condition string for every prefixed variant 5599 var conditionText = []; 5600 while (i--) { 5601 conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')'); 5602 } 5603 conditionText = conditionText.join(' or '); 5604 return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) { 5605 return getComputedStyle(node, null).position == 'absolute'; 5606 }); 5607 } 5608 return undefined; 5609 } 5610 ; 5611 5612 // testProps is a generic CSS / DOM property test. 5613 5614 // In testing support for a given CSS property, it's legit to test: 5615 // `elem.style[styleName] !== undefined` 5616 // If the property is supported it will return an empty string, 5617 // if unsupported it will return undefined. 5618 5619 // We'll take advantage of this quick test and skip setting a style 5620 // on our modernizr element, but instead just testing undefined vs 5621 // empty string. 5622 5623 // Property names can be provided in either camelCase or kebab-case. 5624 5625 function testProps(props, prefixed, value, skipValueTest) { 5626 skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest; 5627 5628 // Try native detect first 5629 if (!is(value, 'undefined')) { 5630 var result = nativeTestProps(props, value); 5631 if (!is(result, 'undefined')) { 5632 return result; 5633 } 5634 } 5635 5636 // Otherwise do it properly 5637 var afterInit, i, propsLength, prop, before; 5638 5639 // If we don't have a style element, that means we're running async or after 5640 // the core tests, so we'll need to create our own elements to use 5641 5642 // inside of an SVG element, in certain browsers, the `style` element is only 5643 // defined for valid tags. Therefore, if `modernizr` does not have one, we 5644 // fall back to a less used element and hope for the best. 5645 // for strict XHTML browsers the hardly used samp element is used 5646 var elems = ['modernizr', 'tspan', 'samp']; 5647 while (!mStyle.style && elems.length) { 5648 afterInit = true; 5649 mStyle.modElem = createElement(elems.shift()); 5650 mStyle.style = mStyle.modElem.style; 5651 } 5652 5653 // Delete the objects if we created them. 5654 function cleanElems() { 5655 if (afterInit) { 5656 delete mStyle.style; 5657 delete mStyle.modElem; 5658 } 5659 } 5660 5661 propsLength = props.length; 5662 for (i = 0; i < propsLength; i++) { 5663 prop = props[i]; 5664 before = mStyle.style[prop]; 5665 5666 if (contains(prop, '-')) { 5667 prop = cssToDOM(prop); 5668 } 5669 5670 if (mStyle.style[prop] !== undefined) { 5671 5672 // If value to test has been passed in, do a set-and-check test. 5673 // 0 (integer) is a valid property value, so check that `value` isn't 5674 // undefined, rather than just checking it's truthy. 5675 if (!skipValueTest && !is(value, 'undefined')) { 5676 5677 // Needs a try catch block because of old IE. This is slow, but will 5678 // be avoided in most cases because `skipValueTest` will be used. 5679 try { 5680 mStyle.style[prop] = value; 5681 } catch (e) {} 5682 5683 // If the property value has changed, we assume the value used is 5684 // supported. If `value` is empty string, it'll fail here (because 5685 // it hasn't changed), which matches how browsers have implemented 5686 // CSS.supports() 5687 if (mStyle.style[prop] != before) { 5688 cleanElems(); 5689 return prefixed == 'pfx' ? prop : true; 5690 } 5691 } 5692 // Otherwise just return true, or the property name if this is a 5693 // `prefixed()` call 5694 else { 5695 cleanElems(); 5696 return prefixed == 'pfx' ? prop : true; 5697 } 5698 } 5699 } 5700 cleanElems(); 5701 return false; 5702 } 5703 5704 ; 5705 5706 /** 5707 * testProp() investigates whether a given style property is recognized 5708 * Property names can be provided in either camelCase or kebab-case. 5709 * 5710 * @memberof Modernizr 5711 * @name Modernizr.testProp 5712 * @access public 5713 * @optionName Modernizr.testProp() 5714 * @optionProp testProp 5715 * @function testProp 5716 * @param {string} prop - Name of the CSS property to check 5717 * @param {string} [value] - Name of the CSS value to check 5718 * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported 5719 * @returns {boolean} 5720 * @example 5721 * 5722 * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed 5723 * version of the string. 5724 * 5725 * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing) 5726 * 5727 * ```js 5728 * Modernizr.testProp('pointerEvents') // true 5729 * ``` 5730 * 5731 * You can also provide a value as an optional second argument to check if a 5732 * specific value is supported 5733 * 5734 * ```js
5735 * Modernizr.testProp('pointerEvents', 'none') // true 5736 * Modernizr.testProp('pointerEvents', 'penguin') // false 5737 * ``` 5738 */ 5739 5740 var testProp = ModernizrProto.testProp = function(prop, value, useValue) { 5741 return testProps([prop], undefined, value, useValue); 5742 }; 5743 5744 5745 /** 5746 * testPropsAll tests a list of DOM properties we want to check against. 5747 * We specify literally ALL possible (known and/or likely) properties on 5748 * the element including the non-vendor prefixed one, for forward- 5749 * compatibility. 5750 * 5751 * @access private 5752 * @function testPropsAll 5753 * @param {string} prop - A string of the property to test for 5754 * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip 5755 * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against 5756 * @param {string} [value] - A string of a css value 5757 * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set 5758 */ 5759 function testPropsAll(prop, prefixed, elem, value, skipValueTest) { 5760 5761 var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), 5762 props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); 5763 5764 // did they call .prefixed('boxSizing') or are we just testing a prop? 5765 if (is(prefixed, 'string') || is(prefixed, 'undefined')) { 5766 return testProps(props, prefixed, value, skipValueTest); 5767 5768 // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) 5769 } else { 5770 props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); 5771 return testDOMProps(props, prefixed, elem); 5772 } 5773 } 5774 5775 // Modernizr.testAllProps() investigates whether a given style property, 5776 // or any of its vendor-prefixed variants, is recognized 5777 // 5778 // Note that the property names must be provided in the camelCase variant. 5779 // Modernizr.testAllProps('boxSizing') 5780 ModernizrProto.testAllProps = testPropsAll; 5781 5782 5783 5784 /** 5785 * prefixed returns the prefixed or nonprefixed property name variant of your input 5786 * 5787 * @memberof Modernizr 5788 * @name Modernizr.prefixed 5789 * @optionName Modernizr.prefixed() 5790 * @optionProp prefixed 5791 * @access public 5792 * @function prefixed 5793 * @param {string} prop - String name of the property to test for 5794 * @param {object} [obj] - An object to test for the prefixed properties on 5795 * @param {HTMLElement} [elem] - An element used to test specific properties against 5796 * @returns {string|false} The string representing the (possibly prefixed) valid 5797 * version of the property, or `false` when it is unsupported. 5798 * @example 5799 * 5800 * Modernizr.prefixed takes a string css value in the DOM style camelCase (as 5801 * opposed to the css style kebab-case) form and returns the (possibly prefixed) 5802 * version of that property that the browser actually supports. 5803 * 5804 * For example, in older Firefox... 5805 * ```js 5806 * prefixed('boxSizing') 5807 * ``` 5808 * returns 'MozBoxSizing' 5809 * 5810 * In newer Firefox, as well as any other browser that support the unprefixed 5811 * version would simply return `boxSizing`. Any browser that does not support 5812 * the property at all, it will return `false`. 5813 * 5814 * By default, prefixed is checked against a DOM element. If you want to check 5815 * for a property on another object, just pass it as a second argument 5816 * 5817 * ```js 5818 * var rAF = prefixed('requestAnimationFrame', window); 5819 * 5820 * raf(function() { 5821 * renderFunction(); 5822 * }) 5823 * ``` 5824 * 5825 * Note that this will return _the actual function_ - not the name of the function. 5826 * If you need the actual name of the property, pass in `false` as a third argument 5827 * 5828 * ```js 5829 * var rAFProp = prefixed('requestAnimationFrame', window, false); 5830 * 5831 * rafProp === 'WebkitRequestAnimationFrame' // in older webkit 5832 * ``` 5833 * 5834 * One common use case for prefixed is if you're trying to determine which transition 5835 * end event to bind to, you might do something like... 5836 * ```js 5837 * var transEndEventNames = { 5838 * 'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser 5839 * 'MozTransition' : 'transitionend', * only for FF < 15 5840 * 'transition' : 'transitionend' * IE10, Opera, Chrome, FF 15+, Saf 7+ 5841 * }; 5842 * 5843 * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; 5844 * ``` 5845 * 5846 * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss). 5847 */ 5848 5849 var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) { 5850 if (prop.indexOf('@') === 0) { 5851 return atRule(prop); 5852 } 5853 5854 if (prop.indexOf('-') != -1) { 5855 // Convert kebab-case to camelCase 5856 prop = cssToDOM(prop); 5857 } 5858 if (!obj) { 5859 return testPropsAll(prop, 'pfx'); 5860 } else { 5861 // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame' 5862 return testPropsAll(prop, obj, elem); 5863 } 5864 }; 5865 5866 5867 5868 /** 5869 * testAllProps determines whether a given CSS property is supported in the browser 5870 * 5871 * @memberof Modernizr 5872 * @name Modernizr.testAllProps 5873 * @optionName Modernizr.testAllProps() 5874 * @optionProp testAllProps 5875 * @access public 5876 * @function testAllProps 5877 * @param {string} prop - String naming the property to test (either camelCase or kebab-case) 5878 * @param {string} [value] - String of the value to test 5879 * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection 5880 * @example 5881 * 5882 * testAllProps determines whether a given CSS property, in some prefixed form, 5883 * is supported by the browser. 5884 * 5885 * ```js 5886 * testAllProps('boxSizing') // true 5887 * ``` 5888 * 5889 * It can optionally be given a CSS value in string form to test if a property 5890 * value is valid 5891 * 5892 * ```js 5893 * testAllProps('display', 'block') // true 5894 * testAllProps('display', 'penguin') // false 5895 * ``` 5896 * 5897 * A boolean can be passed as a third parameter to skip the value check when 5898 * native detection (@supports) isn't available. 5899 * 5900 * ```js 5901 * testAllProps('shapeOutside', 'content-box', true); 5902 * ``` 5903 */ 5904 5905 function testAllProps(prop, value, skipValueTest) { 5906 return testPropsAll(prop, undefined, undefined, value, skipValueTest); 5907 } 5908 ModernizrProto.testAllProps = testAllProps; 5909 5910/*! 5911{ 5912 "name": "CSS Animations", 5913 "property": "cssanimations", 5914 "caniuse": "css-animation", 5915 "polyfills": ["transformie", "csssandpaper"], 5916 "tags": ["css"], 5917 "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"], 5918 "notes": [{ 5919 "name" : "Article: 'Dispelling the Android CSS animation myths'", 5920 "href": "https://goo.gl/OGw5Gm" 5921 }] 5922} 5923!*/ 5924/* DOC 5925Detects whether or not elements can be animated using CSS 5926*/ 5927 5928 Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true)); 5929 5930/*! 5931{ 5932 "name": "CSS Transitions", 5933 "property": "csstransitions", 5934 "caniuse": "css-transitions", 5935 "tags": ["css"] 5936} 5937!*/ 5938 5939 Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true)); 5940 5941/*! 5942{ 5943 "name": "Touch Events", 5944 "property": "touchevents", 5945 "caniuse" : "touch", 5946 "tags": ["media", "attribute"], 5947 "notes": [{ 5948 "name": "Touch Events spec", 5949 "href": "https://www.w3.org/TR/2013/WD-touch-events-20130124/" 5950 }], 5951 "warnings": [ 5952 "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device" 5953 ], 5954 "knownBugs": [ 5955 "False-positive on some configurations of Nokia N900", 5956 "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695" 5957 ] 5958} 5959!*/ 5960/* DOC 5961Indicates if the browser supports the W3C Touch Events API. 5962 5963This *does not* necessarily reflect a touchscreen device: 5964 5965* Older touchscreen devices only emulate mouse events 5966* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that 5967* Some browsers & OS setups may enable touch APIs when no touchscreen is connected 5968* Future browsers may implement other event models for touch interactions 5969 5970See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/). 5971 5972It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/). 5973 5974This test will also return `true` for Firefox 4 Multitouch support. 5975*/ 5976 5977 // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415 5978 Modernizr.addTest('touchevents', function() { 5979 var bool; 5980 if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { 5981 bool = true; 5982 } else { 5983 // include the 'heartz' as a way to have a non matching MQ to help terminate the join 5984 // https://git.io/vznFH 5985 var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join(''); 5986 testStyles(query, function(node) { 5987 bool = node.offsetTop === 9; 5988 }); 5989 } 5990 return bool; 5991 }); 5992 5993 5994 // Run each test 5995 testRunner(); 5996 5997 // Remove the "no-js" class if it exists 5998 setClasses(classes); 5999 6000 delete ModernizrProto.addTest; 6001 delete ModernizrProto.addAsyncTest; 6002 6003 // Run the things that are supposed to run after the tests 6004 for (var i = 0; i < Modernizr._q.length; i++) { 6005 Modernizr._q[i](); 6006 } 6007 6008 // Leak Modernizr namespace 6009 window.Modernizr = Modernizr; 6010 6011 6012; 6013 6014})(window, document); 6015$(function() { 6016 ParallaxScroll.init(); 6017}); 6018 6019// Credit: https://github.com/alumbo/jquery.parallax-scroll 6020var ParallaxScroll = { 6021 /* PUBLIC VARIABLES */ 6022 showLogs: false, 6023 round: 1000, 6024 6025 /* PUBLIC FUNCTIONS */ 6026 init: function() { 6027 this._log("init"); 6028 if (this._inited) { 6029 this._log("Already Inited"); 6030 this._inited = true; 6031 return; 6032 } 6033 this._requestAnimationFrame = (function(){ 6034 return window.requestAnimationFrame || 6035 window.webkitRequestAnimationFrame || 6036 window.mozRequestAnimationFrame || 6037 window.oRequestAnimationFrame || 6038 window.msRequestAnimationFrame || 6039 function(/* function */ callback, /* DOMElement */ element){ 6040 window.setTimeout(callback, 1000 / 60); 6041 }; 6042 })(); 6043 this._onScroll(true); 6044 }, 6045 6046 /* PRIVATE VARIABLES */ 6047 _inited: false, 6048 _properties: ['x', 'y', 'z', 'rotateX', 'rotateY', 'rotateZ', 'scaleX', 'scaleY', 'scaleZ', 'scale'], 6049 _requestAnimationFrame:null, 6050 6051 /* PRIVATE FUNCTIONS */ 6052 _log: function(message) { 6053 if (this.showLogs) console.log("Parallax Scroll / " + message); 6054 }, 6055 _onScroll: function(noSmooth) { 6056 var scroll = $(document).scrollTop(); 6057 var windowHeight = $(window).height(); 6058 this._log("onScroll " + scroll); 6059 $("[data-parallax]").each($.proxy(function(index, el) { 6060 var $el = $(el); 6061 var properties = []; 6062 var applyProperties = false;
6063 var style = $el.data("style"); 6064 if (style == undefined) { 6065 style = $el.attr("style") || ""; 6066 $el.data("style", style); 6067 } 6068 var datas = [$el.data("parallax")]; 6069 var iData; 6070 for(iData = 2; ; iData++) { 6071 if($el.data("parallax"+iData)) { 6072 datas.push($el.data("parallax-"+iData)); 6073 } 6074 else { 6075 break; 6076 } 6077 } 6078 var datasLength = datas.length; 6079 for(iData = 0; iData < datasLength; iData ++) { 6080 var data = datas[iData]; 6081 var scrollFrom = data["from-scroll"]; 6082 if (scrollFrom == undefined) scrollFrom = Math.max(0, $(el).offset().top - windowHeight); 6083 scrollFrom = scrollFrom | 0; 6084 var scrollDistance = data["distance"]; 6085 var scrollTo = data["to-scroll"]; 6086 if (scrollDistance == undefined && scrollTo == undefined) scrollDistance = windowHeight; 6087 scrollDistance = Math.max(scrollDistance | 0, 1); 6088 var easing = data["easing"]; 6089 var easingReturn = data["easing-return"]; 6090 if (easing == undefined || !$.easing|| !$.easing[easing]) easing = null; 6091 if (easingReturn == undefined || !$.easing|| !$.easing[easingReturn]) easingReturn = easing; 6092 if (easing) { 6093 var totalTime = data["duration"]; 6094 if (totalTime == undefined) totalTime = scrollDistance; 6095 totalTime = Math.max(totalTime | 0, 1); 6096 var totalTimeReturn = data["duration-return"]; 6097 if (totalTimeReturn == undefined) totalTimeReturn = totalTime; 6098 scrollDistance = 1; 6099 var currentTime = $el.data("current-time"); 6100 if(currentTime == undefined) currentTime = 0; 6101 } 6102 if (scrollTo == undefined) scrollTo = scrollFrom + scrollDistance; 6103 scrollTo = scrollTo | 0; 6104 var smoothness = data["smoothness"]; 6105 if (smoothness == undefined) smoothness = 30; 6106 smoothness = smoothness | 0; 6107 if (noSmooth || smoothness == 0) smoothness = 1; 6108 smoothness = smoothness | 0; 6109 var scrollCurrent = scroll; 6110 scrollCurrent = Math.max(scrollCurrent, scrollFrom); 6111 scrollCurrent = Math.min(scrollCurrent, scrollTo); 6112 if(easing) { 6113 if($el.data("sens") == undefined) $el.data("sens", "back"); 6114 if(scrollCurrent>scrollFrom) { 6115 if($el.data("sens") == "back") { 6116 currentTime = 1; 6117 $el.data("sens", "go"); 6118 } 6119 else { 6120 currentTime++; 6121 } 6122 } 6123 if(scrollCurrent<scrollTo) { 6124 if($el.data("sens") == "go") { 6125 currentTime = 1; 6126 $el.data("sens", "back"); 6127 } 6128 else { 6129 currentTime++; 6130 } 6131 } 6132 if(noSmooth) currentTime = totalTime; 6133 $el.data("current-time", currentTime); 6134 } 6135 this._properties.map($.proxy(function(prop) { 6136 var defaultProp = 0; 6137 var to = data[prop]; 6138 if (to == undefined) return; 6139 if(prop=="scale" || prop=="scaleX" || prop=="scaleY" || prop=="scaleZ" ) { 6140 defaultProp = 1; 6141 } 6142 else { 6143 to = to | 0; 6144 } 6145 var prev = $el.data("_" + prop); 6146 if (prev == undefined) prev = defaultProp; 6147 var next = ((to-defaultProp) * ((scrollCurrent - scrollFrom) / (scrollTo - scrollFrom))) + defaultProp; 6148 var val = prev + (next - prev) / smoothness; 6149 if(easing && currentTime>0 && currentTime<=totalTime) { 6150 var from = defaultProp; 6151 if($el.data("sens") == "back") { 6152 from = to; 6153 to = -to; 6154 easing = easingReturn; 6155 totalTime = totalTimeReturn; 6156 } 6157 val = $.easing[easing](null, currentTime, from, to, totalTime); 6158 }
6159 val = Math.ceil(val * this.round) / this.round; 6160 if(val==prev&&next==to) val = to; 6161 if(!properties[prop]) properties[prop] = 0; 6162 properties[prop] += val; 6163 if (prev != properties[prop]) { 6164 $el.data("_" + prop, properties[prop]); 6165 applyProperties = true; 6166 } 6167 }, this)); 6168 } 6169 if (applyProperties) { 6170 if (properties["z"] != undefined) { 6171 var perspective = data["perspective"]; 6172 if (perspective == undefined) perspective = 800; 6173 var $parent = $el.parent(); 6174 if(!$parent.data("style")) $parent.data("style", $parent.attr("style") || ""); 6175 $parent.attr("style", "perspective:" + perspective + "px; -webkit-perspective:" + perspective + "px; "+ $parent.data("style")); 6176 } 6177 if(properties["scaleX"] == undefined) properties["scaleX"] = 1; 6178 if(properties["scaleY"] == undefined) properties["scaleY"] = 1; 6179 if(properties["scaleZ"] == undefined) properties["scaleZ"] = 1; 6180 if (properties["scale"] != undefined) { 6181 properties["scaleX"] *= properties["scale"]; 6182 properties["scaleY"] *= properties["scale"]; 6183 properties["scaleZ"] *= properties["scale"]; 6184 } 6185 var translate3d = "translate3d(" + (properties["x"] ? properties["x"] : 0) + "px, " + (properties["y"] ? properties["y"] : 0) + "px, " + (properties["z"] ? properties["z"] : 0) + "px)"; 6186 var rotate3d = "rotateX(" + (properties["rotateX"] ? properties["rotateX"] : 0) + "deg) rotateY(" + (properties["rotateY"] ? properties["rotateY"] : 0) + "deg) rotateZ(" + (properties["rotateZ"] ? properties["rotateZ"] : 0) + "deg)"; 6187 var scale3d = "scaleX(" + properties["scaleX"] + ") scaleY(" + properties["scaleY"] + ") scaleZ(" + properties["scaleZ"] + ")"; 6188 var cssTransform = translate3d + " " + rotate3d + " " + scale3d + ";"; 6189 this._log(cssTransform); 6190 $el.attr("style", "transform:" + cssTransform + " -webkit-transform:" + cssTransform + " " + style); 6191 } 6192 }, this)); 6193 if(window.requestAnimationFrame) { 6194 window.requestAnimationFrame($.proxy(this._onScroll, this, false)); 6195 } 6196 else { 6197 this._requestAnimationFrame($.proxy(this._onScroll, this, false)); 6198 } 6199 } 6200}; 6201; 6202(function($, window, undefined) { 6203 6204 'use strict'; 6205 6206 // global 6207 var Modernizr = window.Modernizr, 6208 $body = $('body'); 6209 6210 $.DLMenu = function(options, element) { 6211 this.$el = $(element); 6212 this._init(options); 6213 }; 6214 6215 $.DLMenu.defaults = { 6216 animationClasses: { 6217 classin: 'mk-vm-animate-in-' + mk_vertical_header_anim, 6218 classout: 'mk-vm-animate-out-' + mk_vertical_header_anim 6219 }, 6220 onLevelClick: function(el, name) { 6221 return false; 6222 }, 6223 onLinkClick: function(el, ev) { 6224 return false; 6225 } 6226 }; 6227 6228 $.DLMenu.prototype = { 6229 _init: function(options) { 6230 6231 this.options = $.extend(true, {}, $.DLMenu.defaults, options); 6232 this._config(); 6233 6234 var animEndEventNames = { 6235 'WebkitAnimation': 'webkitAnimationEnd', 6236 'OAnimation': 'oAnimationEnd', 6237 'msAnimation': 'MSAnimationEnd', 6238 'animation': 'animationend' 6239 }, 6240 transEndEventNames = { 6241 'WebkitTransition': 'webkitTransitionEnd', 6242 'MozTransition': 'transitionend', 6243 'OTransition': 'oTransitionEnd', 6244 'msTransition': 'MSTransitionEnd', 6245 'transition': 'transitionend' 6246 }; 6247 6248 this.animEndEventName = animEndEventNames[Modernizr.prefixed('animation')] + '.dlmenu'; 6249 this.transEndEventName = transEndEventNames[Modernizr.prefixed('transition')] + '.dlmenu'; 6250 6251 this.animEndEventNameUnsufixed = animEndEventNames[Modernizr.prefixed('animation')]; 6252 this.transEndEventNameUnsufixed = transEndEventNames[Modernizr.prefixed('transition')]; 6253 6254 this.supportAnimations = Modernizr.cssanimations; 6255 this.supportTransitions = Modernizr.csstransitions; 6256 6257 this._initEvents(); 6258 6259 }, 6260 _config: function() { 6261 this.open = false;
6262 this.$trigger = this.$el.children('.mk-vm-trigger'); 6263 this.$menu = this.$el.children('ul.mk-vm-menu'); 6264 this.$menuitems = this.$menu.find('li:not(.mk-vm-back)'); 6265 this.$back = this.$menu.find('li.mk-vm-back'); 6266 }, 6267 _initEvents: function() { 6268 6269 var self = this; 6270 6271 $('.mk-vm-menuwrapper a').on('transitionend', function(event) { 6272 event.stopPropagation(); 6273 }); 6274 6275 this.$menuitems.on('click.dlmenu', 'a', function(event) { 6276 6277 // Breaks smooth scroll in vertical menu 6278 // event.stopPropagation(); 6279 6280 var $item = $(event.delegateTarget), 6281 $submenu = $(event.currentTarget).siblings('ul.sub-menu'); 6282 6283 if ($submenu.length > 0) { 6284 var $flyin = $submenu.clone().css('opacity', 0).insertAfter(self.$menu); 6285 var onAnimationEndFn = function() { 6286 var $parent = $item.parents('.mk-vm-subviewopen:first'); 6287 self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classout).addClass('mk-vm-subview'); 6288 $item.addClass('mk-vm-subviewopen') 6289 $parent.removeClass('mk-vm-subviewopen').addClass('mk-vm-subview'); 6290 $flyin.remove(); 6291 6292 // Redraw for firefox issues 6293 var $txt = $item.find('.meni-item-text'); 6294 $txt.css('opacity', 0.99); 6295 setTimeout(function() { $txt.css('opacity', 1) }, 0); 6296 }; 6297 6298 setTimeout(function() { 6299 $flyin.addClass(self.options.animationClasses.classin); 6300 self.$menu.addClass(self.options.animationClasses.classout); 6301 if (self.supportAnimations) { 6302 self.$menu.on(self.animEndEventName, onAnimationEndFn); 6303 } else { 6304 onAnimationEndFn.call(); 6305 } 6306 6307 self.options.onLevelClick($item, $item.children('a:first').text()); 6308 }); 6309 6310 6311 // This caused firefox issue. Test properly if need to bring it back 6312 // if (self.open) { 6313 // self._closeMenu(); 6314 // } else { 6315 // self._openMenu(); 6316 // } 6317 6318 return false; 6319 6320 } else { 6321 self.options.onLinkClick($item, event); 6322 } 6323 6324 }); 6325 6326 6327 // this.$trigger.on('click.dlmenu', function() { 6328 6329 // if (self.open) { 6330 // self._closeMenu(); 6331 // } else { 6332 // // if( ! $(this).hasClass('menu-item-has-children') ) return false; 6333 // self._openMenu(); 6334 // } 6335 // return false; 6336 6337 // }); 6338 6339 this.$back.on('click.dlmenu', function(event) { 6340 6341 var $this = $(this), 6342 $submenu = $this.parents('ul.sub-menu:first'), 6343 $item = $submenu.parent(), 6344 6345 $flyin = $submenu.clone().insertAfter(self.$menu); 6346 6347 var onAnimationEndFn = function() { 6348 self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classin); 6349 $flyin.remove(); 6350 }; 6351 6352 setTimeout(function() { 6353 $flyin.addClass(self.options.animationClasses.classout); 6354 self.$menu.addClass(self.options.animationClasses.classin); 6355 if (self.supportAnimations) { 6356 self.$menu.on(self.animEndEventName, onAnimationEndFn); 6357 } else { 6358 onAnimationEndFn.call(); 6359 } 6360 6361 $item.removeClass('mk-vm-subviewopen'); 6362 6363 var $subview = $this.parents('.mk-vm-subview:first'); 6364 if ($subview.is('li')) { 6365 $subview.addClass('mk-vm-subviewopen'); 6366 } 6367 $subview.removeClass('mk-vm-subview'); 6368 }); 6369 6370 return false; 6371 6372 }); 6373 6374 }, 6375 closeMenu: function() { 6376 if (this.open) { 6377 this._closeMenu(); 6378 } 6379 }, 6380 _closeMenu: function() { 6381 var self = this, 6382 onTransitionEndFn = function() { 6383 self.$menu.off(self.transEndEventName); 6384 self._resetMenu(); 6385 }; 6386 6387 this.$menu.removeClass('mk-vm-menuopen'); 6388 this.$menu.addClass('mk-vm-menu-toggle'); 6389 this.$trigger.removeClass('mk-vm-active'); 6390 6391 if (this.supportTransitions) { 6392 this.$menu.on(this.transEndEventName, onTransitionEndFn); 6393 } else { 6394 onTransitionEndFn.call(); 6395 } 6396 6397 this.open = false; 6398 }, 6399 openMenu: function() { 6400 if (!this.open) { 6401 this._openMenu(); 6402 } 6403 }, 6404 _openMenu: function() { 6405 var self = this; 6406 $body.off('click').on('click.dlmenu', function() { 6407 self._closeMenu(); 6408 }); 6409 this.$menu.addClass('mk-vm-menuopen mk-vm-menu-toggle').on(this.transEndEventName, function() { 6410 $(this).removeClass('mk-vm-menu-toggle'); 6411 }); 6412 this.$trigger.addClass('mk-vm-active'); 6413 this.open = true; 6414 }, 6415 _resetMenu: function() { 6416 this.$menu.removeClass('mk-vm-subview'); 6417 this.$menuitems.removeClass('mk-vm-subview mk-vm-subviewopen'); 6418 } 6419 }; 6420 6421 var logError = function(message) { 6422 if (window.console) { 6423 window.console.error(message); 6424 } 6425 }; 6426 6427 $.fn.dlmenu = function(options) { 6428 if (typeof options === 'string') { 6429 var args = Array.prototype.slice.call(arguments, 1); 6430 this.each(function() { 6431 var instance = $.data(this, 'dlmenu'); 6432 if (!instance) { 6433 logError("cannot call methods on dlmenu prior to initialization; " + 6434 "attempted to call method '" + options + "'"); 6435 return; 6436 } 6437 if (!$.isFunction(instance[options]) || options.charAt(0) === "_") { 6438 logError("no such method '" + options + "' for dlmenu instance"); 6439 return; 6440 } 6441 instance[options].apply(instance, args); 6442 }); 6443 } else { 6444 this.each(function() { 6445 var instance = $.data(this, 'dlmenu'); 6446 if (instance) { 6447 instance._init(); 6448 } else { 6449 instance = $.data(this, 'dlmenu', new $.DLMenu(options, this)); 6450 } 6451 }); 6452 } 6453 return this; 6454 }; 6455 6456})(jQuery, window); 6457( function($) { 6458 'use strict'; 6459 6460 /* 6461 * Define popup / hover states manually to prevent click for IE on touchdevices 6462 */ 6463 6464 $('.mk-main-navigation .menu-item-has-children').children('a').attr('aria-haspopup', 'true'); 6465 $('.animated-column-item').attr('aria-haspopup', 'true'); 6466 6467})( jQuery ); 6468(function($) { 6469 'use strict'; 6470 6471 var Accordion = function(el) { 6472 // Private 6473 var that = this, 6474 $el = $(el), 6475 initial = $el.data('initialindex'), 6476 timeout; 6477 6478 // Public 6479 this.$el = $el; 6480 this.$single = $('.' + this.dom.single, $el); 6481 this.isExpendable = ($el.data('style') === 'toggle-action'); 6482 6483 // Init 6484 this.bindClicks(); 6485 // Reveal initial tab on load event (wait for possible images inside) 6486 $(window).on('load', function() {
6487 if( initial !== -1 ) that.show(that.$single.eq(initial)) 6488 }); 6489 $(window).on('resize', function() { 6490 clearTimeout(timeout); 6491 timeout = setTimeout(that.bindClicks.bind(that), 500); 6492 }); 6493 } 6494 6495 Accordion.prototype.dom = { 6496 // only class names please! 6497 single : 'mk-accordion-single', 6498 tab : 'mk-accordion-tab', 6499 pane : 'mk-accordion-pane', 6500 current : 'current', 6501 mobileToggle : 'mobile-false', 6502 mobileBreakPoint : 767 6503 } 6504 6505 Accordion.prototype.bindClicks = function() { 6506 // Prevent multiple events binding 6507 this.$single.off('click', '.' + this.dom.tab); 6508 6509 if( !(window.matchMedia('(max-width: ' + this.dom.mobileBreakPoint +'px)').matches 6510 && this.$el.hasClass(this.dom.mobileToggle)) ) { 6511 6512 this.$single.on('click', '.' + this.dom.tab, this.handleEvent.bind(this)); 6513 // When website is loaded in mobile view and resized to desktop 'current' will 6514 // inherit display: none from css. Repair it by calling show() on this element 6515 var $current = $('.' + this.dom.current, this.$el); 6516 if($('.' + this.dom.pane, $current).css('display') === 'none') this.show($current); 6517 } 6518 } 6519 6520 Accordion.prototype.handleEvent = function(e) { 6521 e.preventDefault(); 6522 e.stopPropagation(); 6523 6524 var $single = $(e.delegateTarget); 6525 6526 if(!$single.hasClass(this.dom.current)) { 6527 this.show($single); 6528 } 6529 else { 6530 if(this.isExpendable) this.hide($single); 6531 } 6532 } 6533 6534 Accordion.prototype.hide = function($single) { 6535 $single.removeClass(this.dom.current);
6536 $('.' + this.dom.pane, $single).slideUp(); 6537 } 6538 6539 Accordion.prototype.show = function($single) { 6540 // hide currently opened tab 6541 if(!this.isExpendable) { 6542 var that = this; 6543 this.hide($('.' + this.dom.current, that.$el)); 6544 } 6545 6546 $single.addClass(this.dom.current); 6547 $('.' + this.dom.pane, $single).slideDown(); 6548 } 6549 6550 6551 6552 // /////////////////////////////////////// 6553 // 6554 // Apply to: 6555 // 6556 // /////////////////////////////////////// 6557 6558 function init() { 6559 $('.mk-accordion').each(function() { 6560 new Accordion(this); 6561 }); 6562 } 6563 6564 init(); 6565 $(window).on('vc_reload', init); 6566 6567})(jQuery); 6568 6569(function($) { 6570 6571 'use strict'; 6572 6573 var SkillDiagram = function( el ) { 6574 this.el = el; 6575 } 6576 6577 SkillDiagram.prototype = { 6578 init : function() { 6579 this.cacheElements(); 6580 this.createDiagram(); 6581 this.$skills.each( this.createSkill.bind( this ) ); 6582 }, 6583 6584 cacheElements : function() { 6585 this.$el = $( this.el ); 6586 this.$skills = this.$el.find( '.mk-meter-arch'); 6587 this.config = this.$el.data(); 6588 this.config.radius = this.config.dimension / 2; 6589 }, 6590 6591 random : function( l, u ) { 6592 return Math.floor( ( Math.random() * ( u - l + 1 ) ) + l ); 6593 }, 6594 6595 createDiagram : function() { 6596 var self = this; 6597 $(this.el).find('svg').remove(); 6598 6599 this.diagram = Raphael( this.el, this.config.dimension, this.config.dimension ); 6600 6601 // Make svg scalable in different screen sizes 6602 this.diagram.setViewBox(0,0,this.config.dimension,this.config.dimension,true); 6603 this.diagram.setSize('90%', '90%'); 6604 6605 this.diagram.circle( this.config.radius, this.config.radius, 80 ).attr({ 6606 stroke: 'none', 6607 fill: this.config.circleColor 6608 }); 6609 6610 // Export title 6611 this.title = this.diagram.text( this.config.radius, this.config.radius, this.config.defaultText ).attr({ 6612 font: "22px helvetica", 6613 fill: this.config.defaultTextColor 6614 }).toFront(); 6615 6616 this.diagram.customAttributes.arc = function(value, color, rad){ 6617 var v = 3.6 * value, 6618 alpha = v == 360 ? 359.99 : v, 6619 r = self.random( 91, 240 ), 6620 a = (r - alpha) * Math.PI/180, 6621 b = r * Math.PI/180, 6622 sx = self.config.radius + rad * Math.cos(b), 6623 sy = self.config.radius - rad * Math.sin(b), 6624 x = self.config.radius + rad * Math.cos(a), 6625 y = self.config.radius - rad * Math.sin(a), 6626 path = [['M', sx, sy], ['A', rad, rad, 0, +(alpha > 180), 1, x, y]]; 6627 6628 return { 6629 path: path, 6630 stroke: color 6631 } 6632 } 6633 }, 6634 6635 createSkill : function( id, el ) { 6636 var self = this, 6637 $this = $( el ), 6638 config = $this.data(), 6639 radMin = 72, 6640 radVal = 27, 6641 newRad = radMin + ( radVal * (id + 1) ); 6642 6643 var $path = this.diagram.path().attr({ 6644 'stroke-width': 28, 6645 arc: [config.percent, config.color, newRad] 6646 }); 6647 6648 $path.mouseover( function() { 6649 self.showSkill( this, config.name, config.percent ); 6650 }).mouseout( function() { 6651 self.hideSkill( this ) 6652 }); 6653 }, 6654 6655 showSkill : function( self, name, percent ) { 6656 var $this = self, 6657 time = 250; 6658 6659 //solves IE problem 6660 if(Raphael.type != 'VML') $this.toFront(); 6661 6662 $this.animate({ 6663 'stroke-width': 50, 6664 'opacity': 0.9, 6665 }, 800, 'elastic' ); 6666 6667 this.title.stop() 6668 .animate({ opacity: 0 }, time, '>', function(){ 6669 this.attr({ text: name + '\n' + percent + '%' }).animate({ opacity: 1 }, time, '<'); 6670 }).toFront(); 6671 }, 6672 6673 hideSkill : function( self ) { 6674 var $this = self, 6675 self = this, 6676 time = 250; 6677 6678 $this.stop().animate({ 6679 'stroke-width': 28, 6680 opacity: 1 6681 }, time * 4, 'elastic' ); 6682 6683 self.title.stop() 6684 .animate({ opacity: 0 }, time, '>', function(){ 6685 self.title.attr({ text: self.config.defaultText }) 6686 .animate({ opacity: 1 }, time, '<'); 6687 }); 6688 } 6689 } 6690
6691 var init = function init() { 6692 if( typeof Raphael === 'undefined' ) return; 6693 $( '.mk-skill-diagram' ).each( function() { 6694 var diagram = new SkillDiagram( this ); 6695 diagram.init(); 6696 }); 6697 } 6698 6699 init(); 6700 $(window).on('vc_reload', init); 6701 6702})(jQuery); 6703/* 6704 * Tab delegation 6705 * Action for modules when we don't have access to chidren DOM on processing templates 6706 * yet we want ass option of opening link in new tab. 6707 * Helpful for use with external widgets like flickr 6708 */ 6709 6710(function($) { 6711 6712 'use strict'; 6713 6714 $( '[data-js="tab-delegation"]' ).each( tabDelegation ); 6715 6716 function tabDelegation() { 6717 var $this = $( this ), 6718 data = $this.data(); 6719 6720 // Create delegation on parent element to affect async loaded children 6721 if( data.tab ) $this.on( 'click', 'a', openInTab ); 6722 } 6723 6724 function openInTab( e ) { 6725 e.preventDefault(); 6726 6727 var $this = $( this ), 6728 url = $this.attr( 'href' ); 6729 6730 window.open( url, '_blank' ); 6731 } 6732 6733})(jQuery); 6734(function($) { 6735 'use strict'; 6736 6737 var init = function init() { 6738 var Toggle = function(el) { 6739 var that = this, 6740 $el = $(el); 6741 6742 this.$el = $el; 6743 $el.on('click', function() { 6744 $el.hasClass('active-toggle') ? that.close() : that.open() 6745 }); 6746 }; 6747 6748 Toggle.prototype.dom = { 6749 pane : 'mk-toggle-pane', 6750 active : 'active-toggle' 6751 }; 6752 6753 Toggle.prototype.open = function() { 6754 var $this = this.$el; 6755 $this.addClass(this.dom.active); 6756 $this.siblings('.' + this.dom.pane).slideDown(200); 6757 }; 6758 6759 Toggle.prototype.close = function() { 6760 var $this = this.$el; 6761 $this.removeClass(this.dom.active); 6762 $this.siblings('.' + this.dom.pane).slideUp(200); 6763 }; 6764 6765 // Apply to. 6766 var $toggle = $('.mk-toggle-title'); 6767 6768 if(!$toggle.length) return; 6769 6770 $toggle.each(function() { 6771 new Toggle(this); 6772 }); 6773 } 6774 $(window).on('load vc_reload', init); 6775 6776})(jQuery); 6777 6778////////////////////////////////////////////////////////////////////////// 6779// 6780// Init all scripts 6781// 6782////////////////////////////////////////////////////////////////////////// 6783 6784// This is bad but we don't have other access to this scope. 6785// Ajax Portfolio is defined as plugin and on success needs these to be reinited 6786// We'll refactor all of this. 6787window.ajaxInit = function() { 6788 mk_lightbox_init(); 6789 mk_click_events(); 6790 mk_social_share_global(); 6791 // mk_social_share(); 6792 mk_gallery(); 6793 loop_audio_init(); 6794}; 6795 6796window.ajaxDelayedInit = function() { 6797 mk_flexslider_init(); 6798 // mk_portfolio_ajax(); 6799}; 6800 6801$(document).ready(function() { 6802 mk_lightbox_init(); 6803 mk_login_form(); 6804 mk_backgrounds_parallax(); 6805 mk_flexslider_init(); 6806 mk_event_countdown(); 6807 mk_skill_meter(); 6808 mk_milestone(); 6809 mk_ajax_search(); 6810 mk_hover_events(); 6811 mk_portfolio_ajax(); 6812 product_loop_add_cart(); 6813 // mk_social_share(); 6814 mk_portfolio_widget(); 6815 mk_contact_form(); 6816 mk_blog_carousel(); 6817 mk_header_searchform(); 6818 mk_click_events(); 6819 mk_text_typer(); 6820 mk_tab_slider_func(); 6821 6822 $(window).on('load', function() { 6823 mk_unfold_footer(); 6824 mk_tabs(); 6825 mk_accordion_toggles_tooltip(); 6826 mk_gallery(); 6827 mk_theatre_responsive_calculator(); 6828 mk_tabs_responsive(); 6829 mk_start_tour_resize(); 6830 mk_header_social_resize(); 6831 mk_page_section_social_video_bg(); 6832 loop_audio_init(); 6833 mk_one_page_scroller(); 6834 mkPositionSidebar(); 6835 6836 setTimeout(function() { 6837 /* 6838 Somehow the values are not correctly updated for the screens 6839 and we need to put setTimeout to fix the issue 6840 */ 6841 mk_mobile_tablet_responsive_calculator(); 6842 }, 300); 6843 6844 console.log("ready for rock"); 6845 }); 6846 6847 6848 var onDebouncedResize = function() { 6849 mk_theatre_responsive_calculator(); 6850 mk_mobile_tablet_responsive_calculator(); 6851 mk_tabs_responsive(); 6852 mk_accordion_toggles_tooltip(); 6853 mk_start_tour_resize(); 6854 mk_header_social_resize(); 6855 6856 setTimeout(function() { 6857 mk_unfold_footer(); 6858 }, 300); 6859 }; 6860 6861 var debounceResize = null; 6862 $(window).on("resize", function() { 6863 if( debounceResize !== null ) { clearTimeout( debounceResize ); } 6864 debounceResize = setTimeout( onDebouncedResize, 300 ); 6865 }); 6866 6867 var onDebouncedScroll = function() { 6868 mk_skill_meter(); 6869 //TODO: Ask to Bart how we can call javascript component 6870 //mk_charts(); 6871 mk_milestone(); 6872 }; 6873 6874 var debounceScroll = null; 6875 $(window).on("scroll", function() { 6876 if( debounceScroll !== null ) { clearTimeout( debounceScroll ); } 6877 debounceScroll = setTimeout( onDebouncedScroll, 100 ); 6878 }); 6879 6880 if (MK.utils.isMobile()) { 6881 $('body').addClass('no-transform'); 6882 } 6883 6884}); 6885 6886/* VC frontend editor */ 6887/* -------------------------------------------------------------------- */ 6888$(window).on("vc_reload",function () { 6889 mk_flexslider_init(); 6890 loop_audio_init(); 6891 mk_tab_slider_func();
6892 mk_event_countdown(); 6893 videoLoadState(); 6894 mk_page_section_social_video_bg(); 6895 mk_hover_events(); 6896 6897 setTimeout(function() { 6898 mkPositionSidebar(); 6899 }, 200); 6900}); 6901 6902// Replace this if new event for remove found. 6903$( document ).on( 'click', '.vc_control-btn-delete', function() { 6904 $( window ).trigger( 'vc_reload' ); 6905} ); 6906 6907$( document ).on( 'sortupdate', '.ui-sortable', function() { 6908 $( window ).trigger( 'vc_reload' ); 6909} ); 6910 6911/* Typer */ 6912/* -------------------------------------------------------------------- */ 6913function mk_text_typer() { 6914 6915 "use strict"; 6916 6917 $('[data-typer-targets]').each(function() { 6918 var that = this; 6919 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.typed.js' ], function() { 6920 var $this = $(that), 6921 $first_string = [$this.text()], 6922 $rest_strings = $this.attr('data-typer-targets').split(','), 6923 $strings = $first_string.concat($rest_strings); 6924 6925 $this.text(''); 6926 6927 $this.typed({ 6928 strings: $strings, 6929 typeSpeed: 30, // typing speed 6930 backDelay: 1200, // pause before backspacing 6931 loop: true, // loop on or off (true or false) 6932 loopCount: false, // number of loops, false = infinite 6933 }); 6934 }); 6935 }); 6936} 6937 6938 6939 6940/* Tab Slider */ 6941/* -------------------------------------------------------------------- */ 6942 6943function mk_tab_slider_func() { 6944 6945 "use strict"; 6946 6947 $('.mk-tab-slider').each(function() { 6948 var that = this; 6949 6950 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.swiper.js' ], function() { 6951 var $this = $(that), 6952 id = $this.data('id'), 6953 $autoplayTime = $this.data('autoplay'), 6954 $content = $('.mk-slider-content'); 6955 6956 var mk_tab_slider = $this.swiper({ 6957 wrapperClass: 'mk-tab-slider-wrapper', 6958 slideClass: 'mk-tab-slider-item', 6959 calculateHeight: true, 6960 speed: 500, 6961 autoplay: isTest ? false : $autoplayTime, 6962 onSlideChangeStart: function() { 6963 $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active') 6964 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").eq(mk_tab_slider.activeIndex).addClass('active') 6965 } 6966 }); 6967 6968 // Simple repaint for firefox issue (can't handle 100% height after plugin init) 6969 function repaintFirefox() { 6970 $content.css('display','block'); 6971 setTimeout(function() { 6972 mk_tab_slider.reInit(); 6973 $content.css('display','table'); 6974 },100); 6975 } 6976 6977 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").first().addClass('active'); 6978 6979 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").on('touchstart mousedown', function(e) { 6980 e.preventDefault() 6981 $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active') 6982 $(this).addClass('active') 6983 mk_tab_slider.swipeTo($(this).index()) 6984 }); 6985 6986 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").click(function(e) { 6987 e.preventDefault(); 6988 }); 6989 6990 repaintFirefox(); 6991 $(window).on('resize', repaintFirefox); 6992 }); 6993 6994 }); 6995 6996} 6997 6998 6999 7000/* Edge One Pager */ 7001/* -------------------------------------------------------------------- */ 7002function mk_one_page_scroller() { 7003 7004 "use strict"; 7005 7006 $('.mk-edge-one-pager').each(function() { 7007 var self = this; 7008 7009 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.fullpage.js' ], function() { 7010 7011 var $this = $(self), 7012 anchorArr = []; 7013 7014 $this.find('.section').each(function() { 7015 anchorArr.push($(this).attr('data-title')); 7016 }); 7017 7018 var scrollable = true; 7019 $this.find('.section').each(function() { 7020 var $section = $(this), 7021 $content = $section.find('.edge-slide-content'), 7022 sectionHeight = $section.height(),
7023 contentHeight = $content.innerHeight(); 7024 7025 if((contentHeight + 30) > $(window).height()) { 7026 scrollable = false; 7027 } 7028 }); 7029 7030 if(!scrollable){ 7031 $this.find('.section').each(function() { 7032 var $section = $(this); 7033 $section.addClass('active').css({ 7034 'padding-bottom': '50px' 7035 }); 7036 }); 7037 } 7038 7039 if(scrollable) { 7040 $this.fullpage({ 7041 verticalCentered: false, 7042 resize: true, 7043 slidesColor: ['#ccc', '#fff'], 7044 anchors: anchorArr, 7045 scrollingSpeed: 600, 7046 easing: 'easeInQuart', 7047 menu: false, 7048 navigation: true, 7049 navigationPosition: 'right', 7050 navigationTooltips: false, 7051 slidesNavigation: true, 7052 slidesNavPosition: 'bottom', 7053 loopBottom: false, 7054 loopTop: false, 7055 loopHorizontal: true, 7056 autoScrolling: true, 7057 scrollOverflow: false, 7058 css3: true, 7059 paddingTop: 0, 7060 paddingBottom: 0, 7061 normalScrollElements: '.mk-header, .mk-responsive-wrap', 7062 normalScrollElementTouchThreshold: 5, 7063 keyboardScrolling: true, 7064 touchSensitivity: 15, 7065 continuousVertical: false, 7066 animateAnchor: true, 7067 7068 onLeave: function(index, nextIndex, direction) { 7069 var currentSkin = $this.find('.one-pager-slide').eq(nextIndex - 1).attr('data-header-skin'); 7070 MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin ); 7071 $('#fullPage-nav').removeClass('light-skin dark-skin').addClass(currentSkin + '-skin'); 7072 7073 }, 7074 afterRender: function() { 7075 7076 var $nav = $('#fullPage-nav'); 7077 7078 setTimeout(function() { 7079 var currentSkin = $this.find('.one-pager-slide').eq(0).attr('data-header-skin'); 7080 MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin ); 7081 if($nav.length) $nav.removeClass('light-skin dark-skin').addClass(currentSkin + '-skin'); 7082 }, 300); 7083 7084 var $slide = $this.find('.section'), 7085 headerHeight = MK.val.offsetHeaderHeight(0), 7086 windowHeight = $(window).height(); 7087 7088 $slide.height(windowHeight - headerHeight); 7089 7090 if($nav.length) { 7091 $nav.css({ 7092 'top': 'calc(50% + ' + (headerHeight/2) + 'px)', 7093 'marginTop': 0 7094 }); 7095 7096 var style = $this.attr('data-pagination'); 7097 $nav.addClass('pagination-' + style); 7098 } 7099 7100 setTimeout(mk_one_pager_resposnive, 1000); 7101 }, 7102 afterResize: function() { 7103 var $slide = $this.find('.section'), 7104 headerHeight = MK.val.offsetHeaderHeight(0), 7105 windowHeight = $(window).height(); 7106 7107 $slide.height(windowHeight - headerHeight); 7108 7109 $('#fullPage-nav').css({ 7110 'top': 'calc(50% + ' + (headerHeight/2) + 'px)', 7111 'marginTop': 0 7112 }); 7113 7114 setTimeout(mk_one_pager_resposnive, 1000); 7115 console.log('Reposition pager content.'); 7116 }, 7117 }); 7118 } 7119 7120 // Linking to slides available for desktop and mobile scenarios 7121 function swipeTo(href, e) { 7122 href = '_' + href; // ensure a char before # 7123 if (!~href.indexOf('#')) return; 7124 var section = href.split('#')[1]; 7125 if (~anchorArr.indexOf(section)) { 7126 if (typeof e !== 'undefined') e.preventDefault(); 7127 if (scrollable) $.fn.fullpage.moveTo(section); 7128 else MK.utils.scrollToAnchor('[data-title="'+section+'"]'); 7129 } 7130 } 7131 7132 // onload 7133 var loc = window.location; 7134 if(loc.hash) swipeTo(loc.hash); 7135 7136 $(document).on('click', 'a', function(e) { 7137 var $link = $(e.currentTarget); 7138 swipeTo($link.attr('href'), e); 7139 }); 7140 }); 7141 }); 7142 7143 7144 7145} 7146 7147 7148function mk_one_pager_resposnive() { 7149 "use strict"; 7150 7151 $('.mk-edge-one-pager').each(function() { 7152 var $pager = $(this), 7153 headerHeight = MK.val.offsetHeaderHeight(0), 7154 windowHeight = $(window).height() - headerHeight; 7155 7156 $pager.find('.one-pager-slide').each(function() { 7157 var $slide = $(this), 7158 $content = $slide.find('.edge-slide-content'); 7159 7160 if ($slide.hasClass('left_center') || $slide.hasClass('center_center') || $slide.hasClass('right_center')) { 7161 var contentHeight = $content.height(), 7162 distanceFromTop = (windowHeight - contentHeight) / 2; 7163 7164 distanceFromTop = (distanceFromTop < 50) ? 50 + headerHeight : distanceFromTop; 7165 7166 $content.css('marginTop', distanceFromTop); 7167 } 7168 7169 if ($slide.hasClass('left_bottom') || $slide.hasClass('center_bottom') || $slide.hasClass('right_bottom')) { 7170 var distanceFromTop = windowHeight - $content.height() - 90; 7171 $content.css('marginTop', (distanceFromTop)); 7172 } 7173 }); 7174 7175 /** 7176 * Fix AM-2853 7177 * 7178 * @since 6.0.3 7179 * 7180 * At the init of Edge One Pager (EOP), EOP will render all image 7181 * background of each sections from top to bottom. In this case, 7182 * the page height will be more than screen height and the scroll 7183 * bar will appear. At the same time, the full width row will set 7184 * the container width into 100%. But, after all Slides are set up, 7185 * EOP height will be 100% of the screen height, so the scroll bar 7186 * will be disappeared. It's caused spacing issues on the left and 7187 * right side of the EOP container. To fix this, the row width 7188 * should be resized and row position should be readjusted. 7189 */ 7190 var $row = $pager.parents( '.vc_row.vc_row-fluid.mk-fullwidth-true' ); 7191 7192 // Run only if the Edge One Pager is wrapped inside full width row. 7193 if ( $row.length > 0 ) { 7194 // Set the wrapper and row width. 7195 var $wrapper = $( '.mk-main-wrapper-holder' ); 7196 var $grid = $row.children( '.mk-grid' ); 7197 var rowWidth = $row.width(); // Original width.
7198 var wrapperWidth = $wrapper.width(); // The new width. 7199 7200 // Run only if original width is smaller than the new width. 7201 if ( rowWidth >= wrapperWidth || $grid.length > 0 ) { 7202 return; 7203 } 7204 7205 // Get the content left offset. 7206 var $content = $wrapper.find( '.theme-content' ); 7207 var oriPos = $content.position(); 7208 var oriPadLeft = $content.css( 'padding-left' ); 7209 var oriLeft = parseInt( oriPos.left ) + parseInt( oriPadLeft ); 7210 7211 // Ensure the new width and left position is more than 0. 7212 if ( wrapperWidth <= 0 || oriLeft <= 0 ) { 7213 return; 7214 } 7215 7216 // Resize the width and left position of row full width. 7217 $row.css({ 7218 'width': wrapperWidth, 7219 'left': oriLeft * -1, 7220 }); 7221 } 7222 }); 7223} 7224 7225/* Image Gallery */ 7226/* -------------------------------------------------------------------- */ 7227 7228function mk_gallery() { 7229 7230 "use strict"; 7231 7232 $('.mk-gallery .mk-gallery-item.hover-overlay_layer .item-holder').each(function() { 7233 var itemHolder = $(this), 7234 galleryDesc = itemHolder.find('.gallery-desc'); 7235 7236 function updatePosition() { 7237 var parentHeight = itemHolder.outerHeight(), 7238 contentHeight = galleryDesc.innerHeight(); 7239 7240 var paddingVal = (parentHeight - contentHeight) / 2; 7241 galleryDesc.css({ 7242 'top': paddingVal, 7243 // 'padding-bottom': paddingVal 7244 }); 7245 7246 // console.log(parentHeight); 7247 // console.log(contentHeight); 7248 7249 7250 } 7251 updatePosition(); 7252 7253 $(window).on('resize', function() { 7254 setTimeout(function() { 7255 updatePosition(); 7256 }, 1000); 7257 }); 7258 }); 7259 // Execute hover state for mk gallery item 7260 if ($(window).width() <= 1024) { 7261 $('.mk-gallery .mk-gallery-item').on('click', function (e) { 7262 var clicks = $(this).data('clicks'); 7263 if (clicks) { 7264 // First click 7265 $(this).toggleClass('hover-state'); 7266 } else { 7267 // Second click 7268 $(this).toggleClass('hover-state'); 7269 } 7270 $(this).data("clicks", !clicks); 7271 }); 7272 } 7273} 7274 7275/* Theatre Slider Responsive Calculator */ 7276/* -------------------------------------------------------------------- */ 7277 7278function mk_theatre_responsive_calculator() { 7279 var $laptopContainer = $(".laptop-theatre-slider"); 7280 var $computerContainer = $(".desktop-theatre-slider"); 7281 $laptopContainer.each(function() { 7282 var $this = $(this), 7283 $window = $(window), 7284 $windowWidth = $window.outerWidth(), 7285 $windowHeight = $window.outerHeight(), 7286 $width = $this.outerWidth(), 7287 $height = $this.outerHeight(), 7288 $paddingTop = 38, 7289 $paddingRight = 143, 7290 $paddingBottom = 78, 7291 $paddingLeft = 143; 7292 7293 var $player = $this.find('.player-container'); 7294 7295 if ($windowWidth > $width) { 7296 $player.css({ 7297 'padding-left': parseInt(($width * $paddingLeft) / 1200), 7298 'padding-right': parseInt(($width * $paddingRight) / 1200), 7299 'padding-top': parseInt(($height * $paddingTop) / 690), 7300 'padding-bottom': parseInt(($height * $paddingBottom) / 690), 7301 }); 7302 } 7303 7304 }); 7305 7306 $computerContainer.each(function() { 7307 var $this = $(this), 7308 $window = $(window), 7309 $windowWidth = $window.outerWidth(), 7310 $windowHeight = $window.outerHeight(), 7311 $width = $this.outerWidth(), 7312 $height = $this.outerHeight(), 7313 $paddingTop = 60, 7314 $paddingRight = 52, 7315 $paddingBottom = 290, 7316 $paddingLeft = 49; 7317 7318 var $player = $this.find('.player-container'); 7319 7320 if ($windowWidth > $width) { 7321 $player.css({ 7322 'padding-left': parseInt(($width * $paddingLeft) / 1200), 7323 'padding-right': parseInt(($width * $paddingRight) / 1200), 7324 'padding-top': parseInt(($height * $paddingTop) / 969), 7325 'padding-bottom': parseInt(($height * $paddingBottom) / 969), 7326 }); 7327 } 7328 7329 }); 7330 7331} 7332 7333/* Mobile and Tablet Slideshow Responsive Calculator */ 7334/* -------------------------------------------------------------------- */ 7335function mk_mobile_tablet_responsive_calculator() { 7336 var $laptopSlideshow = $(".mk-laptop-slideshow-shortcode"); 7337 var $lcdSlideshow = $(".mk-lcd-slideshow"); 7338 7339 if ($.exists(".mk-laptop-slideshow-shortcode")) { 7340 $laptopSlideshow.each(function() { 7341 var $this = $(this), 7342 $window = $(window), 7343 $windowWidth = $window.outerWidth(), 7344 $windowHeight = $window.outerHeight(), 7345 $width = $this.outerWidth(), 7346 $height = $this.outerHeight(), 7347 $paddingTop = 28, 7348 $paddingRight = 102, 7349 $paddingBottom = 52, 7350 $paddingLeft = 102; 7351 7352 var $player = $this.find(".slideshow-container"); 7353 7354 $player.css({ 7355 "padding-left": parseInt(($width * $paddingLeft) / 836), 7356 "padding-right": parseInt(($width * $paddingRight) / 836), 7357 "padding-top": parseInt(($height * $paddingTop) / 481), 7358 "padding-bottom": parseInt(($height * $paddingBottom) / 481), 7359 }); 7360 7361 }); 7362 } 7363 7364 if ($.exists(".mk-lcd-slideshow")) {
7365 $lcdSlideshow.each(function() { 7366 var $this = $(this), 7367 $window = $(window), 7368 $windowWidth = $window.outerWidth(), 7369 $windowHeight = $window.outerHeight(), 7370 $width = $this.outerWidth(), 7371 $height = $this.outerHeight(), 7372 $paddingTop = 35, 7373 $paddingRight = 39, 7374 $paddingBottom = 213, 7375 $paddingLeft = 36; 7376 7377 var $player = $this.find(".slideshow-container"); 7378 $player.css({ 7379 "padding-left": parseInt(($width * $paddingLeft) / 886), 7380 "padding-right": parseInt(($width * $paddingRight) / 886), 7381 "padding-top": parseInt(($height * $paddingTop) / 713), 7382 "padding-bottom": parseInt(($height * $paddingBottom) / 713), 7383 }); 7384 }); 7385 } 7386} 7387 7388 7389/* Start a tour resize function */ 7390/* -------------------------------------------------------------------- */ 7391function mk_start_tour_resize() { 7392 7393 $('.mk-header-start-tour').each(function() { 7394 7395 var $windowWidth = $(document).width(), 7396 $this = $(this), 7397 $linkWidth = $this.width() + 15, 7398 $padding = ($windowWidth - mk_responsive_nav_width) / 2; 7399 7400 7401 7402 function updateStartTour(){ 7403 if($windowWidth < mk_responsive_nav_width){ 7404 $this.removeClass('hidden'); 7405 $this.addClass('show'); 7406 }else{ 7407 if($padding < $linkWidth){ 7408 $this.removeClass('show'); 7409 $this.addClass('hidden'); 7410 }else{ 7411 $this.removeClass('hidden'); 7412 $this.addClass('show'); 7413 } 7414 } 7415 } 7416 7417 setTimeout(function() { 7418 updateStartTour(); 7419 }, 300); 7420 }); 7421} 7422 7423/* Header social resize function */ 7424/* -------------------------------------------------------------------- */ 7425function mk_header_social_resize() { 7426 7427 $('.mk-header-social.header-section').each(function() { 7428 7429 var $windowWidth = $(document).width(), 7430 $this = $(this), 7431 $linkWidth = $this.width() + 15, 7432 $padding = ($windowWidth - mk_responsive_nav_width) / 2; 7433 7434 7435 7436 function updateStartTour(){ 7437 if($windowWidth < mk_responsive_nav_width){ 7438 $this.removeClass('hidden'); 7439 $this.addClass('show'); 7440 }else{ 7441 if($padding < $linkWidth){ 7442 $this.removeClass('show'); 7443 $this.addClass('hidden'); 7444 }else{ 7445 $this.removeClass('hidden'); 7446 $this.addClass('show'); 7447 } 7448 } 7449 } 7450 7451 setTimeout(function() { 7452 updateStartTour(); 7453 }, 300); 7454 }); 7455} 7456 7457/* Page Section Socail Video Player Controls */ 7458/* -------------------------------------------------------------------- */ 7459 7460function mk_page_section_social_video_bg() { 7461 $(".mk-page-section.social-hosted").each(function() { 7462 var $container = $(this), 7463 $sound = $container.data('sound'), 7464 $source = $container.data('source'), 7465 player, 7466 timer = 1000; 7467 7468 if ( $( 'body' ).hasClass( '.compose-mode' ) ) { 7469 timer = 2000; 7470 } 7471 7472 if ($source == 'youtube') { 7473 var youtube = $container.find('iframe')[0]; 7474 try { 7475 player = new YT.Player(youtube, { 7476 events: { 7477 'onReady': function () { 7478 player.playVideo(); 7479 if($sound == false) { 7480 player.mute(); 7481 } 7482 } 7483 } 7484 }); 7485 7486 7487 } catch (e) { 7488 console.log( e ); 7489 } 7490 } 7491 if ($source == 'vimeo') { 7492 var vimeo = $container.find('iframe')[0]; 7493 player = $f(vimeo); 7494 setTimeout(function() { 7495 player.api('play'); 7496 if($sound === false) {
7497 player.api('setVolume', 0); 7498 } 7499 }, timer); 7500 } 7501 7502 }); 7503} 7504 7505// Pre RequireJS hot bug fixing 7506 7507function videoLoadState() { 7508 $('.mk-section-video video').each(function() { 7509 var mkVideo = this; 7510 7511 mkVideo.play(); 7512 this.onload = fire(); 7513 7514 function fire() { 7515 setTimeout(function() { 7516 $(mkVideo).animate({ 7517 'opacity': 1 7518 }, 300); 7519 }, 1000); 7520 } 7521 }); 7522} 7523videoLoadState(); 7524 7525 7526// Gmap Widget 7527(function($) { 7528 7529 $(window).on('load vc_reload', initialize); 7530 7531 function initialize() { 7532 var $gmap = $('.gmap_widget'); 7533 if($gmap.length && typeof google !== 'undefined') $gmap.each(run); 7534 } 7535 7536 function run() { 7537 var $mapHolder = $(this); 7538 var myLatlng = new google.maps.LatLng($mapHolder.data('latitude'), $mapHolder.data('longitude')); 7539 var mapOptions = $mapHolder.data('options'); 7540 mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP; 7541 mapOptions.center = myLatlng; 7542 var map = new google.maps.Map(this, mapOptions); 7543 7544 new google.maps.Marker({ 7545 position: myLatlng, 7546 map: map 7547 }); 7548 } 7549 7550}(jQuery)); 7551 7552// Instagram Widget 7553(function($) { 7554 7555 $(window).on('load', function() { 7556 var $feeds = $('.mk-instagram-feeds'); 7557 if($feeds.length) $feeds.each(run); 7558 }); 7559 7560 function run() { 7561 var options = $(this).data('options'); 7562 options.template = '<a class="featured-image '+options.tmp_col+'-columns" href="{{link}}" target="_'+options.tmp_target+'"><div class="item-holder"><img src="{{image}}" /><div class="image-hover-overlay"></div></div></a>'; 7563 var feed = new Instafeed(options); 7564 feed.run(); 7565 } 7566}(jQuery)); 7567 7568 7569// Flipbox backface visibility fix for chrome 7570(function($) { 7571 $(window).on('load', function() { 7572 setTimeout( function() { 7573 $('.chrome-flipbox-backface-fix').removeClass('chrome-flipbox-backface-fix'); 7574 }, 300); 7575 }); 7576}(jQuery)); 7577 7578 7579/* Product in VC Tab Bug Fix 7580/* -------------------------------------------------------------------- */ 7581(function($) { 7582 $(window).on('load', function() { 7583 $('.vc_tta-tab a').on('click', function() { 7584 setTimeout( function() { 7585 $(window).trigger('resize'); 7586 }, 100); 7587 }); 7588 }); 7589}(jQuery)); 7590 7591 7592/* Vertical menu fix when childrens exceed screen height 7593/* -------------------------------------------------------------------- */ 7594(function($) { 7595 $(window).on('load', function() { 7596 $('#mk-vm-menu .menu-item-has-children, #mk-vm-menu .mk-vm-back').on('mouseenter', function() { 7597 var $header_inner = $(this).closest('.mk-header-inner'), 7598 $header_inner_height = $header_inner.outerHeight(), 7599 $header_bg = $header_inner.find('.mk-header-bg'), 7600 total_height = 0; 7601 $header_bg.css('height', '100%'); 7602 setTimeout( function() { 7603 $header_inner.children(':visible').each(function() { 7604 total_height += $(this).outerHeight(true); 7605 }); 7606 total_height -= $header_bg.height(); 7607 if ( total_height < $header_inner_height ) { 7608 $header_bg.css('height', '100%'); 7609 } else { 7610 $header_bg.css('height', total_height + 'px'); 7611 } 7612 }, 600); 7613 }); 7614 }); 7615}(jQuery)); 7616 7617 7618/* Woocommerce varitions lightbox fix 7619/* -------------------------------------------------------------------- */ 7620(function($) { 7621 $(window).on('load', function() { 7622 7623 var $variations_form = $('.variations_form'); 7624 7625 if ( $variations_form.length ) { 7626 7627 var $varitions_selects = $variations_form.find('.variations').find('.value').find('select'); 7628 $varitions_selects.on('change', function() { 7629 7630 // Woocommerce variations lightbox with galleries 7631 var $all_img_container = $('.mk-product-image .mk-woocommerce-main-image'); 7632 if ( $all_img_container.length ) { 7633 $( $all_img_container ).each( set_lightbox_href ); 7634 } 7635 7636 }); 7637 $varitions_selects.trigger('change'); 7638 7639 } 7640 7641 }); 7642 7643 function set_lightbox_href() { 7644 7645 var $product_img = $( this ).find( 'img' ), 7646 $lightbox = $( this ).find( '.mk-lightbox' ); 7647 7648 setTimeout( function() { 7649 var image_url = $product_img.attr( 'src' ), 7650 image_suffix = image_url.substr( image_url.lastIndexOf('.') - image_url.length ), // Get image suffix 7651 image_url = image_url.slice( 0 , image_url.lastIndexOf('-') ); // Remove image size 7652 $lightbox.attr('href', image_url + image_suffix ); 7653 }, 300); 7654 } 7655 7656}(jQuery)); 7657 7658 7659/* Remove video section when on mobile */ 7660/* -------------------------------------------------------------------- */ 7661(function($) { 7662 if ( MK.utils.isMobile() ) {
7663 $('.mk-section-video video').remove(); 7664 } 7665}(jQuery)); 7666 7667 7668/* Yith AJAX Product Filter & Yith Infinite Scrolling Plugin Fix 7669/* -------------------------------------------------------------------- */ 7670(function($) { 7671 $(window).on('load', function() { 7672 7673 $(document).on( 'yith-wcan-ajax-filtered yith_infs_added_elem yith-wcan-ajax-reset-filtered', function(){ 7674 setTimeout( function() { 7675 MK.utils.eventManager.publish('ajaxLoaded'); 7676 MK.core.initAll( document ); 7677 }, 1000 ); 7678 }); 7679 7680 // Fixed YITH Filter plugin causes issue for dropdown sort 7681 $(document).on( 'yith-wcan-ajax-filtered yith-wcan-ajax-reset-filtered', function(){ 7682 setTimeout( function() { 7683 $( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() { 7684 $( this ).closest( 'form' ).submit(); 7685 }); 7686 }, 1000 ); 7687 }); 7688 7689 }); 7690}(jQuery)); 7691 7692 7693/* Toggle loading state in URL for anchor links. 7694 * - Add a filter to escape meta-chars from hash string. 7695/* -------------------------------------------------------------------- */ 7696!function(e){var a=window.location,n=a.hash;if(n.length&&n.substring(1).length){var hSuf = n.substring(1).replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, "\\$&");var r=e(".vc_row, .mk-main-wrapper-holder, .mk-page-section, #comments"),t=r.filter("#"+hSuf);if(!t.length)return;n=n.replace("!loading","");var i=n+"!loading";a.hash=i}}(jQuery); 7697 7698 7699/* Determine the top spacing of sidebar for full-width page section & row. 7700/* -------------------------------------------------------------------- */ 7701function mkPositionSidebar() { 7702 7703 var themeContent = $( '.theme-content' ), 7704 lastFullWidthChild = themeContent.find( '.vc_row-full-width' ).last(), 7705 top, 7706 sidebar = $( '#theme-page > .mk-main-wrapper-holder > .theme-page-wrapper > #mk-sidebar' ); 7707 7708 if ( ! lastFullWidthChild.length ) { 7709 sidebar.removeAttr( 'style' ); 7710 return; 7711 } 7712 7713 top = lastFullWidthChild.offset().top - themeContent.offset().top; 7714 sidebar.css( 'padding-top', top ); 7715} 7716 7717function mk_accordion_toggles_tooltip() { 7718 7719 "use strict"; 7720 7721 7722 /* Message Boxes */ 7723 /* -------------------------------------------------------------------- */ 7724 7725 $('.box-close-btn').on('click', function() { 7726 $(this).parent().fadeOut(300); 7727 return false; 7728 7729 }); 7730 7731} 7732 7733function mk_portfolio_ajax() { 7734 "use strict"; 7735 7736 var headerHeight = 0; 7737 if ($.exists("#wpadminbar")) { 7738 headerHeight += $("#wpadminbar").height(); 7739 } 7740 if (!$.exists('.mk-vm-menuwrapper')) { 7741 headerHeight += parseInt($('.mk-header').attr('data-sticky-height')); 7742 } 7743 7744 function init() { 7745 var $portfolio = $('.portfolio-grid.portfolio-ajax-enabled'); 7746 if (!$portfolio.length) return; // quit if no portfolio wrappers 7747 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.ajax.portfolio.js' ], function() { 7748 // wait for ajax response propagation and insertion 7749 setTimeout(function() { 7750 $portfolio.each( function() { 7751 $(this).ajaxPortfolio({ extraOffset: headerHeight }); 7752 }); 7753 }, 100); 7754 }); 7755 } 7756 7757 init(); 7758 7759 // Reinit when ajax loaded stuff 7760 // We have global reinit on Components. so move the ajaxPortfolio to component namespace as a standalone module to get it right. 7761 MK.utils.eventManager.subscribe('ajaxLoaded', init); 7762} 7763 7764/** 7765 * Ajax Search on header nav. 7766 */ 7767function mk_ajax_search() { 7768 "use strict"; 7769 7770 // Check if ajax search box enabled. 7771 if (mk_ajax_search_option !== "beside_nav") { 7772 return; 7773 } 7774 7775 // Set minimum length of text to get ajax result. 7776 var minimumLengthToSearch = 3; 7777 var $mkAjaxSearchInput = $('#mk-ajax-search-input'); 7778 var security = $mkAjaxSearchInput.siblings('input[name="security"]').val(); 7779 var wpHttpReferer = $mkAjaxSearchInput.siblings('input[name="_wp_http_referer"]').val(); 7780 var querySpliter = (ajaxurl.indexOf('?') > -1) ? '&' : '?'; 7781 var ul = document.getElementById('mk-nav-search-result'); 7782 var searchTerm; // Search term 7783 var requestCounter = 0; 7784 var responseCounter = 0; 7785 7786 // Add listener for getting result quickly while user entering text, past text and etc. 7787 $mkAjaxSearchInput.on('paste input propertychange', onSearchBoxInput); 7788 7789 /** 7790 * Callback function for entering search term listener (e.g. keyup). 7791 * It will generate AJAX request to get data. 7792 * 7793 * @param e 7794 */ 7795 function onSearchBoxInput(e) { 7796 var target = e.target || e.srcElement; 7797 var newValue = target.value; 7798 7799 // Check if user change the value of text box 7800 if (searchTerm !== newValue) { 7801 searchTerm = newValue; 7802 ul.innerHTML = ''; 7803 if (searchTerm.length >= minimumLengthToSearch) { 7804 // Show loading icon 7805 $mkAjaxSearchInput.addClass('ajax-searching'); 7806 requestCounter++; 7807 $.getJSON(ajaxurl + querySpliter + 'callback=?&action=mk_ajax_search&security=' + security + '&_wp_http_referer=' + wpHttpReferer + '&term=' + searchTerm) 7808 .done(showSearchResult) 7809 .fail(showErrorMessage); 7810 } 7811 } 7812 } 7813 7814 /** 7815 * Callback function for the response of the search request. 7816 * 7817 * @param data 7818 */ 7819 function showSearchResult(data) { 7820 responseCounter++; 7821 7822 // Only show response of latest request. 7823 if (isCorrectResponse()) { 7824 if (data.length > 0) { 7825 // Append result to result container 7826 for (var i = 0; i < data.length; i++) { 7827 var item = data[i]; 7828 $('<li>').append('<a href="' + item.link + '">' + item.image + '<span class="search-title">' + item.label + '</span><span class="search-date">' + item.date + '</span></a>').appendTo(ul); 7829 } 7830 } else { 7831 // Show no result message 7832 ul.innerHTML = '<li class="mk-nav-search-result-zero">No Result.</li>'; 7833 } 7834 7835 // Hide loading icon 7836 $mkAjaxSearchInput.parent('form').removeClass('ajax-searching').addClass('ajax-search-complete'); 7837 } 7838 } 7839 7840 /** 7841 * If any errors, we need a handler to show error message. 7842 */ 7843 function showErrorMessage() { 7844 responseCounter++; 7845 7846 if (isCorrectResponse()) { 7847 ul.innerHTML = '<li class="mk-nav-search-error-message">Can not search! Please try again.</li>'; 7848 } 7849 } 7850 7851 /** 7852 * Check if the response is right for the request. we show latest response only. 7853 * 7854 * @returns {boolean} 7855 */ 7856 function isCorrectResponse() { 7857 return requestCounter === responseCounter; 7858 } 7859}
7860/* Background Parallax Effects */ 7861/* -------------------------------------------------------------------- */ 7862 7863function mk_backgrounds_parallax() { 7864 7865 "use strict"; 7866 7867 if (mk_header_parallax == true) { 7868 $('.mk-header-bg').addClass('mk-parallax-enabled'); 7869 } 7870 if (mk_body_parallax == true) { 7871 $('body').addClass('mk-parallax-enabled'); 7872 } 7873 if (mk_banner_parallax == true) { 7874 $('.mk-header').addClass('mk-parallax-enabled'); 7875 } 7876 if (mk_footer_parallax == true) { 7877 $('#mk-footer').addClass('mk-parallax-enabled'); 7878 } 7879 7880 $('.mk-parallax-enabled').each(function () { 7881 var $this = $( this ); 7882 if (!MK.utils.isMobile()) { 7883 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() { 7884 $this.parallax("49%", 0.3); 7885 }); 7886 } 7887 }); 7888 7889 $('.mk-fullwidth-slideshow.parallax-slideshow').each(function () { 7890 var $this = $( this ); 7891 if (!MK.utils.isMobile()) { 7892 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() { 7893 var speed_factor = $this.attr('data-speedFactor'); 7894 $this.parallax("49%", speed_factor); 7895 }); 7896 } 7897 }); 7898 7899} 7900/* Blog, Portfolio Audio */ 7901/* -------------------------------------------------------------------- */ 7902 7903function loop_audio_init() { 7904 if ($.exists('.jp-jplayer')) { 7905 $('.jp-jplayer.mk-blog-audio').each(function () { 7906 var $this = $( this ); 7907 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.jplayer.js' ], function() { 7908 var css_selector_ancestor = "#" + $this.siblings('.jp-audio').attr('id'); 7909 var ogg_file, mp3_file, mk_theme_js_path; 7910 ogg_file = $this.attr('data-ogg'); 7911 mp3_file = $this.attr('data-mp3'); 7912 $this.jPlayer({ 7913 ready: function () { 7914 $this.jPlayer("setMedia", { 7915 mp3: mp3_file, 7916 ogg: ogg_file 7917 }); 7918 }, 7919 play: function () { // To avoid both jPlayers playing together. 7920 $this.jPlayer("pauseOthers"); 7921 }, 7922 swfPath: mk_theme_js_path, 7923 supplied: "mp3, ogg", 7924 cssSelectorAncestor: css_selector_ancestor, 7925 wmode: "window" 7926 }); 7927 }); 7928 }); 7929 } 7930} 7931 7932 7933/* Blog Loop Carousel Shortcode */ 7934/* -------------------------------------------------------------------- */ 7935 7936 7937function mk_blog_carousel() { 7938 7939 "use strict"; 7940 7941 if (!$.exists('.mk-blog-showcase')) { 7942 return; 7943 } 7944 $('.mk-blog-showcase ul li').each(function () { 7945 7946 $(this).on('hover', function () { 7947 7948 $(this).siblings('li').removeClass('mk-blog-first-el').end().addClass('mk-blog-first-el'); 7949 7950 }); 7951 7952 }); 7953 7954 7955} 7956 7957 7958 7959 7960/** 7961 * Contact Form 7962 * 7963 * Mostly implemented in Vanilla JS instead of jQuery. 7964 */ 7965function mk_contact_form() { 7966 "use strict"; 7967 var mkContactForms = document.getElementsByClassName('mk-contact-form'); 7968 if (mkContactForms.length === 0) { 7969 return; 7970 } 7971 var captchaImageHolder = $('.captcha-image-holder'); 7972 var activeClassName = 'is-active'; 7973 var invalidClassName = 'mk-invalid'; 7974 for (var i = 0; i < mkContactForms.length; i++) { 7975 initializeForm(mkContactForms[i], activeClassName, invalidClassName); 7976 } 7977 if (captchaImageHolder.length > 0) { 7978 $(window).on('load', initializeCaptchas); 7979 } 7980 /** 7981 * Initialize mk forms. e.g add activeClassName for inputs. 7982 * 7983 * @param form 7984 * @param activeClassName 7985 * @param invalidClassName 7986 */ 7987 function initializeForm(form, activeClassName, invalidClassName) { 7988 var inputs = getFormInputs(form); 7989 for (var i = 0; i < inputs.length; i++) { 7990 markActiveClass(inputs[i]); 7991 } 7992 form.addEventListener('submit', function(e) { 7993 validateForm(e, invalidClassName); 7994 }); 7995 /** 7996 * Set activeClassName for the parent node of the inout 7997 */ 7998 function setActiveClass() { 7999 addClass(this.parentNode, activeClassName); 8000 } 8001 /** 8002 * Unset activeClassName from the parent node of the input. 8003 * We need to unset activeClassName only if the data was empty. 8004 * e.g. in the line style of the mk-contact-form, we set labels position based on activeClassName. 8005 */ 8006 function unsetActiveClass() { 8007 if (this.value === '') { 8008 removeClass(this.parentNode, activeClassName); 8009 } 8010 } 8011 /** 8012 * Add event listeners (focus,blur) for input to set and unset activeClassName. 8013 * 8014 * @param input 8015 */ 8016 function markActiveClass(input) { 8017 input.addEventListener('focus', setActiveClass); 8018 input.addEventListener('blur', unsetActiveClass); 8019 } 8020 } 8021 /** 8022 * Validate form when it's submitted. If everything was valid, we with post form in ajax request. 8023 * 8024 * @param e 8025 * @param invalidClassName 8026 */ 8027 function validateForm(e, invalidClassName) { 8028 e.preventDefault(); 8029 var form = e.target || e.srcElement; 8030 var inputs = getFormInputs(form); 8031 var isValidForm = true; 8032 var hasCaptchaField = false;
8033 for (var i = 0; i < inputs.length; i++) { 8034 var input = inputs[i]; 8035 input.value = String(input.value).trim(); 8036 switch (input.type) { 8037 case 'hidden': 8038 break; 8039 case 'checkbox': 8040 isValidForm = validateCheckBox(input, invalidClassName) && isValidForm; 8041 break; 8042 case 'email': 8043 isValidForm = validateEmail(input, invalidClassName) && isValidForm; 8044 break; 8045 case 'textarea': 8046 isValidForm = validateText(input, invalidClassName) && isValidForm; 8047 break; 8048 case 'text': 8049 /** 8050 * Some old browsers such as IE 8 and 9 detect email type as text. 8051 * So, we need to extra check for data-type attribute 8052 */ 8053 if (input.dataset.type === 'captcha') { 8054 isValidForm = validateText(input, invalidClassName) && isValidForm; 8055 hasCaptchaField = true; 8056 } else if (input.dataset.type === 'email') { 8057 isValidForm = validateEmail(input, invalidClassName) && isValidForm; 8058 } else { 8059 isValidForm = validateText(input, invalidClassName) && isValidForm; 8060 } 8061 break; 8062 default: 8063 /** 8064 * e.g. validating for radiobox, selectbox and etc. 8065 */ 8066 console.warn('Implement validation for ' + input.name + ':' + input.type); 8067 break; 8068 } 8069 } 8070 if (isValidForm) { 8071 if (hasCaptchaField) { 8072 validateCaptcha(form, invalidClassName, sendForm); 8073 } else { 8074 sendForm(form); 8075 } 8076 } 8077 } 8078 /** 8079 * Validate captcha of form. If everything was, we will execute captchaIsValidCallback which as sendForm(). 8080 * 8081 * @param form 8082 * @param invalidClassName 8083 * @param captchaIsValidCallback 8084 * @returns boolean 8085 */ 8086 function validateCaptcha(form, invalidClassName, captchaIsValidCallback) { 8087 var input = form.querySelectorAll('[data-type="captcha"]')[0]; 8088 if (input.value.length === 0) { 8089 addClass(input, invalidClassName); 8090 return false; 8091 } else { 8092 window.get.captcha(input.value).done(function(data) { 8093 loadCaptcha(); 8094 input.value = ''; 8095 if (data !== 'ok') { 8096 addClass(input, invalidClassName); 8097 addClass(input, 'contact-captcha-invalid'); 8098 removeClass(input, 'contact-captcha-valid'); 8099 input.placeholder = mk_captcha_invalid_txt; 8100 } else { 8101 removeClass(input, invalidClassName); 8102 removeClass(input, 'contact-captcha-invalid'); 8103 addClass(input, 'contact-captcha-valid'); 8104 input.placeholder = mk_captcha_correct_txt; 8105 captchaIsValidCallback(form); 8106 } 8107 }); 8108 } 8109 } 8110 /** 8111 * Send submitted form. 8112 * 8113 * @param form 8114 */ 8115 function sendForm(form) { 8116 var $form = $(form); 8117 var data = getFormData(form); 8118 progressButton.loader($form); 8119 $.post(ajaxurl, data, function(response) { 8120 var res = JSON.parse(response); 8121 if (res.action_Status) { 8122 progressButton.success($form); 8123 $form.find('.text-input').val(''); 8124 $form.find('textarea').val(''); 8125 $form.find('input[type=checkbox]').attr("checked", false); 8126 $form.find('.contact-form-message').slideDown().addClass('state-success').html(res.message); 8127 setTimeout(function() { 8128 $form.find('.contact-form-message').slideUp(); 8129 }, 5000); 8130 } else { 8131 progressButton.error($form); 8132 $form.find('.contact-form-message').removeClass('state-success').html(res.message); 8133 } 8134 }); 8135 } 8136 /** 8137 * Initialize all captcha images for first time. All captcha images is always same. e.g. if we have multiple form, 8138 * all of them will have the same image. 8139 * It will also add event listener for '.captcha-change-image' objects to reload the captcha. 8140 */ 8141 function initializeCaptchas() { 8142 var captchaChangeImageButtons = document.getElementsByClassName('captcha-change-image'); 8143 for (var i = 0; i < captchaChangeImageButtons.length; i++) { 8144 captchaChangeImageButtons[i].addEventListener('click', loadCaptcha); 8145 } 8146 } 8147 /** 8148 * Load captcha text and append the image to captcha container. 8149 * If it used as a callback, it will prevent default behave of the event. 8150 * e.g. loading new captcha by click on <a> without changing url. 8151 */ 8152 function loadCaptcha(e) { 8153 if (e) { 8154 e.preventDefault(); 8155 } 8156 $.post(ajaxurl, { 8157 action: 'mk_create_captcha_image' 8158 }, appendImage); 8159 /** 8160 * The callback function for append or change old image src based on response. T 8161 * The captchaImageURL is the url of the captcha which is provided in ajax response of mk_create_captcha_image. 8162 * @param captchaImageURL 8163 */ 8164 function appendImage(captchaImageURL) { 8165 if (captchaImageHolder.find('.captcha-image').length === 0) { 8166 captchaImageHolder.html('<img src="' + captchaImageURL + '" class="captcha-image" alt="captcha txt">'); 8167 } else { 8168 captchaImageHolder.find('.captcha-image').attr("src", captchaImageURL + '?' + new Date().getTime()); 8169 } 8170 } 8171 } 8172 /** 8173 * Get form inputs using querySelectorAll(). 8174 * It returns <input> and <textarea> tags. If you need any other tags such as <select>, please update this function. 8175 * 8176 * @param form 8177 * @returns {NodeList} 8178 */ 8179 function getFormInputs(form) { 8180 return form.querySelectorAll('input,textarea'); 8181 } 8182 /** 8183 * Get data of the form inputs and textareas as a object. 8184 * 8185 * @param form 8186 * @returns {{action: string}} 8187 */ 8188 function getFormData(form) { 8189 var data = { 8190 action: 'mk_contact_form' 8191 }; 8192 var inputs = getFormInputs(form); 8193 for (var i = 0; i < inputs.length; i++) {
8194 data[inputs[i].name] = inputs[i].value; 8195 } 8196 return data; 8197 } 8198} 8199/* Ajax Login Form */ 8200/* -------------------------------------------------------------------- */ 8201function mk_login_form() { 8202 $('form.mk-login-form').each(function() { 8203 var $this = $(this); 8204 $this.on('submit', function(e) { 8205 $('p.mk-login-status', $this).show().text(ajax_login_object.loadingmessage); 8206 $.ajax({ 8207 type: 'POST', 8208 dataType: 'json', 8209 url: ajax_login_object.ajaxurl, 8210 data: { 8211 'action': 'ajaxlogin', 8212 'username': $('#username', $this).val(), 8213 'password': $('#password', $this).val(), 8214 'security': $('#security', $this).val() 8215 }, 8216 success: function(data) { 8217 $('p.mk-login-status', $this).text(data.message); 8218 if (data.loggedin === true) { 8219 document.location.href = ajax_login_object.redirecturl; 8220 } 8221 } 8222 }); 8223 e.preventDefault(); 8224 }); 8225 }); 8226} 8227/* Progress Button */ 8228/* -------------------------------------------------------------------- */ 8229var progressButton = { 8230 loader: function(form) { 8231 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() { 8232 var $form = form, 8233 progressBar = $form.find(".mk-progress-button .mk-progress-inner"), 8234 buttonText = $form.find(".mk-progress-button .mk-progress-button-content"), 8235 progressButton = new TimelineLite(); 8236 progressButton.to(progressBar, 0, { 8237 width: "100%", 8238 scaleX: 0, 8239 scaleY: 1 8240 }).to(buttonText, .3, { 8241 y: -5 8242 }).to(progressBar, 1.5, { 8243 scaleX: 1, 8244 ease: Power2.easeInOut 8245 }, "-=.1").to(buttonText, .3, { 8246 y: 0 8247 }).to(progressBar, .3, { 8248 scaleY: 0 8249 }); 8250 }); 8251 }, 8252 success: function(form) { 8253 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() { 8254 var $form = form, 8255 buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"), 8256 successIcon = $form.find(".mk-progress-button .state-success"), 8257 progressButtonSuccess = new TimelineLite({ 8258 onComplete: hideSuccessMessage 8259 }); 8260 progressButtonSuccess.to(buttonText, .3, { 8261 paddingRight: 20, 8262 ease: Power2.easeInOut 8263 }, "+=1").to(successIcon, .3, { 8264 opacity: 1 8265 }).to(successIcon, 2, { 8266 opacity: 1 8267 }); 8268 8269 function hideSuccessMessage() { 8270 progressButtonSuccess.reverse() 8271 } 8272 }); 8273 }, 8274 error: function(form) { 8275 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() { 8276 var $form = form, 8277 buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"), 8278 errorIcon = $form.find(".mk-progress-button .state-error"), 8279 progressButtonError = new TimelineLite({ 8280 onComplete: hideErrorMessage 8281 }); 8282 progressButtonError.to(buttonText, .3, { 8283 paddingRight: 20 8284 }, "+=1").to(errorIcon, .3, { 8285 opacity: 1 8286 }).to(errorIcon, 2, { 8287 opacity: 1 8288 }); 8289 8290 function hideErrorMessage() { 8291 progressButtonError.reverse() 8292 } 8293 }); 8294 } 8295}; 8296function mk_click_events() { 8297 "use strict"; 8298 8299 var eventtype = 'click'; 8300 8301 $(".mk-header-login, .mk-header-signup, .mk-side-dashboard, .mk-quick-contact-wrapper, .mk-dashboard-trigger, .blog-share-container, .news-share-buttons, .main-nav-side-search, #mk-fullscreen-search-wrapper, #fullscreen-navigation").on(eventtype, function(event) { 8302 if (event.stopPropagation) { 8303 event.stopPropagation(); 8304 } else if (window.event) { 8305 window.event.cancelBubble = true; 8306 } 8307 }); 8308 $("html").on(eventtype, function() {
8309 $(".mk-login-register, .mk-header-subscribe, #mk-quick-contact, .single-share-buttons, .single-share-box, .blog-social-share, .news-share-buttons, #mk-nav-search-wrapper").fadeOut(300); 8310 $('.mk-quick-contact-link').removeClass('quick-contact-active'); 8311 // Removed By Maki for repairing fullnav scroll issue. Hope it odesnt break anything 8312 // $('body').css('overflow', 'visible'); 8313 }); 8314 8315 $('.mk-fullscreen-search-overlay').on(eventtype,function(){ 8316 $(this).removeClass('mk-fullscreen-search-overlay-show'); 8317 }); 8318 8319 $('.mk-forget-password').on(eventtype, function() { 8320 $('.mk-forget-panel').siblings().hide().end().show(); 8321 }); 8322 8323 $('.mk-create-account').on(eventtype, function() { 8324 $('#mk-register-panel').siblings().hide().end().show(); 8325 }); 8326 8327 $('.mk-return-login').on(eventtype, function() { 8328 $('#mk-login-panel').siblings().hide().end().show(); 8329 }); 8330 8331 8332 $('.mk-quick-contact-link').on(eventtype, function() { 8333 var $this = $(this), 8334 $quickContact = $('#mk-quick-contact'); 8335 if (!$this.hasClass('quick-contact-active')) { 8336 $quickContact.addClass('quick-contact-anim').fadeIn(250); 8337 $this.addClass('quick-contact-active'); 8338 } else { 8339 $quickContact.removeClass('quick-contact-anim').fadeOut(100); 8340 $this.removeClass('quick-contact-active'); 8341 } 8342 return false; 8343 }); 8344 8345} 8346 8347function mk_social_share_global() { 8348 8349 "use strict"; 8350 8351 var eventtype = 'click'; 8352 8353 $('.twitter-share').on(eventtype, function() { 8354 var $this = $(this), 8355 $url = $this.attr('data-url'), 8356 $title = $this.attr('data-title'); 8357 8358 window.open('http://twitter.com/intent/tweet?text=' + $title + ' ' + $url, "twitterWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 8359 return false; 8360 }); 8361 8362 $('.pinterest-share').on(eventtype, function() { 8363 var $this = $(this), 8364 $url = $this.attr('data-url'), 8365 $title = $this.attr('data-title'), 8366 $image = $this.attr('data-image'); 8367 window.open('http://pinterest.com/pin/create/button/?url=' + $url + '&media=' + $image + '&description=' + $title, "twitterWindow", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 8368 return false; 8369 }); 8370 8371 $('.facebook-share').on(eventtype, function() { 8372 var $url = $(this).attr('data-url'); 8373 window.open('https://www.facebook.com/sharer/sharer.php?u=' + $url, "facebookWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 8374 return false; 8375 }); 8376 8377 $('.googleplus-share').on(eventtype, function() { 8378 var $url = $(this).attr('data-url'); 8379 window.open('https://plus.google.com/share?url=' + $url, "googlePlusWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 8380 return false; 8381 }); 8382 8383 $('.linkedin-share').on(eventtype, function() { 8384 var $this = $(this), 8385 $url = $this.attr('data-url'), 8386 $title = $this.attr('data-title'), 8387 $desc = $this.attr('data-desc'); 8388 window.open('http://www.linkedin.com/shareArticle?mini=true&url=' + $url + '&title=' + $title + '&summary=' + $desc, "linkedInWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 8389 return false; 8390 }); 8391} 8392 8393 8394/* Event Count Down */ 8395/* -------------------------------------------------------------------- */ 8396 8397function mk_event_countdown() { 8398 if ($.exists('.mk-event-countdown')) { 8399 8400 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.countdown.js' ], function() { 8401 8402 $('.mk-event-countdown').each(function () { 8403 if (isTest) return; 8404 var $this = $(this), 8405 $date = $this.attr('data-date'), 8406 $offset = $this.attr('data-offset'); 8407 8408 $this.downCount({ 8409 date: $date, 8410 offset: $offset 8411 }); 8412 }); 8413 8414 }); 8415 } 8416} 8417/* Flexslider init */ 8418/* -------------------------------------------------------------------- */ 8419 8420function mk_flexslider_init() { 8421 8422 var $lcd = $('.mk-lcd-slideshow'), 8423 $laptop = $('.mk-laptop-slideshow-shortcode'); 8424 8425 if($lcd.length) $lcd.find('.mk-lcd-image').fadeIn(); 8426 if($laptop.length) $laptop.find(".mk-laptop-image").fadeIn(); 8427 8428 $('.js-flexslider').each(function () { 8429 8430 if ($(this).parents('.mk-tabs').length || $(this).parents('.mk-accordion').length) { 8431 $(this).removeData("flexslider"); 8432 } 8433 8434 var $this = $(this), 8435 $selector = $this.attr('data-selector'), 8436 $animation = $this.attr('data-animation'), 8437 $easing = $this.attr('data-easing'), 8438 $direction = $this.attr('data-direction'), 8439 $smoothHeight = $this.attr('data-smoothHeight') == "true" ? true : false,
8440 $slideshowSpeed = $this.attr('data-slideshowSpeed'), 8441 $animationSpeed = $this.attr('data-animationSpeed'), 8442 $controlNav = $this.attr('data-controlNav') == "true" ? true : false, 8443 $directionNav = $this.attr('data-directionNav') == "true" ? true : false, 8444 $pauseOnHover = $this.attr('data-pauseOnHover') == "true" ? true : false, 8445 $isCarousel = $this.attr('data-isCarousel') == "true" ? true : false; 8446 8447 8448 if ($selector !== undefined) { 8449 var $selector_class = $selector; 8450 } else { 8451 var $selector_class = ".mk-flex-slides > li"; 8452 } 8453 8454 if ($isCarousel === true) { 8455 var $itemWidth = parseInt($this.attr('data-itemWidth')), 8456 $itemMargin = parseInt($this.attr('data-itemMargin')), 8457 $minItems = parseInt($this.attr('data-minItems')), 8458 $maxItems = parseInt($this.attr('data-maxItems')), 8459 $move = parseInt($this.attr('data-move')); 8460 } else { 8461 var $itemWidth = $itemMargin = $minItems = $maxItems = $move = 0; 8462 } 8463 8464 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.flexslider.js' ], function() { 8465 $this.flexslider({ 8466 selector: $selector_class, 8467 animation: $animation, 8468 easing: $easing, 8469 direction: $direction, 8470 smoothHeight: $smoothHeight, 8471 slideshow: !isTest, // autoplay 8472 slideshowSpeed: $slideshowSpeed, 8473 animationSpeed: $animationSpeed, 8474 controlNav: $controlNav, 8475 directionNav: $directionNav, 8476 pauseOnHover: $pauseOnHover, 8477 prevText: "", 8478 nextText: "", 8479 itemWidth: $itemWidth, 8480 itemMargin: $itemMargin, 8481 minItems: $minItems, 8482 maxItems: $maxItems, 8483 move: $move 8484 }); 8485 }); 8486 8487 }); 8488 8489} 8490 8491/* Header Search Form */ 8492/* -------------------------------------------------------------------- */ 8493 8494function mk_header_searchform() { 8495 8496 $('.mk-search-trigger').click(function(){ 8497 setTimeout(function() { 8498 $('#mk-ajax-search-input').focus(); 8499 },500); 8500 }); 8501 8502 "use strict"; 8503 8504 $('.mk-header-toolbar .mk-header-searchform .text-input').on('focus', function () { 8505 8506 if ($('.mk-header-toolbar .mk-header-searchform .text-input').hasClass('on-close-state')) { 8507 $('.mk-header-toolbar .mk-header-searchform .text-input').removeClass('on-close-state').animate({ 8508 'width': '200px' 8509 }, 200); 8510 return false; 8511 } 8512 }); 8513 8514 $(".mk-header-toolbar .mk-header-searchform").click(function (event) { 8515 if (event.stopPropagation) { 8516 event.stopPropagation(); 8517 } else if (window.event) { 8518 window.event.cancelBubble = true; 8519 } 8520 }); 8521 8522 8523 $("html").click(function () { 8524 $(this).find(".mk-header-toolbar .mk-header-searchform .text-input").addClass('on-close-state').animate({ 8525 'width': 90 8526 }, 300); 8527 }); 8528 8529 // Fix search for edge browser 8530 if(MK.utils.browser.name === 'Edge') { 8531 $('#mk-fullscreen-search-input').on('keydown', function(e) { 8532 if (e.which == 13) { 8533 e.preventDefault(); 8534 $('#mk-fullscreen-searchform').submit(); 8535 } 8536 }); 8537 } 8538 8539} 8540 8541 8542 8543 8544/* Hover Events */ 8545/* -------------------------------------------------------------------- */ 8546 8547function mk_hover_events() { 8548 8549 "use strict"; 8550 8551 $('.shopping-cart-header').hover( 8552 function() { 8553 $(this).find('.mk-shopping-cart-box').stop(true, true).fadeIn(250); 8554 }, 8555 function() { 8556 $(this).find('.mk-shopping-cart-box').stop(true, true).delay(500).fadeOut(250); 8557 } 8558 ); 8559 8560 8561 $('.widget-sub-navigation > ul > li, .widget_nav_menu ul.menu > li, .widget_product_categories ul > .cat-item').each(function() { 8562 8563 var $this = $(this), 8564 $subLevel = $this.find('ul').first(); 8565 8566 if ($this.hasClass('page_item_has_children') || $this.hasClass('menu-item-has-children') || $this.hasClass('cat-parent')) { 8567 $this.on('click', function() { 8568 if($this.hasClass('toggle-active')) { 8569 $subLevel.stop(true, true).slideUp(700); 8570 $this.removeClass('toggle-active'); 8571 } else { 8572 $subLevel.stop(true, true).slideDown(700); 8573 $this.addClass('toggle-active'); 8574 } 8575 }); 8576 8577 $subLevel.on('click', function(e){ 8578 e.stopPropagation(); 8579 }); 8580 } 8581 8582 }); 8583 8584 // var eventtype = mobilecheck() ? 'touchstart' : 'click'; 8585 var eventtype = 'click'; 8586 8587 $('.mk-fullscreen-trigger').on(eventtype, function(e) { 8588 $('.mk-fullscreen-search-overlay').addClass('mk-fullscreen-search-overlay-show'); 8589 setTimeout(function(){ 8590 $("#mk-fullscreen-search-input").focus(); 8591 }, 300); 8592 e.preventDefault(); 8593 }); 8594 8595 $('.mk-fullscreen-close').on(eventtype, function(e) { 8596 $('.mk-fullscreen-search-overlay').removeClass('mk-fullscreen-search-overlay-show'); 8597 e.preventDefault(); 8598 }); 8599 8600} 8601 8602function mk_unfold_footer() { 8603 var $this = $('#mk-footer'), 8604 $spacer = $('#mk-footer-unfold-spacer'), 8605 $footerHeight = $this.outerHeight(); 8606 8607 // Stick with CSS media query breakpoint to target exact screen width 8608 if( !window.matchMedia("(max-width: 767px)").matches ) { 8609 if ($this.hasClass('mk-footer-unfold')) { 8610 $spacer.css('height', $footerHeight); 8611 } 8612 } else { 8613 $spacer.css('height', 0); 8614 } 8615} 8616/* jQuery fancybox lightbox */ 8617/* -------------------------------------------------------------------- */ 8618function mk_lightbox_init() { 8619 8620var $lightbox = $(".mk-lightbox"); 8621 8622 $lightbox.fancybox({ 8623 padding: 15, 8624 margin: 15, 8625 8626 width: 800, 8627 height: 600, 8628 minWidth: 100, 8629 minHeight: 100, 8630 maxWidth: 9999, 8631 maxHeight: 9999,
8632 pixelRatio: 1, // Set to 2 for retina display support 8633 8634 autoSize: true, 8635 autoHeight: false, 8636 autoWidth: false, 8637 8638 autoResize: true, 8639 fitToView: true, 8640 aspectRatio: false, 8641 topRatio: 0.5, 8642 leftRatio: 0.5, 8643 8644 scrolling: 'auto', // 'auto', 'yes' or 'no' 8645 wrapCSS: '', 8646 8647 arrows: true, 8648 closeBtn: true, 8649 closeClick: false, 8650 nextClick: false, 8651 mouseWheel: true, 8652 autoPlay: false, 8653 playSpeed: 3000, 8654 preload: 3, 8655 modal: false, 8656 loop: true, 8657 // Properties for each animation type 8658 // Opening fancyBox 8659 openEffect: 'fade', // 'elastic', 'fade' or 'none' 8660 openSpeed: 200, 8661 openEasing: 'swing', 8662 openOpacity: true, 8663 openMethod: 'zoomIn', 8664 8665 // Closing fancyBox 8666 closeEffect: 'fade', // 'elastic', 'fade' or 'none' 8667 closeSpeed: 200, 8668 closeEasing: 'swing', 8669 closeOpacity: true, 8670 closeMethod: 'zoomOut', 8671 8672 // Changing next gallery item 8673 nextEffect: 'none', // 'elastic', 'fade' or 'none' 8674 nextSpeed: 350, 8675 nextEasing: 'swing', 8676 nextMethod: 'changeIn', 8677 8678 // Changing previous gallery item 8679 prevEffect: 'none', // 'elastic', 'fade' or 'none' 8680 prevSpeed: 350, 8681 prevEasing: 'swing', 8682 prevMethod: 'changeOut', 8683 helpers : { 8684 media : {}, 8685 overlay: { 8686 locked: true 8687 } 8688 }, 8689 8690 tpl: { 8691 wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 8692 image: '<img class="fancybox-image" src="{href}" alt="" />', 8693 error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 8694 closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"><i><svg class="mk-svg-icon" svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M390.628 345.372l-45.256 45.256-89.372-89.373-89.373 89.372-45.255-45.255 89.373-89.372-89.372-89.373 45.254-45.254 89.373 89.372 89.372-89.373 45.256 45.255-89.373 89.373 89.373 89.372z"/></svg></i></a>', 8695 next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span><i><svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M144 505.6c8 0 16-3.2 22.4-8l240-225.6c6.4-6.4 9.6-14.4 9.6-22.4s-3.2-16-9.6-22.4l-240-224c-12.8-12.8-32-12.8-44.8 0s-11.2 32 1.6 44.8l214.4 201.6-216 203.2c-12.8 11.2-12.8 32 0 44.8 6.4 4.8 14.4 8 22.4 8z"/></svg></i></span></a>', 8696 prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span><i><svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M368 505.6c-8 0-16-3.2-22.4-8l-240-225.6c-6.4-6.4-9.6-14.4-9.6-24 0-8 3.2-16 9.6-22.4l240-224c12.8-11.2 33.6-11.2 44.8 1.6 12.8 12.8 11.2 32-1.6 44.8l-214.4 201.6 216 203.2c12.8 11.2 12.8 32 0 44.8-4.8 4.8-14.4 8-22.4 8z"/></svg></i></span></a>', 8697 loading: '<div id="fancybox-loading"><div></div></div>' 8698 }, 8699 8700 afterLoad: function() { 8701 $('html').addClass('fancybox-lock'); 8702 $('.fancybox-wrap').appendTo('.fancybox-overlay'); 8703 }, 8704 beforeShow: function(){ 8705 this.locked = true; 8706 }, 8707 afterClose: function() { 8708 // Only for gallery shortcode. 8709 var galleryParent = this.element.parents( '.mk-gallery-item' ); 8710 8711 if ( galleryParent ) { 8712 galleryParent.removeClass('hover-state'); 8713 } 8714 } 8715 8716 }); 8717} 8718 8719 8720/* Milestone Number Shortcode */ 8721/* -------------------------------------------------------------------- */ 8722 8723function mk_milestone() { 8724 8725 "use strict"; 8726 8727 if( isTest || !$.exists('.mk-milestone') ) return; 8728 8729 $('.mk-milestone').each(function () { 8730 var $this = $(this), 8731 stop_number = $this.find('.milestone-number').attr('data-stop'), 8732 animation_speed = parseInt($this.find('.milestone-number').attr('data-speed')); 8733 8734 var build = function() { 8735 if (!$this.hasClass('scroll-animated')) { 8736 $this.addClass('scroll-animated'); 8737 8738 $({ 8739 countNum: $this.find('.milestone-number').text() 8740 }).animate({ 8741 countNum: stop_number 8742 }, { 8743 duration: animation_speed, 8744 easing: 'linear', 8745 step: function () { 8746 $this.find('.milestone-number').text(Math.floor(this.countNum)); 8747 }, 8748 complete: function () { 8749 $this.find('.milestone-number').text(this.countNum); 8750 } 8751 }); 8752 } 8753 }; 8754 8755 if ( !MK.utils.isMobile() ) { 8756 // refactored only :in-viewport logic. rest is to-do 8757 MK.utils.scrollSpy( this, { 8758 position: 'bottom', 8759 after: build 8760 }); 8761 } else { 8762 build(); 8763 } 8764 8765 }); 8766 8767} 8768 8769 8770 8771 8772/* Recent Works Widget */ 8773/* -------------------------------------------------------------------- */ 8774 8775function mk_portfolio_widget() { 8776 8777 "use strict"; 8778 8779 $('.widget_recent_portfolio li').each(function () { 8780 8781 $(this).find('.portfolio-widget-thumb').hover(function () { 8782 8783 $(this).siblings('.portfolio-widget-info').animate({ 8784 'opacity': 1 8785 }, 200); 8786 }, function () { 8787 8788 $(this).siblings('.portfolio-widget-info').animate({ 8789 'opacity': 0 8790 }, 200); 8791 }); 8792 8793 }); 8794} 8795 8796 8797 8798/* Skill Meter and Charts */ 8799/* -------------------------------------------------------------------- */ 8800function mk_skill_meter() { 8801 "use strict"; 8802 if ($.exists('.mk-skill-meter')) { 8803 if (!MK.utils.isMobile()) { 8804 $(".mk-skill-meter .progress-outer").each(function() { 8805 var $this = $(this); 8806 8807 var build = function() { 8808 if (!$this.hasClass('scroll-animated')) { 8809 $this.addClass('scroll-animated'); 8810 $this.animate({ 8811 width: $this.attr("data-width") + '%' 8812 }, 2000); 8813 } 8814 }; 8815 8816 MK.utils.scrollSpy( this, { 8817 position: 'bottom', 8818 after: build 8819 }); 8820 }); 8821 } else { 8822 $(".mk-skill-meter .progress-outer").each(function() { 8823 var $this = $(this); 8824 if (!$this.hasClass('scroll-animated')) { 8825 $this.addClass('scroll-animated'); 8826 $this.css({ 8827 width: $(this).attr("data-width") + '%' 8828 }); 8829 } 8830 }); 8831 } 8832 } 8833} 8834 8835// function mk_charts() { 8836// "use strict"; 8837 8838// if( !$.exists('.mk-chart') ) return; 8839 8840// MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.easyPieChart.js' ], function() { 8841 8842// $('.mk-chart').each(function() { 8843 8844// var $this = $(this), 8845// $parent_width = $(this).parent().width(), 8846// $chart_size = parseInt($this.attr('data-barSize')); 8847 8848// if ($parent_width < $chart_size) { 8849// $chart_size = $parent_width; 8850// $this.css('line-height', $chart_size); 8851// $this.find('i').css({ 8852// 'line-height': $chart_size + 'px' 8853// }); 8854// $this.css({ 8855// 'line-height': $chart_size + 'px' 8856// }); 8857// } 8858 8859// var build = function() { 8860// $this.easyPieChart({ 8861// animate: 1300, 8862// lineCap: 'butt', 8863// lineWidth: $this.attr('data-lineWidth'), 8864// size: $chart_size, 8865// barColor: $this.attr('data-barColor'), 8866// trackColor: $this.attr('data-trackColor'), 8867// scaleColor: 'transparent', 8868// onStep: function(value) {
8869// this.$el.find('.chart-percent span').text(Math.ceil(value)); 8870// } 8871// }); 8872// }; 8873 8874// // refactored only :in-viewport logic. rest is to-do 8875// MK.utils.scrollSpy( this, { 8876// position: 'bottom', 8877// after: build 8878// }); 8879 8880 8881// }); 8882// }); 8883// } 8884/* Toolbar subscribe form */ 8885/* -------------------------------------------------------------------- */ 8886 8887$( "#mc-embedded-subscribe-form" ).submit(function( e ){ 8888 var $this = $(this); 8889 8890 e.preventDefault(); 8891 $.ajax({ 8892 url: MK.core.path.ajaxUrl, 8893 type: "POST", 8894 data: { 8895 action: "mk_ajax_subscribe", 8896 email: $this.find( ".mk-subscribe--email" ).val(), 8897 list_id: $this.find( ".mk-subscribe--list-id" ).val(), 8898 optin: $this.find( ".mk-subscribe--optin" ).val() 8899 }, 8900 success: function ( res ) { 8901 $this.parent().find( ".mk-subscribe--message" ).html( $.parseJSON( res ).message ); 8902 } 8903 }); 8904}); 8905/** 8906 * Add class to tag. It's vanilla js instead of jQuery. 8907 * @param tag 8908 * @param className 8909 */ 8910function addClass(tag, className) { 8911 tag.className += ' ' + className; 8912} 8913 8914/** 8915 * Remove class from tag. It's vanilla js instead of jQuery. 8916 * Replacing should be with g for replacing all occurrence. 8917 * 8918 * @param tag 8919 * @param className 8920 */ 8921function removeClass(tag, className) { 8922 tag.className = tag.className.replace(new RegExp(className, 'g'), ''); 8923} 8924 8925 8926/** 8927 * If we're running under Node for testing purpose. 8928 */ 8929if(typeof exports !== 'undefined') { 8930 exports.addClass = addClass; 8931 exports.removeClass = removeClass; 8932} 8933 8934/*! 8935* javascript-debounce 1.0.0 8936* 8937* A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function. 8938* 8939* Source code available at: https://github.com/jgarber623/javascript-debounce 8940* 8941* (c) 2015-present Jason Garber (http://sixtwothree.org) 8942* 8943* javascript-debounce may be freely distributed under the MIT license. 8944*/ 8945 8946(function(root, factory) { 8947 if (typeof define === "function" && define.amd) { 8948 define([], factory); 8949 } else if (typeof exports === "object") { 8950 module.exports = factory(); 8951 } else { 8952 root.debounce = factory(); 8953 } 8954})(this, function() { 8955 "use strict"; 8956 return function(callback, delay) { 8957 var timeout; 8958 return function() { 8959 var context = this, args = arguments; 8960 clearTimeout(timeout); 8961 timeout = setTimeout(function() { 8962 callback.apply(context, args); 8963 }, delay); 8964 }; 8965 }; 8966}); 8967 8968/** 8969 * Validate email address. 8970 * 8971 * @param input 8972 * @param invalidClassName 8973 * @returns boolean 8974 */ 8975function validateEmail(input, invalidClassName) { 8976 var value = input.value.trim(); 8977 if ((input.required || value.length > 0) && !/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,63})$/i.test(value)) { 8978 if (invalidClassName) { 8979 addClass(input, invalidClassName); 8980 } 8981 return false; 8982 } else { 8983 if (invalidClassName) { 8984 removeClass(input, invalidClassName); 8985 } 8986 return true; 8987 } 8988} 8989/** 8990 * Validate text entry. 8991 * 8992 * @param input 8993 * @param invalidClassName 8994 * @returns boolean 8995 */ 8996function validateText(input, invalidClassName) { 8997 var value = input.value.trim(); 8998 if (input.required && value.length === 0) { 8999 if (invalidClassName) { 9000 addClass(input, invalidClassName); 9001 } 9002 return false; 9003 } else { 9004 if (invalidClassName) { 9005 removeClass(input, invalidClassName); 9006 } 9007 return true; 9008 } 9009} 9010/** 9011 * Validate Checkbox. 9012 * 9013 * @param input 9014 * @param invalidClassName 9015 * @returns boolean 9016 */ 9017function validateCheckBox(input, invalidClassName) { 9018 if (input.required && input.checked == false) { 9019 if (invalidClassName) { 9020 addClass(input, invalidClassName); 9021 } 9022 return false; 9023 } else { 9024 if (invalidClassName) { 9025 removeClass(input, invalidClassName); 9026 } 9027 return true; 9028 } 9029} 9030/** 9031 * If we're running under Node for testing purpose. 9032 */ 9033if (typeof exports !== 'undefined') { 9034 exports.validateEmail = validateEmail; 9035 exports.validateText = validateText; 9036} 9037(function( $ ) { 9038 'use strict'; 9039 9040 var $wrapper = $('.js-bottom-corner-btns'); 9041 var $contactBtn = $wrapper.find('.js-bottom-corner-btn--contact'); 9042 var $backBtn = $wrapper.find('.js-bottom-corner-btn--back'); 9043 var hasContactBtn = $contactBtn.length; 9044 var hasBackBtn = $backBtn.length; 9045 9046 if(!hasBackBtn) return; 9047 9048 function deactivate() { 9049 $contactBtn.removeClass('is-active'); 9050 $backBtn.removeClass('is-active'); 9051 } 9052 9053 function activate() { 9054 $contactBtn.addClass('is-active'); 9055 $backBtn.addClass('is-active'); 9056 } 9057 9058 MK.utils.scrollSpy( 400, {
9059 before: deactivate, 9060 after: activate 9061 }); 9062 9063})( jQuery ); 9064(function($) { 9065 'use strict'; 9066 9067 $('.mk-fullscreen-nav-close, .mk-fullscreen-nav-wrapper, #fullscreen-navigation a').on('click', function(e) { 9068 9069 // Close nav with removing classes 9070 $('.mk-fullscreen-nav').removeClass('opened'); 9071 $('.mk-dashboard-trigger').removeClass('fullscreen-active'); 9072 $('body').removeClass('fullscreen-nav-opened'); 9073 9074 var anchor = MK.utils.detectAnchor( this ), 9075 $this = $( this ); 9076 9077 // Scroll to anchor if exists 9078 if( anchor.length ) { 9079 // Moved 4 these lines after anchor check because console error. If anchor 9080 // return false, split part will throw an error because $this is not a link. 9081 // Fix AM-2027 9082 var href = $this.attr( 'href' ).split( '#' )[0]; 9083 var url = window.location.href; 9084 var isSamePage = url.indexOf( href ) !== -1; 9085 9086 if ( isSamePage ) { 9087 e.preventDefault(); 9088 } 9089 MK.utils.scrollToAnchor( anchor ); 9090 9091 // Or do nothing if pointless # as href 9092 // BAD PRACTICE: it is very popular to use "#" for click elements that we listen to with js. 9093 // GOOD PRACTICE: prefer "javascript:;" as easier to handle and more readable version 9094 } else if( $this.attr( 'href' ) === '#' ) { 9095 e.preventDefault(); 9096 } 9097 }); 9098 9099 $('.fullscreen-navigation-ul .menu-sub-level-arrow').on('click', function(){ 9100 $(this).siblings('.sub-menu').slideToggle(); 9101 }); 9102 9103}(jQuery)); 9104(function($) { 9105 'use strict'; 9106 9107 /** 9108 * Mega menu 9109 */ 9110 var $navList = $(".main-navigation-ul"); 9111 var megaMenu = function megaMenu() { 9112 9113 $navList.MegaMenu({ 9114 type: "vertical", 9115 delay: 200 9116 }); 9117 }; 9118 9119 $(window).on('load', megaMenu); 9120 9121}(jQuery)); 9122(function($) { 9123 'use strict'; 9124 9125 /** 9126 * One pager menu hash update. 9127 * Smooth scroll is appended globally whenever the click element has corresponding #el 9128 */ 9129 var onePageNavItem = function onePageNavItem() { 9130 var $this = $( this ), 9131 link = $this.find( 'a' ), 9132 anchor = MK.utils.detectAnchor( link ); // anchor on current page 9133 9134 if( !anchor.length ) return; 9135 9136 $this.removeClass( 'current-menu-item current-menu-ancestor current-menu-parent' ); 9137 9138 var activeNav = function( state ) { 9139 return function() { 9140 $this[ state ? 'addClass' : 'removeClass' ]( 'current-menu-item' ); 9141 window.history.replaceState( undefined, undefined, [ state ? anchor : ' ' ] ); 9142 }; 9143 }; 9144 9145 MK.utils.scrollSpy( $( anchor )[0], { 9146 before : activeNav( false ), 9147 active : activeNav( true ), 9148 after : activeNav( false ), 9149 }); 9150 }; 9151 9152 var $navItems = $('.js-main-nav').find( 'li' ); 9153 9154 $(window).on('load', function() { 9155 // Wait with spying anchors so we do not assign anchor that is browser scroll to after page load 9156 // Especially when there are anchors on top - refreshing page can cause grabbing one of them into url 9157 // and force unwanted scroll 9158 setTimeout(function() { 9159 $navItems.each( onePageNavItem ); 9160 }, 1000); 9161 }); 9162 9163}(jQuery)); 9164(function($) { 9165 'use strict'; 9166 9167 var $window = $(window); 9168 var $body = $('body'); 9169 var $resMenuWrap = $('.mk-responsive-wrap'); 9170 var $post_nav = $('.mk-post-nav'); 9171 var $toolbar = $('.mk-header-toolbar'); 9172 var $resMenuLink = $('.mk-nav-responsive-link'); 9173 9174 // Flags 9175 var hasResMenu = ($resMenuWrap.length > 0); 9176 9177 //initial window and screen height 9178 var windowHeight = $window.height(); 9179 var screenHeight = screen.height; 9180 9181 // We keep this handler above hasResMenu flag. 9182 // Even if our header doesn't contain droppable responsive menu (in favor of fullscreen or side menu) 9183 // we still transform tollbar into collapsible menu part in responsive state 9184 $('.mk-toolbar-resposnive-icon').on('click', function(e) { 9185 e.preventDefault(); 9186 console.log('clicked'); 9187 if ($body.hasClass('toolbar-opened')) { 9188 $body.removeClass('toolbar-opened').addClass('toolbar-closed'); 9189 $toolbar.hide(); 9190 } else { 9191 $body.removeClass('toolbar-closed').addClass('toolbar-opened'); 9192 $toolbar.show(); 9193 } 9194 }); 9195 9196 9197 if ( ! hasResMenu && ! $('.vc_mk_header') ) return; 9198 9199 function toggleResMenu(e) { 9200 e.preventDefault(); 9201 var $this = $(this); 9202 var $headerInner = $this.parents('header'); 9203 var $resMenu = $headerInner.find('.mk-responsive-wrap'); 9204 var searchBox = $('.responsive-searchform .text-input'); 9205 var adminBarHeight = $('#wpadminbar').height(); /* Fix AM-1918 */ 9206 9207 if ($body.hasClass('mk-opened-nav')) { 9208 $this.removeClass('is-active'); 9209 $body.removeClass('mk-opened-nav').addClass('mk-closed-nav').trigger('mk-closed-nav'); 9210 $resMenu.hide(); 9211 $post_nav.removeClass('post-nav-backward'); 9212 } else { 9213 $this.addClass('is-active'); 9214 $body.removeClass('mk-closed-nav').addClass('mk-opened-nav').trigger('mk-opened-nav'); 9215 $resMenu.show(); 9216 $post_nav.addClass('post-nav-backward'); 9217 9218 } 9219 9220 //for iPhone 5 focus bug , remove search box focused class 9221 if(searchBox.hasClass('input-focused')){ 9222 searchBox.removeClass('input-focused'); 9223 } 9224 9225 } 9226 9227 $resMenuLink.each(function() { 9228 $(this).on('click', toggleResMenu); 9229 }); 9230 9231 $( window ).on( 'vc_reload', function () { 9232 $('.vc_mk_header .mk-nav-responsive-link').each(function() { 9233 $(this).on('click', toggleResMenu); 9234 }); 9235 } ) 9236 9237 var setResMenuHeight = function() { 9238 var height = $window.height() - MK.val.offsetHeaderHeight(0); 9239 $resMenuWrap.css('max-height', height); 9240 }; 9241 9242 // check if device virtual keyboard is active 9243 var isVirtualKeyboard = function() { 9244 var currentWindowHeight = $window.height(); 9245 var currentScreenHeight = screen.height; 9246 var searchBox = $('.responsive-searchform .text-input'); 9247 var searchBoxIsFocused = false; 9248 9249 //for iPhone 5 focus bug , add class for detect focus state 9250 searchBox.on('touchstart touchend', function(e) { 9251 searchBox.addClass('input-focused'); 9252 }); 9253 9254 searchBoxIsFocused = (searchBox.is(':focus') || searchBox.hasClass("input-focused")); 9255 9256 if ($body.hasClass('mk-opened-nav') && searchBoxIsFocused && currentScreenHeight == screenHeight && currentWindowHeight != windowHeight) { 9257 return true; 9258 } else { 9259 return false;
9260 } 9261 }; 9262 9263 var hideResMenu = function hideResMenu() { 9264 if (MK.utils.isResponsiveMenuState()) { 9265 9266 //when search box in responsive menu is focused , window resize fired but at this time responsive menu should be open 9267 if (!isVirtualKeyboard()) { 9268 // hide toggled menu and its states 9269 if ($body.hasClass('mk-opened-nav')) { 9270 $resMenuLink.filter('.is-active').trigger('click'); 9271 } 9272 // hide menu wrapper 9273 $resMenuWrap.hide(); 9274 9275 } 9276 } 9277 }; 9278 9279 $resMenuWrap.on('click', 'a', hideResMenu); 9280 9281}(jQuery)); 9282 9283(function($) { 9284 'use strict'; 9285 9286 var $header = $('.mk-header'); 9287 var hasHeader = ($header.length > 0); 9288 9289 if(!hasHeader && ! $('.vc_mk_header') ) return; 9290 9291 var $sticky_style = $header.attr('data-header-style'); 9292 9293 //if ($sticky_style !== 3) return; 9294 9295 $('.sidedash-navigation-ul > li').each(function() { 9296 var $this = $(this); 9297 9298 $this.children('ul').siblings('a').after('<span class="mk-nav-arrow mk-nav-sub-closed"><svg class="mk-svg-icon" data-name="mk-moon-arrow-down" data-cacheid="2" style=" height:14px; width: 14px; " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M512 192l-96-96-160 160-160-160-96 96 256 255.999z"></path></svg></span>'); 9299 }); 9300 9301 function toggleSubMenu(e) { 9302 e.preventDefault(); 9303 var $this = $(this); 9304 9305 if ($this.hasClass('mk-nav-sub-closed')) { 9306 $this.siblings('ul').slideDown(450).end().removeClass('mk-nav-sub-closed').addClass('mk-nav-sub-opened'); 9307 } else { 9308 $this.siblings('ul').slideUp(450).end().removeClass('mk-nav-sub-opened').addClass('mk-nav-sub-closed'); 9309 } 9310 }; 9311 9312 function toggleFullMenu(e) { 9313 e.preventDefault(); 9314 var $this = $(this), 9315 $body = $('body'), 9316 $fullscreen_box = $('.mk-fullscreen-nav'); 9317 9318 if ($this.hasClass('dashboard-style')){ 9319 if (!$this.hasClass('dashboard-active')) { 9320 $this.addClass('dashboard-active'); 9321 $body.addClass('dashboard-opened'); 9322 } else { 9323 $this.removeClass('dashboard-active'); 9324 $body.removeClass('dashboard-opened'); 9325 } 9326 }else if($this.hasClass('fullscreen-style')){ 9327 if (!$this.hasClass('fullscreen-active')) { 9328 $this.addClass('fullscreen-active'); 9329 $body.addClass('fullscreen-nav-opened'); 9330 $fullscreen_box.addClass('opened'); 9331 // MK.utils.scroll.disable(); 9332 } else { 9333 $this.removeClass('fullscreen-active'); 9334 $body.removeClass('fullscreen-nav-opened'); 9335 $fullscreen_box.removeClass('opened'); 9336 } 9337 } 9338 } 9339 9340 $('.mk-nav-arrow').each(function() { 9341 $(this).stop(true).on('click', toggleSubMenu); 9342 }); 9343 9344 $('.mk-dashboard-trigger').each(function() { 9345 $(this).on('click', toggleFullMenu); 9346 }); 9347 9348 $( window ).on( 'vc_reload', function () { 9349 $('.vc_mk_header .mk-dashboard-trigger').each(function() { 9350 $(this).on('click', toggleFullMenu); 9351 }); 9352 9353 $('.vc_mk_header .mk-nav-arrow').each(function() { 9354 $(this).stop(true).on('click', toggleSubMenu); 9355 }); 9356 } ); 9357 9358 $('html').on('click', function() { 9359 $('body').removeClass('dashboard-opened'); 9360 $('.mk-dashboard-trigger').removeClass('dashboard-active'); 9361 }); 9362 9363}(jQuery)); 9364 9365(function($) { 9366 'use strict'; 9367 9368 /** 9369 * Vertical menu 9370 */ 9371 var $verticalMenu = $('#mk-vm-menu'); 9372 var verticalMenu = function verticalMenu() { 9373 if(!$verticalMenu.data('vertical-menu') && !MK.utils.isResponsiveMenuState()) { 9374 $verticalMenu.dlmenu(); 9375 $verticalMenu.data('vertical-menu', true); 9376 } 9377 }; 9378 9379 verticalMenu(); 9380 $(window).on('resize', verticalMenu); 9381 9382}(jQuery)); 9383(function($) { 9384 'use strict'; 9385 9386 // WPML 9387 var $lang_item = $('.mk-main-navigation > .main-navigation-ul > .menu-item-language'); 9388 $lang_item.addClass('no-mega-menu').css('visibility', 'visible'); 9389 $('.mk-main-navigation .menu-item-language > a').addClass('menu-item-link'); 9390 9391})(jQuery); 9392(function($) { 9393 'use strict'; 9394 9395 var $header = $( '.mk-header' ).first(); // Theme header is always first, do not apply to shortcode headers. 9396 var hasHeader = ($header.length > 0); 9397 9398 if(!hasHeader) return; 9399 9400 var $window = $( window ); 9401 var $document = $( document ); 9402 var $headerHolder = $header.find( '.mk-header-holder' ); 9403 var $paddingWrapper = $header.find('.mk-header-padding-wrapper'); 9404 var config = $header.data(); 9405 9406 /** 9407 * Flags 9408 * @type {Boolean} 9409 */ 9410 var isStickyLazy = (config.stickyStyle === 'lazy'); 9411 var isStickyFixed = (config.stickyStyle === 'fixed'); 9412 var isStickySlide = (config.stickyStyle === 'slide'); 9413 9414 function isSticky() { // Check for sticky compatibility 9415 //return config.headerStyle !== 4; header style 4 needs sticky state for transparent header. 9416 return true; 9417 } 9418
9419 function isColorable() { // Check for coloring compatibility 9420 // TODO make it explicit in DOM that header is transparent as this is only scenario for colorable header 9421 // Monkey patch - exclude header styles that don't fit colorable 9422 return config.headerStyle !== 4; 9423 } 9424 9425 9426 /** 9427 * Change header skin 9428 */ 9429 function changeSkin( e, skin ) { 9430 $header.attr( 'data-transparent-skin', skin ); 9431 // Fix for class based skining 9432 var contrast = skin === 'light' ? 'dark' : 'light'; 9433 $header.addClass(skin + '-skin'); 9434 $header.removeClass(contrast + '-skin'); 9435 } 9436 9437 if(isColorable()) MK.utils.eventManager.subscribe( 'firstElSkinChange', changeSkin ); 9438 9439 9440 // Assign sticky scenarions 9441 if (isSticky() && isStickyLazy) { 9442 if(config.headerStyle !== 2) { 9443 lazySticky(); 9444 } 9445 } 9446 else if (isSticky() && isStickyFixed) fixedSticky(); 9447 else if (isSticky() && isStickySlide) slideSticky(); 9448 9449 /** 9450 * Sticky header behavior: Lazy 9451 */ 9452 function lazySticky() { 9453 var elClassHidden = 'header--hidden'; 9454 var elClassSticky = 'a-sticky'; 9455 var wScrollCurrent = 0; 9456 var wScrollBefore = 0; 9457 var wScrollDiff = 0; 9458 var wHeight = 0; 9459 var dHeight = 0; 9460 9461 var setSizes = function setSizes() { 9462 dHeight = $document.height(); 9463 wHeight = $window.height(); 9464 }; 9465 9466 var onScroll = function onScroll() { 9467 wScrollCurrent = MK.val.scroll(); 9468 wScrollDiff = wScrollBefore - wScrollCurrent; 9469 9470 if( wScrollCurrent <= 0 ) { // scrolled to the very top; element sticks to the top 9471 $headerHolder.removeClass( elClassHidden ); 9472 $header.removeClass( elClassSticky ); 9473 $('body').trigger('mk:header-unsticky'); 9474 9475 } else if( wScrollDiff > 0 && $headerHolder.hasClass( elClassHidden ) ) { // scrolled up; element slides in 9476 $headerHolder.removeClass( elClassHidden ); 9477 $header.addClass( elClassSticky ); 9478 $('body').trigger('mk:header-sticky'); 9479 9480 } else if( wScrollDiff < 0 ) { // scrolled down 9481 9482 if( wScrollCurrent + wHeight >= dHeight && $headerHolder.hasClass( elClassHidden ) ) { // scrolled to the very bottom; element slides in 9483 $headerHolder.removeClass( elClassHidden ); 9484 $header.addClass( elClassSticky ); 9485 $('body').trigger('mk:header-sticky'); 9486 } else { // scrolled down; element slides out 9487 $headerHolder.addClass( elClassHidden ); 9488 $header.removeClass( elClassSticky ); 9489 $('body').trigger('mk:header-unsticky'); 9490 } 9491 } 9492 9493 wScrollBefore = wScrollCurrent; 9494 }; 9495 9496 setSizes(); 9497 onScroll(); 9498 $window.on( 'resize', MK.utils.throttle( 100, setSizes ) ); 9499 $window.on( 'scroll', MK.utils.throttle( 500, onScroll ) ); 9500 } 9501 9502 9503 /** 9504 * Sticky header behavior: Fixed 9505 */ 9506 function fixedSticky() { 9507 var sticked = false; 9508 var scrollPos; 9509 9510 var toggleState = function toggleState() { 9511 scrollPos = MK.val.scroll() + MK.val.adminbarHeight(); 9512 9513 if( (scrollPos > MK.val.stickyOffset() ) && ! MK.utils.isResponsiveMenuState() ) { 9514 if(sticked) return; // stop if already sticked 9515 $header.addClass('a-sticky'); 9516 sticked = true; 9517 $('body').trigger('mk:header-sticky'); 9518 } else { 9519 if(!sticked) return; // stop if already unsticked 9520 $header.removeClass('a-sticky'); 9521 sticked = false; 9522 $('body').trigger('mk:header-unsticky'); 9523 } 9524 }; 9525 9526 toggleState(); 9527 $window.on( 'scroll', MK.utils.throttle( 100, toggleState) ); 9528 $window.on( 'resize', MK.utils.throttle( 100, toggleState) ); 9529 } 9530 9531 9532 /** 9533 * Sticky header behavior: Slide 9534 */ 9535 function slideSticky() { 9536 var sticked = false;
9537 var onScroll = function onScroll() { 9538 if (MK.val.scroll() > MK.val.stickyOffset()) { 9539 if(sticked) return; // stop if already sticked 9540 $header.addClass('pre-sticky'); 9541 $paddingWrapper.addClass('enable-padding'); 9542 setTimeout(function() { 9543 $header.addClass('a-sticky'); 9544 $('body').trigger('mk:header-sticky'); 9545 }, 1); 9546 sticked = true; 9547 } else { 9548 if(!sticked) return; // stop if already unsticked 9549 $header.removeClass('a-sticky'); 9550 $header.removeClass('pre-sticky'); 9551 $paddingWrapper.removeClass('enable-padding'); 9552 sticked = false; 9553 $('body').trigger('mk:header-unsticky'); 9554 } 9555 }; 9556 9557 onScroll(); 9558 $window.on( 'scroll', MK.utils.throttle( 100, onScroll) ); 9559 } 9560 9561 // TODO 9562 // var pageIntro = $('body').data('intro'); // block scrolling on page intro 9563 9564 9565})( jQuery ); 9566 9567(function($){ 9568 'use strict'; 9569 9570 // Do not assign at all if no touch events 9571 var hasTouchscreen = ('ontouchstart' in document.documentElement); 9572 if(!hasTouchscreen) return; 9573 9574 $('.mk-main-navigation .menu-item-has-children').each( normalizeClick ); 9575 9576 function normalizeClick() { 9577 $(this).on('click', handleClick); 9578 } 9579 9580 // Most reasonable way to normalize click and let hover state on first touch yet don't break experience on multiple input devices is to actually check against desired effect. 9581 // Better way would be to check against expected state but JS doesn't detect :hover so it would be nice to have it normalized globally like expecting .hover class in css 9582 function handleClick(e) { 9583 var $this = $(e.currentTarget); 9584 var $child = $this.find('> ul'); 9585 var isVisible = $child.css('display') !== 'none'; 9586 9587 if(!isVisible) { 9588 e.preventDefault(); 9589 e.stopPropagation(); 9590 } 9591 } 9592 9593}(jQuery)); 9594(function( $ ) { 9595 'use strict'; 9596 9597 MK.ui.preloader = { 9598 dom : { 9599 overlay: '.mk-body-loader-overlay' 9600 }, 9601 9602 hide : function hide() { 9603 $( this.dom.overlay ).fadeOut(600, "easeInOutExpo", function() { 9604 $('body').removeClass('loading'); 9605 //$( this ).remove(); 9606 }); 9607 } 9608 }; 9609 9610})( jQuery ); 9611(function($) { 9612 'use strict'; 9613 9614 var _ajaxUrl = MK.core.path.ajaxUrl; 9615 var _instances = {}; 9616 9617 MK.utils.ajaxLoader = function ajaxLoader(el) { 9618 // retrun a cached instance to have control over state from within multiple places 9619 // we may need for example to reset pageId when do filtering. It is really one instance that controls both filtering and pagination / load more 9620 var id = '#' + ($(el).attr('id')); 9621 if(typeof _instances[id] !== 'undefined') return _instances[id]; 9622 9623 // else lets start new instance 9624 this.id = id; 9625 this.el = el; 9626 this.isLoading = false; 9627 this.xhrCounter = 0; 9628 }; 9629 9630 MK.utils.ajaxLoader.prototype = { 9631 init: function init() { 9632 // prevent double initialization of we return an instance 9633 if ( this.initialized && typeof window.vc_iframe === 'undefined' ) { 9634 return; 9635 } 9636 9637 this.createInstance(); 9638 this.cacheElements(); 9639 9640 this.initialized = true; 9641 }, 9642 9643 cacheElements: function cacheElements() { 9644 this.$container = $(this.el); 9645 this.id = '#' + (this.$container.attr('id')); 9646 this.categories = this.$container.data('loop-categories'); 9647 9648 this.data = {}; 9649 this.data.action = 'mk_load_more'; 9650 this.data.query = this.$container.data('query'); 9651 this.data.atts = this.$container.data('loop-atts'); 9652 this.data.loop_iterator = this.$container.data('loop-iterator'); 9653 this.data.author = this.$container.data('loop-author'); 9654 this.data.posts = this.$container.data('loop-posts'); 9655 this.data.safe_load_more = this.$container.siblings('#safe_load_more').val(); 9656 this.data._wp_http_referer = this.$container.siblings('input[name="_wp_http_referer"]').val(); 9657 this.data.paged = 1; 9658 this.data.maxPages = this.$container.data('max-pages'); 9659 this.data.term = this.categories; 9660 }, 9661 9662 createInstance: function() { 9663 _instances[this.id] = this; 9664 }, 9665 9666 load: function load(unique) { 9667 var self = this; 9668 var seq = ++this.xhrCounter; 9669 this.isLoading = true; 9670 9671 // If mk-ajax-loaded-posts span exists, get the post ids 9672 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 9673 var loaded_posts = this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts'); 9674
9675 // Do not send looaded posts for Classic Pagination Navigation 9676 if ( this.$container.attr('data-pagination-style') != 1 ) { 9677 self.data.loaded_posts = loaded_posts.split(','); 9678 } 9679 } 9680 9681 return $.when( 9682 $.ajax({ 9683 url : _ajaxUrl, 9684 type : "POST", 9685 data : self.data 9686 }) 9687 ).done(function(response) { 9688 self.onDone(response, unique, seq); 9689 }); 9690 }, 9691 9692 onDone: function(response, unique, seq) { 9693 if(seq === this.xhrCounter) { 9694 var self = this; 9695 9696 response = $.parseJSON(response); 9697 response.unique = unique; 9698 response.id = this.id; 9699 9700 // If mk-ajax-loaded-posts span exists, update current post ids 9701 // with new post ids from server's response 9702 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 9703 this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', response.loaded_posts); 9704 } 9705 9706 this.setData({ 9707 maxPages: response.maxPages, 9708 found_posts: response.found_posts, 9709 loop_iterator: response.i 9710 }); 9711 9712 // Preload images first by creating object from returned content. 9713 // mk_imagesLoaded() method will create a promise that gets resolved when all images inside are loaded. 9714 // Our ajaxLoad is somehow more similar to window.onload event now. 9715 $(response.content).mk_imagesLoaded().then(function() { 9716 MK.utils.eventManager.publish('ajaxLoaded', response); 9717 self.isLoading = false; 9718 self.initNewComponents(); 9719 }); 9720 9721 } else console.log('XHR request nr '+ seq +' aborted'); 9722 9723 }, 9724 9725 setData: function setData(atts) { 9726 for(var att in atts) { 9727 if(att === 'term' && atts[att] === '*') this.data.term = ''; 9728 else this.data[att] = atts[att]; 9729 } 9730 }, 9731 9732 getData: function getData(att) { 9733 return this.data[att]; 9734 }, 9735 9736 initNewComponents: function initNewComponents() { 9737 // Legacy scripts reinit 9738 window.ajaxInit(); 9739 setTimeout(window.ajaxDelayedInit, 1000); 9740 // New way to init apended things 9741 MK.core.initAll(this.el); 9742 } 9743 }; 9744 9745}(jQuery)); 9746MK.component.BackgroundImageSetter = (function ($) { 9747 9748 'use strict'; 9749 9750 var module = {}; 9751 9752 9753 /*---------------------------------------------------------------------------------*/ 9754 /* Private Variables 9755 /*---------------------------------------------------------------------------------*/ 9756 9757 /** 9758 * Take all elements with data-mk-img-set attribute and evaluate best image according to given device orientation and resolution, 9759 * sets style for backround-image on the same node element. * 9760 */ 9761 9762 var $win = $(window), 9763 // $layers = $('[data-mk-img-set]'), 9764 screen = getScreenSize(), 9765 orientation = getOrientation(), 9766 device = getDevice(), 9767 lastOrientation = orientation, 9768 lastDevice = device; 9769 9770 9771 /*---------------------------------------------------------------------------------*/ 9772 /* Private Methods 9773 /*---------------------------------------------------------------------------------*/ 9774 9775 function run($layers) { 9776 $layers.filter( function() { 9777 return !this.hasAttribute("mk-img-loaded"); 9778 }).each(applyBg); 9779 } 9780 9781 // Keep our main side effect out of calculations so they can be run once before loop of applying bg as a result 9782 function applyBg() { 9783 var $this = $(this), 9784 imgs = $this.data('mk-img-set'); 9785 9786 $this.css('background-image', 'url('+ module.getImage(imgs) +')'); 9787 $this.find('.mk-adaptive-image').attr('src', module.getImage(imgs)); 9788 } 9789 9790 // Keep track of current screen size while resizing but update device reference 9791 // and reapply backgrounds only when we discover switch point 9792 function handleResize($layers) { 9793 updateScreenSize(); 9794 if(hasSwitched()) { 9795 updateDevice(); 9796 run($layers); 9797 } 9798 } 9799 9800 function getScreenSize() { 9801 return { 9802 w: $win.width(), 9803 h: $win.height() 9804 }; 9805 } 9806 9807 // Name our device classes and add them id which simply means which one is wider 9808 function getDevice() { 9809 if (screen.w > 1024) return {class: 'desktop', id: 2}; 9810 else if(screen.w > 736) return {class: 'tablet', id: 1}; 9811 else return {class: 'mobile', id: 0}; 9812 } 9813 9814 function getOrientation() { 9815 if(screen.w > screen.h) return 'landscape'; 9816 else return 'portrait'; 9817 } 9818 9819 function updateScreenSize() { 9820 screen = getScreenSize(); 9821 } 9822 9823 function updateDevice() { 9824 if(lastOrientation !== orientation) orientation = lastOrientation; 9825 // Switch device only if going from smaller size to bigger. 9826 // Bigger to smaller is perfectly handled by browsers and doesn't require change and reupload 9827 if(lastDevice.id > device.id) device = lastDevice; 9828 } 9829 9830 function hasSwitched() { 9831 lastOrientation = getOrientation(); 9832 lastDevice = getDevice(); 9833 9834 if(lastOrientation !== orientation || lastDevice.class !== device.class) return true; 9835 else return false;
9836 } 9837 9838 9839 /*---------------------------------------------------------------------------------*/ 9840 /* Public Methods 9841 /*---------------------------------------------------------------------------------*/ 9842 9843 // As desired image might be not available we have to evaluate the best match. 9844 module.getImage = function (imgs) { 9845 if (imgs['responsive'] === 'false') { 9846 return (imgs['landscape']['desktop']) ? imgs['landscape']['desktop'] : (imgs['landscape']['external'] ? imgs['landscape']['external'] : ''); 9847 9848 } 9849 var hasOrientation = !!imgs[orientation]; 9850 // there are only two orientations now and we may get them by string name if both are there 9851 // or by index of 0 if only one is available. Note Objects has no lexical order so we need to grab key name by its index. 9852 // Also we may have external file for each orientation which we don't scale internaly so we grab it as it is. If nothing found return an empty string 9853 var imgOriented = imgs[ (hasOrientation ? orientation : Object.keys(imgs)[0]) ], 9854 imgExact = (imgOriented[device.class]) ? imgOriented[device.class] : (imgOriented['external'] ? imgOriented['external'] : ''); 9855 return imgExact; 9856 } 9857 9858 module.init = function ($layers) { 9859 9860 // Run and bind 9861 run($layers); 9862 $layers.attr('mk-img-loaded', ''); 9863 }; 9864 9865 module.onResize = function ($layers) { 9866 $win.on('resize', MK.utils.throttle( 500, function() { 9867 handleResize($layers); 9868 })); 9869 }; 9870 9871 return module; 9872 9873}(jQuery)); 9874 9875 9876jQuery(function($) { 9877 9878 var init = function init() { 9879 // Get All Layers, Excluding Edge Slider and Page Section 9880 $allLayers = $('[data-mk-img-set]').filter(function(index) { 9881 return !$(this).hasClass('mk-section-image') && !$(this).hasClass('background-layer') && !$(this).hasClass('mk-video-section-touch'); 9882 });; 9883 9884 // Handle the resize 9885 MK.component.BackgroundImageSetter.onResize($allLayers); 9886 9887 // Set all the BG Layers 9888 MK.component.BackgroundImageSetter.init($allLayers); 9889 } 9890 init(); 9891 9892 $(window).on('vc_reload', init); 9893 9894}); 9895 9896(function( $ ) { 9897 'use strict'; 9898 9899 var val = MK.val; 9900 9901 MK.component.FullHeight = function( el ) { 9902 var $window = $( window ), 9903 $this = $( el ), 9904 config = $this.data( 'fullheight-config' ), 9905 container = document.getElementById( 'mk-theme-container' ), 9906 minH = (config && config.min) ? config.min : 0, 9907 winH = null, 9908 height = null, 9909 update_count = 0, 9910 testing = MK.utils.getUrlParameter('testing'), 9911 offset = null; 9912 9913 // We need to provide height on the same specificity level for workaround to IE bug 9914 // connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview 9915 // stackoverflow.com/questions/19371626/flexbox-not-centering-vertically-in-ie 9916 if(MK.utils.browser.name === ('IE' || 'Edge')) $this.css( 'height', '1px' ); 9917 9918 var update = function() { 9919 9920 if(update_count === 0) { 9921 winH = $window.height(); 9922 // for correct calculate 9923 offset = $this.offset().top - 1; 9924 height = Math.max(minH, winH - val.offsetHeaderHeight( offset )); 9925 $this.css( 'min-height', height ); 9926 if(testing !== undefined ) 9927 update_count++; 9928 } 9929 9930 }; 9931 9932 // TODO remove scroll listener by dynamic offset reader 9933 var init = function() { 9934 update(); 9935 $window.on( 'resize', update ); 9936 $window.on( 'scroll', update ); 9937 window.addResizeListener( container, update ); 9938 }; 9939 9940 return { 9941 init : init 9942 }; 9943 }; 9944 9945})( jQuery ); 9946 9947 9948(function( $ ) { 9949 'use strict'; 9950 9951 var core = MK.core, 9952 utils = MK.utils, 9953 path = MK.core.path; 9954 9955 9956 MK.ui.FullScreenGallery = function( element, settings ) { 9957 this.element = element; 9958 this.config = settings; 9959 9960 this.isFullScreen = false; 9961 }; 9962 9963 9964 // preload slick PLUGIN TO USE THIS 9965 MK.ui.FullScreenGallery.prototype = { 9966 dom : { 9967 fullScrBtn : '.slick-full-screen', 9968 exitFullScrBtn : '.slick-minimize', 9969 playBtn : '.slick-play', 9970 pauseBtn : '.slick-pause', 9971 shareBtn : '.slick-share', 9972 socialShare : '.slick-social-share', 9973 wrapper : '.slick-slider-wrapper', 9974 slider : '.slick-slides', 9975 slides : '.slick-slide', 9976 dots : '.slick-dot', 9977 active : '.slick-active', 9978 hiddenClass : 'is-hidden', 9979 dataId : 'slick-index' 9980 }, 9981 9982 tpl: { 9983 dot : '<div class="slick-dot"></div>', 9984 next : '<a href="javascript:;" class="slick-next"> <svg width="33px" height="65px"> <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points=" 0.5,0.5 32.5,32.5 0.5,64.5"/> </svg> </a>', 9985 prev : '<a href="javascript:;" class="slick-prev"> <svg width="33px" height="65px"> <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points=" 32.5,64.5 0.5,32.5 32.5,0.5"/> </svg> </a>' 9986 }, 9987 9988 init : function() { 9989 var self = this; 9990 9991 // core.loadDependencies([ path.plugins + 'slick.js' ], function() { 9992 self.cacheElements(); 9993 self.getViewportSizes(); 9994 self.updateSizes( 'window' ); 9995 self.create(); 9996 // update cache with elements propagated by plugin 9997 self.updateCacheElements(); 9998 self.createPagination(); 9999 self.bindEvents(); 10000 // }); 10001 }, 10002 10003 create : function() { 10004 var self = this; 10005 10006 this.slick = this.$gallery.slick({ 10007 dots: true, 10008 arrows: true, 10009 infinite: true, 10010 speed: 300, 10011 slidesToShow: 1, 10012 centerMode: true, 10013 centerPadding: '0px', 10014 variableWidth: true, 10015 autoplay: false, 10016 autoplaySpeed: 3000, 10017 useTransform: true, 10018 prevArrow: self.tpl.prev, 10019 nextArrow: self.tpl.next, 10020 customPaging: function(slider, i) { 10021 return self.tpl.dot; 10022 }, 10023 }); 10024 }, 10025 10026 cacheElements : function() { 10027 this.$window = $( window ); 10028 this.$gallery = $( this.element ); 10029 10030 this.$fullScrBtn = $( this.dom.fullScrBtn ); 10031 this.$exitFullScrBtn = $( this.dom.exitFullScrBtn ); 10032 this.$playBtn = $( this.dom.playBtn ); 10033 this.$pauseBtn = $( this.dom.pauseBtn ); 10034 this.$shareBtn = $( this.dom.shareBtn ); 10035 this.$socialShare = $( this.dom.socialShare ); 10036 10037 this.$wrapper = $( this.dom.wrapper ); 10038 this.$slider = $( this.dom.slider ); 10039 this.$slides = $( this.dom.slides ); 10040 this.$imgs = this.$slides.find( 'img' ); 10041 // store reference to initial images without slides appended by pugin 10042 // - needed for creating of pagination 10043 this.$originalImgs = this.$imgs; 10044 }, 10045 10046 updateCacheElements : function() { 10047 this.$slides = $( this.dom.slides ); 10048 this.$imgs = this.$slides.find( 'img' ); 10049 this.$dots = $( this.dom.dots ); 10050 }, 10051 10052 bindEvents : function() { 10053 var self = this; 10054 this.$fullScrBtn.on( 'click', this.toFullScreen.bind( this ) ); 10055 this.$exitFullScrBtn.on( 'click', this.exitFullScreen.bind( this ) ); 10056 this.$playBtn.on( 'click', this.play.bind( this ) ); 10057 this.$pauseBtn.on( 'click', this.pause.bind( this ) ); 10058 this.$shareBtn.on( 'click', this.toggleShare.bind( this ) ); 10059 this.$socialShare.on( 'click', 'a', this.socialShare.bind( this ) ); 10060 this.$window.on( 'resize', this.onResize.bind( this ) ); 10061 this.$window.on( 'keydown', function(e) { 10062 if(e.keyCode === 39) self.$gallery.slick('slickNext'); 10063 if(e.keyCode === 37) self.$gallery.slick('slickPrev'); 10064 }); 10065 $( document ).on( 'fullscreenchange mozfullscreenchange webkitfullscreenchange msfullcreenchange', this.exitFullScreen.bind( this ) ); 10066 }, 10067 10068 getViewportSizes : function() { 10069 this.screen = { 10070 w: screen.width, 10071 h: screen.height 10072 }; 10073 this.window = { 10074 w: this.$window.width(), 10075 h: this.$window.height() 10076 }; 10077 }, 10078 10079 updateSizes : function( viewport ) { 10080 this.$wrapper.width( this[ viewport ].w ); 10081 this.$wrapper.height( '100%' ); 10082 this.$imgs.height( '100%'); 10083 }, 10084 10085 createPagination : function() { 10086 var self = this; 10087 this.$dots.each( function( i ) { 10088 var img = self.$originalImgs.eq( i ).attr( 'src' ); 10089 10090 $( this ).css({ 10091 'background-image': 'url('+ img +')' 10092 }); 10093 }); 10094 }, 10095 10096 play : function(e) { 10097 e.preventDefault(); 10098 this.$playBtn.addClass( this.dom.hiddenClass ); 10099 this.$pauseBtn.removeClass( this.dom.hiddenClass ); 10100 $( this.element ).slick( 'slickPlay' ); 10101 }, 10102 10103 pause : function(e) { 10104 e.preventDefault(); 10105 this.$pauseBtn.addClass( this.dom.hiddenClass ); 10106 this.$playBtn.removeClass( this.dom.hiddenClass ); 10107 $( this.element ).slick( 'slickPause' ); 10108 }, 10109 10110 toggleShare : function(e) { 10111 e.preventDefault(); 10112 this.$socialShare.toggleClass( this.dom.hiddenClass ); 10113 }, 10114 10115 getCurentId : function() { 10116 return this.$slides.filter( this.dom.active ).data( this.dom.dataId ); 10117 }, 10118 10119 toFullScreen : function() { 10120 var self = this; 10121 10122 this.$fullScrBtn.addClass( this.dom.hiddenClass ); 10123 this.$exitFullScrBtn.removeClass( this.dom.hiddenClass ); 10124 10125 this.$slider.hide().fadeIn( 500 ); 10126 utils.launchIntoFullscreen( document.documentElement ); 10127 this.updateSizes( 'screen' ); 10128 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10129 10130 // Update state with delay so we avoid triggering exitFullScreen fn from 10131 // fullscreenchange event 10132 setTimeout( function() { 10133 self.isFullScreen = true; 10134 }, 1000); 10135 }, 10136 10137 exitFullScreen : function() { 10138 if( this.isFullScreen ) { 10139 this.$exitFullScrBtn.addClass( this.dom.hiddenClass ); 10140 this.$fullScrBtn.removeClass( this.dom.hiddenClass ); 10141 10142 utils.exitFullscreen(); 10143 this.updateSizes( 'window' ); 10144 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10145 10146 this.isFullScreen = false;
10147 } 10148 10149 }, 10150 10151 onResize : function() { 10152 this.getViewportSizes(); 10153 this.updateSizes( this.isFullScreen ? 'screen' : 'window' ); 10154 $( this.element ).slick( 'refresh' ); 10155 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10156 this.updateCacheElements(); 10157 this.createPagination(); 10158 }, 10159 10160 socialShare : function( e ) { 10161 e.preventDefault(); 10162 var $this = $( e.currentTarget ), 10163 network = $this.data( 'network' ), 10164 id = this.config.id, 10165 url = this.config.url, 10166 title = this.$wrapper.find( '.slick-title' ).text(), 10167 name; 10168 var picture = this.$slides.filter( this.dom.active ).children().first().attr( 'src' ); 10169 switch( network ) { 10170 case 'facebook': 10171 url = 'https://www.facebook.com/sharer/sharer.php?picture=' + picture+'&u=' + url + '#id=' + id; 10172 name = 'Facebook Share'; 10173 break; 10174 case 'twitter': 10175 url = 'http://twitter.com/intent/tweet?text=' + url + '#id=' + id; 10176 name = 'Twitter Share'; 10177 break; 10178 case 'pinterest': 10179 url = 'http://pinterest.com/pin/create/bookmarklet/?media=' + picture + '&url=' + url + '&is_video=false&description=' + title; 10180 // other available link paranmeters: media, description 10181 name = 'Pinterest Share'; 10182 break; 10183 10184 } 10185 10186 window.open( url, name, "height=380 ,width=660, resizable=0, toolbar=0, menubar=0, status=0, location=0, scrollbars=0" ); 10187 } 10188 }; 10189 10190})( jQuery ); 10191(function( $ ) { 10192 'use strict'; 10193 10194 /** 10195 * A fork from original VC function. 10196 * The original one is adding some padding which causes extra padding 10197 * on our templates so we customized the codes. 10198 * 10199 * @since 5.9.8 10200 * @since 6.0.1 Improve logic to handle LTR responsive state. 10201 * @since 6.0.1 Fix missing padding-left if row has its own padding-left when 10202 * Vertical Header is active. 10203 */ 10204 function MkfullWidthRow() { 10205 var $windowWidth = $(document).width(); 10206 var $elements = $('[data-mk-full-width="true"]'); 10207 var direction = $('body.rtl').length ? 'right' : 'left'; 10208 var verticalHeader = $('body.vertical-header-enabled').length ? true : false; 10209 var verticalHeaderWidth = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : 270; 10210 var verticalHeaderRtl = $('body.rtl').length ? -1 : 1; 10211 var verticalHeaderRtlWidth = $('body.rtl.vertical-header-enabled').length ? verticalHeaderWidth : 0; 10212 var verticalHeaderRight = $('body.vertical-header-right').length ? -1 : 1; 10213 var verticalHeaderWidthBoxed = 0; 10214 var boxed = $('body.mk-boxed-enabled').length; 10215 var boxedOffset = ( boxed ) ? ( $(window).width() - $('#theme-page').outerWidth() ) / 2 : 0; 10216 var boxedMaxWidth = ( boxed ) ? $('#theme-page').outerWidth() : 'auto'; 10217 10218 if ( verticalHeader && boxed ) { 10219 verticalHeaderWidthBoxed = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : verticalHeaderRtl * verticalHeaderRight * 135; 10220 } 10221 10222 var transparentHeader = $('.transparent-header').length; 10223 if ( transparentHeader > 0 ) { 10224 verticalHeaderWidthBoxed = 0; 10225 } 10226 10227 $.each($elements, function(key, item) { 10228 var $el = $(this); 10229 var css; 10230 $el.addClass("vc_hidden"); 10231 var $el_full = $el.next(".vc_row-full-width"); 10232 if ($el_full.length || ($el_full = $el.parent().next(".vc_row-full-width")), $el_full.length) { 10233 var el_margin_left = parseInt($el.css("margin-left"), 10), 10234 el_margin_right = parseInt($el.css("margin-right"), 10), 10235 offset = 0 - $el_full.offset().left - el_margin_left, 10236 width = $(window).width(); 10237 if (css = { 10238 position: "relative", 10239 "box-sizing": "border-box", 10240 width: $(window).width(), 10241 maxWidth: boxedMaxWidth 10242 }, 10243 css[direction] = offset + boxedOffset + verticalHeaderWidthBoxed + ( verticalHeaderRight * verticalHeaderRtlWidth ), 10244 $el.css(css), !$el.data("mkStretchContent")) { 10245 var padding = -1 * offset; 10246 0 > padding && (padding = 0); 10247 var paddingRight = width - padding - $el_full.width() + el_margin_left + el_margin_right; 10248 padding = padding - paddingRight; 10249 if ( 0 > paddingRight && (paddingRight = 0) ) { 10250 css = {}; 10251 if ( 'right' === direction ) { 10252 css["padding-left"] = padding + "px"; 10253 css["padding-right"] = 0; 10254 } else { 10255 css["padding-right"] = padding + "px"; 10256 css["padding-left"] = 0; 10257 } 10258 10259 $el.css(css) 10260 } 10261 } 10262 10263 /** 10264 * Fix AM-2974 10265 * 10266 * When user set padding-left or padding-right in the row, both of them 10267 * will be prioritized as important styles. It breaks padding-left set 10268 * by Vertical Header to make the row content fit with the content 10269 * container. We need to repopulate the padding-{side - based on Vertical 10270 * Header position} value. 10271 * 10272 * Works when: 10273 * - Vertical Header is active 10274 * - Main layout is not boxed 10275 * - Page Section is full layout 10276 * - Row is full width layout and content 10277 * - Row has its own padding-left and padding-right 10278 * - There is no additional padding added 10279 * 10280 * How it works: 10281 * Get current row padding-left and vertical header width. If both of them 10282 * are equal, it means row position is correct related to Vertical Header. 10283 * If not, we should sum both of them, then declare new padding-{side} 10284 * style attribute. 10285 * 10286 * Tested with: 10287 * - Main Layout: Full & Boxed Layout 10288 * - Page Section: Full Layout and Non Full Layout 10289 * - Row: Full Width, Full Width Content, and Non Full Width 10290 * - Header: Non vertical headers 10291 * - Transparent Header 10292 * - RTL and LTR 10293 */ 10294 if ( verticalHeader && ! boxed && ! transparentHeader && ! css.hasOwnProperty( 'padding-left' ) && ! css.hasOwnProperty( 'padding-right' )) { 10295 // Get row padding-{side} and Vertical Header width. 10296 var side = 'left'; 10297 if ( verticalHeaderRight === -1 ) { 10298 side = 'right'; 10299 } 10300 var el_padding_dir = parseInt( $el.css( 'padding-' + side ), 10 ); 10301 var header_padding_dir = $( '.header-style-4 .mk-header-inner' ).outerWidth(); 10302 // Compare both of row and vertical header padding-{side}. 10303 if ( el_padding_dir != header_padding_dir) { 10304 if($windowWidth > mk_responsive_nav_width) { 10305 $el[0].style.setProperty( 'padding-' + side, header_padding_dir + 'px', 'important' ); 10306 } else { 10307 $el[0].style.removeProperty( 'padding-' + side); 10308 } 10309 10310 10311 // Reset padding-{side} for page section. 10312 var $el_page_section = $el.find( '.mk-page-section.full_layout' ); 10313 if ( $el_page_section.length > 0 ) { 10314 $el_page_section[0].style.setProperty( 'padding-' + side, 'unset', 'important' ); 10315 } 10316 } 10317 } 10318 10319 $el.attr("data-mk-full-width-init", "true"), $el.removeClass("vc_hidden"), $(document).trigger("vc-full-width-row-single", { 10320 el: $el, 10321 offset: offset, 10322 marginLeft: el_margin_left, 10323 marginRight: el_margin_right, 10324 elFull: $el_full, 10325 width: width 10326 }) 10327 } 10328 }
10328), $(document).trigger("mk-full-width-row", $elements); 10329 } 10330 10331 MkfullWidthRow(); 10332 var debounceResize = null; 10333 $(window).on("resize", function() { 10334 if( debounceResize !== null ) { clearTimeout( debounceResize ); } 10335 debounceResize = setTimeout( MkfullWidthRow, 100 ); 10336 }); 10337 10338})( jQuery ); 10339 10340(function($) { 10341 'use strict'; 10342 10343 MK.component.Grid = function( el ) { 10344 var $container = $(el); 10345 var config = $container.data( 'grid-config' ); 10346 var isSlideshow = $container.closest('[data-mk-component="SwipeSlideshow"]').length; 10347 var miniGridConfig = { 10348 container: el, 10349 item: config.item + ':not(.is-hidden)', 10350 gutter: 0 10351 }; 10352 10353 var init = function init(){ 10354 // Flags for cancelling usage goes first : 10355 // Quit early if we discover that Grid is used inside SwipeSlideshow as it brings bug with crossoverriding positioning 10356 // + grid is not really needed as we have single row all handled by slider. 10357 // It happens only in woocommerce carousel as of hardcoded Grid in loop-start.php 10358 if(isSlideshow) return; 10359 MK.core.loadDependencies([ MK.core.path.plugins + 'minigrid.js' ], create); 10360 }; 10361 10362 // Remove el hidden without adding proper class 10363 var prepareForGrid = function prepareForGrid() { 10364 var $item = $(this); 10365 var isHidden = ($item.css('display') === 'none'); 10366 if(isHidden) $item.addClass('is-hidden'); 10367 else $item.removeClass('is-hidden'); 10368 }; 10369 10370 var create = function create() { 10371 var timer = null; 10372 10373 function draw() { 10374 // Prevent plugin breaking when feeding it with hidden elements 10375 $container.find(config.item).each( prepareForGrid ); 10376 minigrid(miniGridConfig); 10377 } 10378 10379 function redraw() { 10380 if (timer) clearTimeout(timer); 10381 timer = setTimeout(draw, 100); 10382 } 10383 10384 // init 10385 draw(); 10386 // If reinitializing drop existing event handler 10387 $(window).off('resize', redraw); 10388 $(window).on('resize', redraw); 10389 MK.utils.eventManager.subscribe('item-expanded', redraw); 10390 MK.utils.eventManager.subscribe('ajaxLoaded', redraw); 10391 MK.utils.eventManager.subscribe('staticFilter', redraw); 10392 }; 10393 10394 return { 10395 init : init 10396 }; 10397 }; 10398 10399})(jQuery); 10400 10401 10402 10403 10404 10405 10406 10407 10408/** 10409 * ICON FACTORY @ Maki 10410 * 10411 * Javascript part that translates css styles into link to server side manufacturer. 10412 * By passing extra args we generate icons as needed on server and send them back with ajax and attch them to DOM here. 10413 * 10414 * This is temporary solution that helps us switching from font icons to singular svgs without too match overhead. The finalized solution shoulnd be 99% server side. 10415 * Our main templating is happening there. We should have an icon_factory(name, properties) function that we can call directly in templates to serve us icons. 10416 * Post load, js soluition should target only elements that we have no direct access to. We set it as TODO for future as part of progressive development. 10417 * When correct factory is done we should be able to use it here and there to progressively kill overhead generated by current solution until we could totally switch it. 10418 * 10419 * Prons: 10420 * - automated process where we can mimic old behaviour 10421 * - possible bugs are easy to patch 10422 * - far samller download size for assets needed by theme (no font families css and fonts itself to download, which are currently blocking page load time) 10423 * - icon generation moved to server side where our main templating is already happening 10424 * - we can easily switch how our Icon should be outputed - inline, img, object, iframe. Whatever our situation requires (img for responsive icons for example) 10425 * 10426 * Cons: 10427 * - possible bugs based on different nature of svgs / fonts. Need to be manually fixed 10428 * - some manual work to straighten things - litle css refactors here and there 10429 * - as the mapping the icons happens in server side, it may cause CPU bottlenecks and should be cashed in DB for repetitve usage. 10430 * 10431 * 10432 * TODO Refactor to config obj as parameter for easier passing it. Also decouple more - especially loops 10433 */ 10434(function ($) { 10435 'use strict'; 10436 10437 // As long as we can manage this manually it is better like so. We avoid delay based on waiting for ajax to finish 10438 // $.get( MK.core.path.theme + '/assets/icons/icon-families.json', createAll); 10439 var families = [ 10440 ['awesome-icons' , 'mk-icon-'], // [family, prefix] 10441 ['icomoon' , 'mk-moon-'], 10442 ['pe-line-icons' , 'mk-li-'], 10443 ['theme-icons' , 'mk-jupiter-icon-'] 10444 ]; 10445 10446 // Our css contains this extends for particular families of fonts. For now we automate the process and extend it here as well 10447 var extend = { 10448 'awesome-icons' : [], 10449 'icomoon' : [], 10450 'pe-line-icons' : [], 10451 'theme-icons' : [] 10452 }; 10453 10454 // Cache holder for quick access to repeating icons. config / svg 10455 var _cache = {}; 10456 var _cacheId = 0;
10457 // Merge configs to call it with single ajax 10458 var _config = []; 10459 // Counter for all families. We merge all our families for single ajax request and countdown when to trigger the download. 10460 var _roundCount = 0; 10461 // Mapper for icons - config / array with nodes 10462 var _iconMap = {}; 10463 10464 10465 // Closure to merge $icons together and to run the download when we counted down icon families to 0 10466 var getIconsSprite = (function() { 10467 var $icons = null; 10468 var iterator = 0; 10469 10470 function run(callback) { 10471 var config = encodeURIComponent(JSON.stringify(_config)); 10472 10473 $.ajax({ 10474 url : MK.core.path.ajaxUrl, 10475 // dataType: 'xml', 10476 method: 'POST', 10477 data: {action : 'mk_get_icon', iterator: iterator++, config: config}, 10478 success: function(sprite) { 10479 callback(sprite, $icons); 10480 _config = []; 10481 _iconMap = {}; 10482 $icons = null; 10483 }, 10484 error: function(err) { 10485 console.log('Icon load problem'); 10486 } 10487 }); 10488 } 10489 10490 return function(callback, $els, count) { 10491 if(!$icons) $icons = $els; 10492 else $icons.add($els); 10493 // console.log(count); 10494 if(!count) run(callback); 10495 }; 10496 }()); 10497 10498 // Wait for DOM manipulations and run where really needed 10499 $(window).on('load', function() { 10500 setTimeout(function() { 10501 createAll(document); 10502 if($('.mk-header').length) createAll('.mk-header'); 10503 if($('.js-flexslider, .mk-flexslider').length) createAll('.js-flexslider, .mk-flexslider'); 10504 if($('.mk-accordion').length) createAll('.mk-accordion'); 10505 }, 1000); 10506 }); 10507 10508 MK.utils.eventManager.subscribe('ajaxLoaded', function() { 10509 // Wait for actuall DOM insertion 10510 setTimeout(createAll, 100, '.js-loop'); 10511 }); 10512 10513 MK.utils.eventManager.subscribe('ajax-preview', function() { 10514 setTimeout(createAll, 100, '.ajax-container'); 10515 }); 10516 10517 MK.utils.eventManager.subscribe('photoAlbum-open', function() { 10518 setTimeout(createAll, 100, '.gallery-share'); 10519 }); 10520 10521 MK.utils.eventManager.subscribe('quickViewOpen', function() { 10522 setTimeout(createAll, 300, '.mk-modal-content'); 10523 }); 10524 10525 // Our main runner that creates all icons in given scope 10526 function createAll(scope) { 10527 // iterate through families 10528 for(var i = 0, l = families.length; i < l; i++) { 10529 var family = families[i][0]; 10530 var prefix = families[i][1]; 10531 var $icons = getIcons(family, prefix, scope); 10532 if($icons.length) { 10533 _roundCount++; 10534 // apply arguments from current loop iteration but send createIcons to event loop so it will get trigerred in the same order as this loop finish. 10535 // We need it to pass all $icons first so we can merge all families before ajax request. 10536 setTimeout(createIcons, 0, $icons, family, prefix); 10537 } 10538 } 10539 } 10540 10541 // Grab all els in given scope that contains our prefix, anywhere in class attribute. Extend if needed 10542 function getIcons(family, prefix, scope) { 10543 var $scope = $(scope); 10544 var $icons = $scope.find('[class*='+ prefix +']'); 10545 var extraClassNames = extend[family]; 10546 // if nothing to extend just return what we have till now 10547 if(!extraClassNames) return $icons; 10548 // Extend it with our css garbish 10549 extraClassNames.forEach(function(className) { 10550 var $icon = $scope.find(className); 10551 $icons = $icons.add($icon); 10552 }); 10553 // serve all 10554 return $icons; 10555 } 10556 10557 10558 function createIcons($icons, family, prefix, i, unicode) { 10559 var id = i || 0; 10560 var icon = $icons[id]; 10561 10562 // quick check point, if no more icons break recursion 10563 if(!icon) { 10564 _roundCount--; 10565 getIconsSprite(insertIcons, $icons, _roundCount, _config); 10566 return; 10567 } 10568 10569 var css = getComputedStyle( icon, ':before'); 10570 var classAttr = icon.getAttribute('class'); 10571 var name = (classAttr) ? matchClass(classAttr.split(' '), prefix) : false; 10572 var h = getComputedStyle(icon).fontSize; 10573 var config = createConfig(css, name, family, unicode, h); 10574 var cache = JSON.stringify(config); 10575 10576 if(!config) { 10577 // Yep, we have a mess so sometimes we try to call for an icon where it should not exist (no class match or unicode found) 10578 // As we expect empty response from server, we just skip to next icon 10579 10580 } else if(_cache[cache]) { 10581 // Use cached icon when possible 10582 // 10583 if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)]; 10584 else _iconMap[cache].push($icons.eq(id)); 10585 10586 } else { 10587 if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)]; 10588 else _iconMap[cache].push($icons.eq(id)); 10589 10590 _cache[cache] = _cacheId.toString(); // number as string so we could do [var] key lookup after reversal 10591 config.id = _cacheId; // extend config for server only 10592 _config.push(config); 10593 10594 _cacheId++; // increment after caching 10595 } 10596 10597 createIcons($icons, family, prefix, ++id); 10598 } 10599 10600 function insertIcons(sprite, $icons) { 10601 var $sprite = $(sprite); 10602 var $svgs = $sprite.find('svg'); 10603 var idMap = invert(_cache); 10604 10605 $sprite.each(function() { 10606 var $svg = $(this); 10607 var id = $svg.attr('data-cacheid'); // read as string 10608 var configKey = idMap[id]; 10609 10610 _cache[configKey] = this; 10611 // console.log(id, this) 10612 }); 10613 10614 // console.log('sprite',sprite) 10615 // 10616
10617 Object.keys(_iconMap).forEach(function (cacheKey) { 10618 _iconMap[cacheKey].forEach(function($icons) { 10619 $icons.each(function() { 10620 var $svg = $(_cache[cacheKey]).clone(); 10621 var $icon = $(this); 10622 10623 // console.log($icon[0], _cache[cacheKey]); 10624 10625 function remove() { 10626 // exclude problematic stuff 10627 if($icon.parents('.pricing-features')) return; 10628 $icon.not('.mk-jupiter-icon-xing') 10629 .not('.mk-jupiter-icon-square-xing') 10630 .not('.mk-jupiter-icon-simple-xing') 10631 .find('.mk-svg-icon') 10632 .not('[data-name="mk-moon-zoom-in"]') 10633 .remove(); // and remove else to reapply styles with new loaded svg 10634 } 10635 10636 if($svg.length ) remove(); 10637 10638 if(!$icon.find('svg').length) { 10639 if($icon.parents('.widget ul').length) $icon.prepend($svg); 10640 else $icon.append($svg); 10641 } 10642 }); 10643 }); 10644 }); 10645 10646 // Notify rest of app 10647 MK.utils.eventManager.publish('iconsInsert'); 10648 } 10649 10650 // Prepare configuration for server side. We need to grab icons and manipulate them a little there 10651 function createConfig(css, name, family, unicode, height) { 10652 var hasGradient = checkGradient(css); 10653 var hasDirection = extractGradient('direction', css.background); 10654 10655 var config = { 10656 family: family, 10657 // this is mostly for Extends. Because we've been customizing singular elements and assigning content unicode manually, 10658 // now we don't have any proper anchor for usage with our json map 10659 unicode: (unicode) ? unicode : decodeUnicode(css.content), 10660 name: name, 10661 // fill: css.color, 10662 gradient_type: hasGradient ? extractGradient('type' , css.background) : false, 10663 gradient_start: hasGradient ? extractGradient('start', css.background) : false, 10664 gradient_stop: hasGradient ? extractGradient('stop' , css.background) : false, 10665 gradient_direction: hasDirection ? extractGradient('direction', css.background).replace(' ', '-') : false, 10666 height: height 10667 }; 10668 10669 // If there is no name or unicode the whole config is invalid 10670 if(!config.name && !config.unicode) return false; 10671 else return config; 10672 } 10673 10674 // Extract class name that represents the icon that we try to generate
10675 function matchClass(classes, prefix) { 10676 // var missing = ''; 10677 for(var i = 0, l = classes.length; i < l; i++) { 10678 if(classes[i].indexOf(prefix) !== -1) return classes[i]; // return first matched class name 10679 // else missing += ' .' + classes[i]; // collect not matching classes 10680 } 10681 // if we didn't returned anything within loop we output notification here. Keep it for testing only 10682 // console.log('Possibility of missing icons for element with classes:' + missing); 10683 } 10684 10685 // Check if background conatains gradient declaration and return bg string if so or false 10686 function checkGradient(css) { 10687 var bg = css.background; 10688 if(bg.indexOf('radial') !== -1 || bg.indexOf('linear') !== -1) return bg; 10689 else return false; 10690 } 10691 10692 // Extract background attribiutes from bg string. 10693 // Multipurpose function which returns part we ask for 10694 function extractGradient(attr, grad) { 10695 // quit if gradient is falsy 10696 // console.log(grad); 10697 if(!grad) return false; 10698 10699 var isRadial = grad.indexOf('radial') !== -1; 10700 var isLinear = grad.indexOf('linear') !== -1; 10701 var hasDirection = grad.indexOf('(to') !== -1; 10702 var f, t; // from, to 10703 10704 if(attr === 'type') { 10705 if(isRadial) return 'radial'; 10706 if(isLinear) return 'linear'; 10707 10708 } else if(attr === 'start') { 10709 f = getStrPosition(grad, 'rgb(', 1); 10710 t = getStrPosition(grad, '0%' , 1); 10711 10712 } else if(attr === 'stop') { 10713 f = getStrPosition(grad, 'rgb(', 2); 10714 t = getStrPosition(grad, '100%', 1); 10715 10716 } else if(attr === 'direction') { 10717 if(!hasDirection) return false; 10718 f = getStrPosition(grad, '(to', 1) + 4; 10719 t = getStrPosition(grad, ', rgb(', 1); 10720 10721 } else { 10722 return false; 10723 } 10724 10725 return grad.slice(f, t); 10726 } 10727 10728 // Helper for getting indexOf but with lookup for instance of the string 10729 // str - string to search 10730 // m - what we're looking for 10731 // i - instance, starting at 1 10732 function getStrPosition(str, m, i) { 10733 return str.split(m, i).join(m).length; 10734 } 10735 10736 // JS outputs unicode results rather than code representation. This helper function does the job 10737 function decodeUnicode(content) { 10738 // escape() kills \ escape signature and outputs it as %u 10739 // str replace to drop special chars 10740 // and we bring it all to lowercase to match filenames we keep on server 10741 if(content && content !== 'none') return escape(content).replace(/%22/g, '').replace('%u', '').toLowerCase(); 10742 else return false; // just in case we haven't provided content to work with 10743 } 10744 10745 function invert(obj) { 10746 var new_obj = {}; 10747 for (var prop in obj) { 10748 if(obj.hasOwnProperty(prop)) { 10749 new_obj[obj[prop]] = prop; 10750 } 10751 } 10752 return new_obj; 10753 } 10754 10755}(jQuery)); 10756/*! 10757 * imagesLoaded PACKAGED v4.1.1 10758 * JavaScript is all like "You images are done yet or what?" 10759 * MIT License 10760 */ 10761 10762!function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e}function o(t,e,r){return this instanceof o?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=n(t),this.options=i({},this.options),"function"==typeof e?r=e:i(this.options,e),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(function(){this.check()}.bind(this))):new o(t,e,r)}function r(t){this.img=t}function s(t,e){this.url=t,this.element=e,this.img=new Image}var h=t.jQuery,a=t.console;o.prototype=Object.create(e.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEac
10762h(this.addElementImages,this)},o.prototype.addElementImages=function(t){"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);var e=t.nodeType;if(e&&d[e]){for(var i=t.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var d={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}},o.prototype.addImage=function(t){var e=new r(t);this.images.push(e)},o.prototype.addBackground=function(t,e){var i=new s(t,e);this.images.push(i)},o.prototype.check=function(){function t(t,i,n){setTimeout(function(){e.progress(t,i,n)})}var e=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){e.once("progress",t),e.check()}):void this.complete()},o.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,t,e)},o.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}},r.prototype=Object.create(e.prototype),r.prototype.check=function(){var t=this.getIsImageComplete();return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},r.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])},r.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var t=this.getIsImageComplete();t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},o.makeJQueryPlugin=function(e){e=e||t.jQuery,e&&(h=e,h.fn.imagesLoaded=function(t,e){var i=new o(this,t,e);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o}); 10763 10764(function($, window){ 10765 'use strict'; 10766 10767 var scrollY = MK.val.scroll; 10768 var dynamicHeight = MK.val.dynamicHeight; 10769 10770 var $window = $(window); 10771 var $containers = $('.js-loop'); 10772 10773 $containers.each( pagination ); 10774 10775 $window.on( 'vc_reload', function() { 10776 $('.js-loop').each( pagination ); 10777 } ); 10778 10779 function pagination() { 10780 var unique = Date.now(); 10781 var $container = $(this); 10782 var $superContainer = $container.parent(); // should contain clearing so it stretches with floating children 10783 var $loadBtn = $container.siblings('.js-loadmore-holder').find('.js-loadmore-button'); 10784 var $loadScroll = $('.js-load-more-scroll'); 10785 var style = $container.data('pagination-style'); 10786 var maxPages = $container.data('max-pages'); 10787 var id = '#' + ($container.attr('id')); 10788 var ajaxLoader = new MK.utils.ajaxLoader(id); 10789 var isLoadBtn = (style === 2); 10790 var isInfiniteScroll = (style === 3); // add flag for last container 10791 var scrollCheckPoint = null; 10792 var isHandlerBinded = false;
10793 10794 ajaxLoader.init(); 10795 10796 init(); 10797 10798 function init() { 10799 MK.utils.eventManager.subscribe('ajaxLoaded', onLoad); 10800 bindHandlers(); 10801 if( isInfiniteScroll ) scrollCheckPoint = spyScrollCheckPoint(); 10802 10803 $window.on( 'vc_reload', function() { 10804 $window.off('scroll', handleScroll); 10805 } ); 10806 } 10807 10808 function bindHandlers() { 10809 if( isLoadBtn ) $loadBtn.on('click', handleClick); 10810 if( isInfiniteScroll ) $window.on('scroll', handleScroll); 10811 isHandlerBinded = true; 10812 } 10813 10814 function unbindHandlers() { 10815 if( isLoadBtn ) $loadBtn.off('click', handleClick); 10816 if( isInfiniteScroll ) $window.off('scroll', handleScroll); 10817 isHandlerBinded = false; 10818 } 10819 10820 function handleClick(e) { 10821 e.preventDefault(); 10822 if(!ajaxLoader.isLoading) loadMore(); 10823 } 10824 10825 function handleScroll() { 10826 if((scrollY() > scrollCheckPoint()) && !ajaxLoader.isLoading) loadMore(); 10827 } 10828 10829 function loadMore() { 10830 loadingIndicatorStart(); 10831 var page = ajaxLoader.getData('paged'); 10832 ajaxLoader.setData({paged: ++page}); 10833 ajaxLoader.load(unique); 10834 } 10835 10836 function onLoad(e, response) { 10837 if( typeof response !== 'undefined' && response.id === id) { 10838 // Checking found posts helps to fix all pagination styles 10839 if( ajaxLoader.getData('found_posts') <= 0 && ajaxLoader.getData('paged') >= ajaxLoader.getData('maxPages')) loadingIndicatorHide(); 10840 else loadingIndicatorShow(); 10841 if(response.unique === unique) $container.append(response.content); 10842 loadingIndicatorStop(); 10843 } 10844 } 10845 10846 function loadingIndicatorStart() { 10847 if(isLoadBtn) $loadBtn.addClass('is-active'); 10848 else if(isInfiniteScroll) MK.ui.loader.add('.js-load-more-scroll'); 10849 10850 } 10851 10852 function loadingIndicatorStop() { 10853 if(isLoadBtn) $loadBtn.removeClass('is-active'); 10854 else if(isInfiniteScroll) MK.ui.loader.remove('.js-load-more-scroll'); 10855 } 10856 10857 function loadingIndicatorShow() { 10858 if(isHandlerBinded) return; 10859 if(isLoadBtn) $loadBtn.show(); 10860 else if(isInfiniteScroll) $loadScroll.show(); 10861 bindHandlers(); 10862 } 10863 10864 function loadingIndicatorHide() { 10865 if(!isHandlerBinded) return; 10866 if(isLoadBtn) $loadBtn.hide(); 10867 else if(isInfiniteScroll) $loadScroll.hide(); 10868 unbindHandlers(); 10869 } 10870 10871 10872 function spyScrollCheckPoint() { 10873 var containerO = 0; 10874 var containerH = dynamicHeight( $superContainer ); 10875 var winH = dynamicHeight( window ); 10876 10877 var setVals = function() { 10878 containerO = $superContainer.offset().top; 10879 }; 10880 10881 setVals(); 10882 $window.on('resize', function() { requestAnimationFrame(setVals); }); 10883 10884 return function() { 10885 return (containerH() + containerO) - (winH() * 2); 10886 }; 10887 } 10888 } 10889 10890})(jQuery, window); 10891(function($) { 10892 'use strict'; 10893 10894 // Check if it's inside hidden parent 10895 // Cannot be position: fixed 10896 function isHidden(el) { 10897 return (el.offsetParent === null); 10898 } 10899 10900 MK.component.Masonry = function(el) { 10901 var $window = $(window); 10902 var $container = $(el); 10903 var config = $container.data( 'masonry-config' ); 10904 var $masonryItems = $container.find(config.item); 10905 var cols = config.cols || 8; 10906 var $filterItems = null; // assign only when apply filter 10907 var wall = null; 10908 10909 var init = function init() { 10910 MK.core.loadDependencies([ MK.core.path.plugins + 'freewall.js' ], onDepLoad); 10911 }; 10912 10913 var onDepLoad = function onDepLoad() { 10914 masonry(); 10915 10916 // Events 10917 $window.on('resize', onResize); 10918 MK.utils.eventManager.subscribe('ajaxLoaded', onPostAddition); 10919 MK.utils.eventManager.subscribe('staticFilter', resize); 10920 }; 10921 10922 var masonry = function masonry() { 10923 // Quit for hidden elements for now. 10924 if(isHidden(el)) return; 10925 10926 var newCols; 10927 if(window.matchMedia( '(max-width:600px)' ).matches) newCols = 2; 10928 else if(window.matchMedia( '(max-width:850px)' ).matches) newCols = 4; 10929 else newCols = cols; 10930 10931 var colW = $container.width() / newCols; 10932 10933 wall = new Freewall( config.container ); 10934 10935 // We need to pass settings to a plugin via reset method. Strange but works fine. 10936 wall.reset({
10937 selector: config.item + ':not(.is-hidden)', 10938 gutterX: 0, // set default gutter to 0 and again - apply margins to item holders in css 10939 gutterY: 0, 10940 cellW: colW, 10941 cellH: colW 10942 }); 10943 10944 wall.fillHoles(); 10945 wall.fitWidth(); 10946 10947 $masonryItems.each(function() { 10948 $(this).data('loaded', true); 10949 }); 10950 }; 10951 10952 10953 // Clear attributes after the plugin. It's API method dosn't handle it properly 10954 var destroyContainer = function destroyContainer() { 10955 $container.removeAttr('style') 10956 .removeData('wall-height') 10957 .removeData('wall-width') 10958 .removeData('min-width') 10959 .removeData('total-col') 10960 .removeData('total-row') 10961 .removeAttr('data-wall-height') 10962 .removeAttr('data-wall-width') 10963 .removeAttr('data-min-width') 10964 .removeAttr('data-total-col') 10965 .removeAttr('data-total-row'); 10966 }; 10967 10968 var destroyItem = function destroyItem() { 10969 var $item = $(this); 10970 $item.removeAttr('style') 10971 .removeData('delay') 10972 .removeData('height') 10973 .removeData('width') 10974 .removeData('state') 10975 .removeAttr('data-delay') 10976 .removeAttr('data-height') 10977 .removeAttr('data-width') 10978 .removeAttr('data-state'); 10979 }; 10980 10981 var destroyAll = function destroyAll() { 10982 if( !wall ) return; 10983 wall.destroy(); // API destroy 10984 destroyContainer(); 10985 $masonryItems.each( destroyItem ); // run our deeper destroy 10986 }; 10987 10988 var onResize = function onResize() { 10989 requestAnimationFrame(resize); 10990 }; 10991 10992 var refresh = function refresh() { 10993 if( !wall ) return; 10994 setTimeout(wall.fitWidth.bind(wall), 5); 10995 }; 10996 10997 var resize = function resize() { 10998 destroyAll(); 10999 masonry(); 11000 }; 11001 11002 var onPostAddition = function onPostAddition() { 11003 $masonryItems = $container.find(config.item); 11004 11005 $masonryItems.each(function() { 11006 var $item = $(this), 11007 isLoaded = $item.data('loaded'); 11008 11009 if(!isLoaded) $item.css('visibility', 'hidden'); 11010 }); 11011 11012 11013 $container.mk_imagesLoaded().then(function() { 11014 destroyAll(); 11015 masonry(); 11016 }); 11017 }; 11018 11019 return { 11020 init : init 11021 }; 11022 }; 11023 11024}(jQuery)); 11025(function($) { 11026 'use strict'; 11027 11028 MK.component.Pagination = function(el) { 11029 this.el = el; 11030 }; 11031 11032 MK.component.Pagination.prototype = { 11033 init: function init() { 11034 this.cacheElements(); 11035 this.bindEvents(); 11036 this.onInitLoad(); 11037 }, 11038 11039 cacheElements: function cacheElements() { 11040 this.lastId = 1; 11041 this.unique = Date.now(); 11042 this.$pagination = $(this.el); 11043 this.$container = this.$pagination.prev('.js-loop'); 11044 this.$pageLinks = this.$pagination.find('.js-pagination-page'); 11045 this.$nextLink = this.$pagination.find('.js-pagination-next'); 11046 this.$prevLink = this.$pagination.find('.js-pagination-prev'); 11047 this.$current = this.$pagination.find('.js-current-page'); 11048 this.$maxPages = this.$pagination.find('.pagination-max-pages'); // TODO change in DOM and here to js class 11049 this.containerId = '#' + this.$container.attr('id'); 11050 this.pagePathname = window.location.pathname; 11051 this.pageSearch = window.location.search; 11052 this.popState = false; 11053 this.ajaxLoader = new MK.utils.ajaxLoader('#' + this.$container.attr('id')); 11054 this.ajaxLoader.init(); 11055 }, 11056 11057 bindEvents: function bindEvents() { 11058 this.$pageLinks.on('click', this.pageClick.bind(this)); 11059 this.$nextLink.on('click', this.nextClick.bind(this)); 11060 this.$prevLink.on('click', this.prevClick.bind(this)); 11061 MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this)); 11062 }, 11063 11064 pageClick: function pageClick(e) { 11065 e.preventDefault(); 11066 var $this = $(e.currentTarget); 11067 var id = parseFloat($this.attr('data-page-id')); 11068 11069 if(id > this.ajaxLoader.getData('maxPages') || id < 1) return; 11070 this.load(id, $this); 11071 this.updatePagedNumUrl( id ); 11072 }, 11073 11074 nextClick: function nextClick(e) { 11075 e.preventDefault(); 11076 if(this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')) return; 11077 this.load(++this.lastId, $(e.currentTarget)); 11078 this.updatePagedNumUrl( this.lastId ); 11079 }, 11080 11081 prevClick: function prevClick(e) { 11082 e.preventDefault(); 11083 if(this.ajaxLoader.getData('paged') === 1) return; 11084 this.load(--this.lastId, $(e.currentTarget)); 11085 this.updatePagedNumUrl( this.lastId ); 11086 }, 11087 11088 load: function load(id, $el) { 11089 this.lastId = id; 11090 this.ajaxLoader.setData({paged: id}); 11091 this.ajaxLoader.load(this.unique); 11092 this.removeIndicator(); 11093 MK.ui.loader.add($el); 11094 }, 11095 11096 onLoad: function success(e, response) { 11097 if( typeof response !== 'undefined' && response.id === this.containerId) { 11098 this.updatePagination(); 11099 this.lastId = this.ajaxLoader.getData('paged'); 11100 11101 if(response.unique === this.unique) { 11102 this.removeIndicator(); 11103 this.scrollPage(); 11104 this.$container.html(response.content); 11105 } 11106 } 11107 }, 11108 11109 updatePagination: function updatePagination() { 11110 var self = this; 11111 11112 // Hide / show arrows 11113 var isFirst = (this.ajaxLoader.getData('paged') === 1); 11114 var isLast = (this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')); 11115 11116 if(isFirst) this.$prevLink.addClass('is-vis-hidden'); 11117 else this.$prevLink.removeClass('is-vis-hidden'); 11118 11119 if(isLast) this.$nextLink.addClass('is-vis-hidden'); 11120 else this.$nextLink.removeClass('is-vis-hidden'); 11121 11122 // X of Y 11123 this.$current.html(this.ajaxLoader.getData('paged')); 11124 this.$maxPages.html(this.ajaxLoader.getData('maxPages')); 11125 11126 // Move overfloating items 11127 var displayItems = 10; 11128 var centerAt = displayItems / 2; 11129 11130 if(this.ajaxLoader.getData('maxPages') > displayItems) { 11131 this.$pageLinks.each(function(i) { 11132 11133 var id = self.lastId - centerAt; 11134 id = Math.max(id, 1); 11135 id = Math.min(id, self.ajaxLoader.getData('maxPages') - displayItems + 1); 11136 id = id + i; 11137 11138 $(this).html( id ).attr('data-page-id', id).show(); 11139 11140 if(i === 0 && id > 1) $(this).html('...'); 11141 if(i === displayItems - 1 && id < self.ajaxLoader.getData('maxPages')) $(this).html('...'); 11142 }); 11143 } else { 11144 this.$pageLinks.each(function(i) { 11145 var $link = $(this); 11146 var id = i + 1; 11147 11148 $link.html(id).attr('data-page-id', id); 11149 11150 if( self.ajaxLoader.getData('maxPages') === 1) { 11151 self.$pageLinks.hide(); 11152 } else { 11153 if(i > self.ajaxLoader.getData('maxPages') - 1) $link.hide(); 11154 else $link.show(); 11155 } 11156 11157 }); 11158 } 11159 11160 // Highlight current only 11161 this.$pageLinks.filter('[data-page-id="' + this.ajaxLoader.getData('paged') + '"]' ).addClass('current-page') 11162 .siblings().removeClass('current-page'); 11163 11164 }, 11165 11166 scrollPage: function scrollPage() { 11167 var containerOffset = this.$container.offset().top; 11168 var offset = containerOffset - MK.val.offsetHeaderHeight( containerOffset ) - 20; 11169 11170 this.$container.find('a:first').focus() 11171 MK.utils.scrollTo( offset ); 11172 }, 11173 11174 removeIndicator: function removeIndicator() { 11175 MK.ui.loader.remove('.js-pagination-page, .js-pagination-next, .js-pagination-prev'); 11176 }, 11177 11178 /** 11179 * Set some actions when archive/category page is loaded. Actions list: 11180 * - Select the correct paged ID on pagination list. 11181 * - Set current paged ID on the label. 11182 * - Add event listener onpopstate for handling prev/next button of Browser URL. 11183 * - Set info for updatePagedNumUrl() about request comes from popstate. 11184 * 11185 * @since 5.9.8 11186 */ 11187 onInitLoad: function onInitLoad() { 11188 var initPagedID = this.$pagination.data( 'init-pagination' ); 11189 if ( initPagedID && initPagedID > 1 ) { 11190 this.$current.html( initPagedID ); 11191 this.$pageLinks.filter( '[data-page-id="' + initPagedID + '"]' ).addClass( 'current-page' ).siblings().removeClass( 'current-page' ); 11192 } 11193 11194 // Run popstate only if it's supported by the browser. 11195 if ( 'onpopstate' in window ) { 11196 var thisPop = this; 11197 window.onpopstate = function( event ) { 11198 var id = 1; 11199 11200 // At start, state is always null. So, we should check it before processing. 11201 if ( typeof event.state === 'object' && event.state ) { 11202 var state = event.state; 11203 11204 // Set paged ID for updating page. 11205 if ( state.hasOwnProperty( 'MkPagination' ) ) { 11206 var currentState = state.MkPagination; 11207 if ( currentState.hasOwnProperty( 'paged' ) ) { 11208 id = parseFloat( currentState.paged ); 11209 } 11210 } 11211 } else { 11212 id = parseFloat( thisPop.getURLPagedID() ); 11213 } 11214 11215 // Tell updatePagedNumUrl() if request come from popstate. 11216 thisPop.popState = true; 11217 thisPop.$pageLinks.filter( '[data-page-id="' + id + '"]' ).trigger( 'click' ); 11218 } 11219 } 11220 }, 11221 11222 /** 11223 * Update current pagination browser URL by adding/changing paged number. Only run if 11224 * the browser support pushState and the request not coming from popstate. 11225 * 11226 * WordPress has some ways to set paged number: 11227 * 1. page/[number], paged=[number] will be directed here. 11228 * 2. page=[number] 11229 * So, we should check which one the request is used here. 11230 * 11231 * @since 5.9.8 11232 */ 11233 updatePagedNumUrl: function updatePagedNumUrl( id ) { 11234 // Check pushState browser support and ignore if request come from popstate. 11235 if ( 'history' in window && 'pushState' in history && id && ! this.popState ) { 11236 var fullPage = this.pagePathname + this.pageSearch; 11237 var isQueryPage = false;
11238 11239 // Style 1 - /page/[number], as default value. 11240 var newPage = 'page/' + id + '/'; 11241 var expPage = /page\/\d+\/?/; 11242 var result = this.pagePathname.match( /\/page\/\d+/ ); 11243 var isPagedExist = ( result ) ? true : false; 11244 11245 // Style 2 - ?page=[number], only run if /page/ is not exist and URL query var exist. 11246 if ( ! isPagedExist && this.pageSearch ) { 11247 isQueryPage = this.pageSearch.match( /page\=\d+/ ); 11248 if ( isQueryPage ) { 11249 newPage = 'page=' + id; 11250 expPage = /page\=\d+/; 11251 } 11252 } 11253 11254 // If page number is 1, remove paged number from URL. 11255 if ( id === 1 ) { 11256 newPage = ''; 11257 if ( isQueryPage ) { 11258 expPage = ( this.pageSearch.match( /\&+/ ) ) ? /page\=\d+\&?/ : /\?page\=\d+\&?/; 11259 } 11260 } 11261 11262 // Set new pathname. Do replacement only if the new pathname contains paged number. 11263 var newURL = this.pagePathname + newPage + this.pageSearch; 11264 if ( fullPage.match( expPage ) ) { 11265 newURL = fullPage.replace( expPage, newPage ); 11266 } 11267 11268 // Set history state and return popstate back to fal
11268se. 11269 var historyState = { 11270 MkPagination: { 11271 url: newURL, 11272 paged: id 11273 } 11274 } 11275 this.popState = false; 11276 11277 // Push new pathname to display/hide the paged number. 11278 window.history.pushState( historyState, null, newURL ); 11279 } 11280 this.popState = false; 11281 }, 11282 11283 /** 11284 * Get current URL page ID. Notes: 11285 * 1. page/[number], paged=[number] will be directed here. 11286 * 2. page=[number] 11287 * 11288 * @return {integer} Current paged ID. Default 1. 11289 */ 11290 getURLPagedID: function getURLPagedID() { 11291 var pathname = window.location.pathname; 11292 var search = window.location.search; 11293 var pagedId = 1; 11294 var result = ''; 11295 var isPagedExist = false; 11296 11297 // Search based on style 1. 11298 result = pathname.match( /\/page\/(\d+)/ ); 11299 if ( result ) { 11300 isPagedExist = true; 11301 pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1; 11302 } 11303 11304 // Search based on style 2. 11305 if ( ! isPagedExist && search ) { 11306 result = search.match( /page\=(\d+)/ ); 11307 if ( result ) { 11308 isPagedExist = true; 11309 pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1; 11310 } 11311 } 11312 11313 return pagedId; 11314 } 11315 }; 11316 11317}(jQuery)); 11318(function( $ ) { 11319 'use strict'; 11320 11321 var val = MK.val, 11322 utils = MK.utils; 11323 11324 MK.component.Parallax = function( el ) { 11325 var self = this, 11326 $this = $( el ), 11327 obj = $this[0], 11328 $window = $( window ), 11329 container = document.getElementById( 'mk-theme-container' ), 11330 config = $this.data( 'parallax-config' ), 11331 $holder = $( config.holder ), 11332 headerHeight = null, 11333 offset = null, 11334 elHeight = null, 11335 ticking = false, 11336 isMobile = null; 11337 11338 11339 var clientRect = null; 11340 11341 var update = function() { 11342 // Clear styles to check for natural styles 11343 // then apply position and size 11344 obj.style.transform = null; 11345 obj.style.top = null; 11346 obj.style.bottom = null; 11347 11348 isMobile = MK.utils.isMobile(); 11349 11350 if( isMobile ) { 11351 $this.css( 'height', '' ); 11352 return; 11353 } 11354 11355 clientRect = $this[ 0 ].getBoundingClientRect(); 11356 offset = clientRect.top; 11357 elHeight = clientRect.height; 11358 headerHeight = val.offsetHeaderHeight( offset ); 11359 offset = offset - headerHeight + val.scroll(); 11360 11361 setPosition(); 11362 setSize( ); 11363 }; 11364 11365 11366 var h = 0, 11367 winH = 0, 11368 proportion = 0, 11369 height = 0; 11370 11371 // Position and background attachement should me moved to CSS but we repair it high specificity here as styles are not reliable currently 11372 var setSize = function() { 11373 $this.css( 'height', '' ); 11374 winH = $window.height() - headerHeight; 11375 h = obj.getBoundingClientRect().height; 11376 11377 if( config.speed <= 1 && config.speed > 0 ) { 11378 if( offset === 0 ) { 11379 $this.css({ 11380 backgroundAttachment: 'scroll', 11381 'will-change': 'transform' 11382 }); 11383 } else { 11384 $this.css({ 11385 height : h + ( (winH - h) * config.speed ), 11386 backgroundAttachment: 'scroll', 11387 'will-change': 'transform' 11388 }); 11389 } 11390 11391 } else if ( config.speed > 1 && h <= winH ) { 11392 $this.css({ 11393 // good for full heights - 2 because it's viewable by 2 screen heights 11394 height: ( winH + ( ( winH * config.speed ) - winH ) * 2 ), 11395 top: -( ( winH * config.speed ) - winH ), 11396 backgroundAttachment: 'scroll', 11397 'will-change': 'transform' 11398 }); 11399 11400 } else if ( config.speed > 1 && h > winH ) { 11401 proportion = h / winH; 11402 height = ( winH + ( ( winH * config.speed ) - winH ) * (1 + proportion) ); 11403 11404 $this.css({ 11405 height: height, 11406 top: -( height - (winH * config.speed) ), 11407 backgroundAttachment: 'scroll', 11408 'will-change': 'transform' 11409 }); 11410 11411 } else if ( config.speed < 0 && h >= winH ) { 11412 height = h * (1 - config.speed); 11413 $this.css({ 11414 height: height + (height - h), 11415 top: h - height, 11416 backgroundAttachment: 'scroll', 11417 'will-change': 'transform' 11418 }); 11419 11420 } else if ( config.speed < 0 && h < winH ) { 11421 // candidate to change 11422 var display = (winH + h) / winH; 11423 height = h * -config.speed * display; 11424 $this.css({ 11425 height: h + (height * 2), 11426 top: -height, 11427 backgroundAttachment: 'scroll', 11428 'will-change': 'transform' 11429 }); 11430 } 11431 }; 11432 11433 11434 var currentPoint = null, 11435 progressVal = null, 11436 startPoint = null, 11437 endPoint = null, 11438 $opacityLayer = config.opacity ? $this.find( config.opacity ) : null, 11439 scrollY = null; 11440 11441 var setPosition = function() { 11442 startPoint = offset - winH; 11443 endPoint = offset + elHeight + winH - headerHeight; 11444 scrollY = val.scroll(); 11445 11446 if( scrollY < startPoint || scrollY > endPoint ) { 11447 ticking = false;
11448 return; 11449 } 11450 11451 currentPoint = (( -offset + scrollY ) * config.speed); 11452 11453 $this.css({ 11454 '-webkit-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11455 '-moz-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11456 '-ms-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11457 '-o-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11458 'transform': 'translateY(' + currentPoint + 'px) translateZ(0)' 11459 }); 11460 11461 ticking = false; 11462 }; 11463 11464 11465 var requestTick = function() { 11466 if( !ticking && !isMobile ) { 11467 ticking = true; 11468 window.requestAnimationFrame( setPosition ); 11469 } 11470 }; 11471 11472 11473 var init = function() { 11474 // Disable scroll effects when smooth scroll is disabled 11475 if( !MK.utils.isSmoothScroll ) { return; } 11476 11477 update(); 11478 setTimeout(update, 100); 11479 $window.on( 'load', update ); 11480 $window.on( 'resize', update ); 11481 window.addResizeListener( container, update ); 11482 11483 $window.on( 'scroll', requestTick ); 11484 }; 11485 11486 11487 return { 11488 init : init 11489 }; 11490 }; 11491 11492})( jQuery ); 11493(function($) { 11494 'use strict'; 11495 11496 MK.component.Preloader = function(el) { 11497 this.el = el; 11498 }; 11499 11500 MK.component.Preloader.prototype = { 11501 init: function init() { 11502 this.cacheElements(); 11503 this.bindEvents(); 11504 }, 11505 11506 cacheElements: function cacheElements() { 11507 this.$preloader = $(this.el); 11508 }, 11509 11510 bindEvents: function bindEvents() { 11511 this.onLoad(); // all components inited on page load 11512 }, 11513 11514 onLoad: function onLoad() { 11515 setTimeout(this.hidePreloader.bind(this), 300); 11516 }, 11517 11518 hidePreloader: function hidePreloader() { 11519 this.$preloader.hide(); 11520 } 11521 }; 11522 11523}(jQuery)); 11524 11525(function($) { 11526 'use strict'; 11527 11528 // Image added for proportional scaling 11529 MK.ui.loader = { 11530 tpl : function() { 11531 return '<div class="mk-loading-indicator">' + 11532 '<div class="mk-loading-indicator__inner">' + 11533 '<div class="mk-loading-indicator__icon"></div>' + 11534 '<img style="height:100%; width:auto;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">' + 11535 '</div>' + 11536 '</div>'; 11537 }, 11538 11539 add : function(item) { 11540 $(item).append(this.tpl); 11541 }, 11542 11543 remove : function(item) { 11544 if(item) $(item).find('.mk-loading-indicator').remove(); 11545 else $('.mk-loading-indicator').remove(); 11546 } 11547 }; 11548 11549}(jQuery)); 11550(function( $ ) { 11551 // IE / Edge fix for fixed positioned elements 11552 // MS clip path doesnt redraw properly so we expirience similar bug like with background attachement fixed on Chrome 11553 if (MK.utils.browser.name === 'Edge' || MK.utils.browser.name === 'IE') { 11554 var val = 1; 11555 var $edgeClipper = $('.mk-slider-slide'); // edge slider 11556 var $sectionClipper = $('.clipper-true'); // edge slider 11557 var $bgLayer = $('.background-layer'); // page section 11558 11559 var onScroll = function onScroll() { 11560 val *= -1; 11561 if( $edgeClipper.length ) $edgeClipper.each( redraw ); 11562 if( $sectionClipper.length ) $sectionClipper.each( redraw ); 11563 if( $bgLayer.length ) $bgLayer.each( redraw ); 11564 }; 11565 11566 var redraw = function redraw() { 11567 $(this).css('margin-top', val / 100); 11568 }; 11569 11570 $(window).on("scroll", function () { 11571 window.requestAnimationFrame(onScroll); 11572 }); 11573 } 11574}(jQuery)); 11575MK.component.ResponsiveImageSetter = (function ($) { 11576 11577 'use strict'; 11578 11579 var module = {}; 11580 11581 11582 /*---------------------------------------------------------------------------------*/ 11583 /* Private Variables 11584 /*---------------------------------------------------------------------------------*/ 11585 11586 var viewportClass = getViewportClass(); 11587 var isRetina = window.devicePixelRatio >= 2; 11588 11589 11590 /*---------------------------------------------------------------------------------*/ 11591 /* Private Methods 11592 /*---------------------------------------------------------------------------------*/ 11593 11594 function run($imgs) { 11595 $imgs.filter( function() { 11596 return !this.hasAttribute("mk-img-src-setted"); 11597 }).each(setSrcAttr); 11598 } 11599 11600 function setSrcAttr() { 11601 var $img = $(this); 11602 var set = $img.data('mk-image-src-set'); 11603 // Set src attribute to img link suitable for our logic. It will load the image. 11604 if(set['responsive'] === 'false' && isRetina && set['2x']) $img.attr('src', set['2x']); 11605 else if(set['responsive'] === 'false') $img.attr('src', set.default); 11606 else if(viewportClass === 1 && isRetina && set['2x']) $img.attr('src', set['2x']); // default x2 for retina 11607 else if(viewportClass === 0 && set.mobile) $img.attr('src', set.mobile); 11608 else $img.attr('src', set.default); 11609 11610 $img.load(function() { 11611 $(window).trigger('mk-image-loaded') 11612 }) 11613 } 11614 11615 function getViewportClass() { 11616 if(window.matchMedia('(max-width: 736px)').matches) return 0; 11617 else return 1; 11618 } 11619 11620 function handleResize($imgs) { 11621 if(!$imgs.length) return;
11621 // Do not run if empty collection 11622 var currentViewportClass = getViewportClass(); 11623 // We don't need to reload bigger images when screen size is decreasing as browser already performs resize operation. 11624 // Run update on for increasing screen size 11625 if( currentViewportClass > viewportClass) { 11626 viewportClass = currentViewportClass; // update for further reference 11627 run($imgs); 11628 } 11629 } 11630 11631 11632 /*---------------------------------------------------------------------------------*/ 11633 /* Public Methods 11634 /*---------------------------------------------------------------------------------*/ 11635 11636 module.init = function ($imgs) { 11637 11638 // Do not run if empty collection 11639 if(!$imgs.length) return; 11640 11641 // Run and bind to events 11642 run($imgs); 11643 $imgs.attr('mk-img-src-setted', ''); 11644 11645 }; 11646 11647 module.onResize = function ($imgs) { 11648 11649 $(window).on( 'resize', MK.utils.throttle( 500, function() { 11650 handleResize($imgs); 11651 })); 11652 11653 11654 }; 11655 11656 11657 module.handleAjax = function () { 11658 setTimeout(function ajaxDelayedCallback() { // give it a chance to insert content first 11659 var $newImgs = $('img[data-mk-image-src-set]').filter( function() { 11660 return !this.hasAttribute("mk-lazyload"); 11661 }); 11662 if(!$newImgs.length) return; 11663 run($newImgs); 11664 }, 100); 11665 } 11666 11667 11668 return module; 11669 11670}(jQuery)); 11671 11672 11673jQuery(function($) { 11674 11675 var init = function init() { 11676 // Get All Responsive Images 11677 $allImages = $('img[data-mk-image-src-set]').filter(function(index) { 11678 var isNotPortfolioImage = !$(this).hasClass('portfolio-image'), 11679 isNotBlogImage = $(this).closest('.mk-blog-container').length == 0, 11680 isNotSwiperImage = !$(this).hasClass('swiper-slide-image'), 11681 isNotGalleryImage = !$(this).hasClass('mk-gallery-image'); 11682 return isNotPortfolioImage && isNotBlogImage && isNotSwiperImage && isNotGalleryImage; 11683 });; 11684 11685 // Handle the resize 11686 MK.component.ResponsiveImageSetter.onResize($allImages); 11687 11688 MK.component.ResponsiveImageSetter.init($allImages); 11689 11690 MK.utils.eventManager.subscribe('ajaxLoaded', MK.component.ResponsiveImageSetter.handleAjax ); // ajax loops 11691 MK.utils.eventManager.subscribe('ajax-preview', MK.component.ResponsiveImageSetter.handleAjax ); // ajax portfolio 11692 MK.utils.eventManager.subscribe('quickViewOpen', MK.component.ResponsiveImageSetter.handleAjax ); 11693 }
11694 init(); 11695 $(window).on('vc_reload', init); 11696 11697}); 11698 11699 11700 11701(function( $ ) { 11702 'use strict'; 11703 11704 var utils = MK.utils; 11705 var val = MK.val; 11706 11707 /** 11708 * Keep track of top Level sections so we can easly skip to next one. 11709 * We must be explicit about DOM level to nested sections. 11710 * The list of sections is static. If you'd need to refreh it on ajax etc do it with pub/sub (not really needed now). 11711 * We keep track for the same sections in Footer for mutating window location with '!loading' to prevent native anchor behaviour. 11712 */ 11713 var $topLevelSections = $('#theme-page > .vc_row, #theme-page > .mk-main-wrapper-holder, #theme-page > .mk-page-section'); 11714 11715 $( document ).on( 'click', '.mk-skip-to-next', function() { 11716 var $this = $( this ), 11717 /** 11718 * Static height of button + the space to the bottom of the container. 11719 * 11720 * @TODO Possible to calculate dynamically. 11721 */ 11722 btnHeight = $this.hasClass( 'edge-skip-slider' ) ? 150 : 76, 11723 offset = $this.offset().top + btnHeight, 11724 nextOffset = utils.nextHigherVal( utils.offsets( $topLevelSections ), [offset] ); 11725 11726 utils.scrollTo( nextOffset - val.offsetHeaderHeight( nextOffset ) ); 11727 }); 11728 11729})( jQuery ); 11730 11731(function($) { 11732 'use strict'; 11733 11734 // 11735 // Constructor 11736 // 11737 // ///////////////////////////////////////////////////////// 11738 11739 MK.ui.Slider = function( container, config ) { 11740 11741 var defaults = { 11742 slide : '.mk-slider-slide', 11743 nav : '.mk-slider-nav', 11744 effect : 'roulete', 11745 ease : 'easeOutQuart', // should not be changed, remove 11746 slidesPerView : 1, 11747 slidesToView : 1, 11748 transitionTime : 700, 11749 displayTime : 3000, 11750 autoplay : true, 11751 hasNav : true, 11752 hasPagination : true, 11753 paginationTpl : '<span></span>', 11754 paginationEl : '#pagination', 11755 draggable : true, 11756 fluidHeight : false, 11757 pauseOnHover : false, 11758 lazyload : false, 11759 activeClass : 'is-active', 11760 edgeSlider : false, 11761 spinnerTpl : '<div class="mk-slider-spinner-wrap"><div class="mk-slider-spinner-fallback"></div><svg class="mk-slider-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="mk-slider-spinner-path" fill="none" stroke-width="4" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>', 11762 onInitialize : function() {}, 11763 onAfterSlide : function( id ) {}, 11764 onBeforeSlide : function( id ) {} 11765 }; 11766 11767 this.state = { 11768 id : 0, 11769 moveForward : true, 11770 running : false, 11771 zIFlow : null, 11772 stop : false, 11773 }; 11774 11775 this.config = $.extend( defaults, config ); 11776 this.container = container; 11777 11778 this.initPerView = this.config.slidesPerView; 11779 11780 // Timer holder 11781 this.activeTimer = null; 11782 this.autoplay = null; 11783 this.timer = null; 11784 this.timerRemaining = parseInt(this.config.displayTime); 11785 11786 // Boolean 'Em All, Making sure it's not string 11787 this.config.lazyload = JSON.parse(this.config.lazyload); 11788 this.config.edgeSlider = JSON.parse(this.config.edgeSlider); 11789 11790 // Image Loader Instance 11791 this.imageLoader = null; 11792 11793 // Add abort command to imagesLoaded, Placing it inside script makes it to work with different versions 11794 // of imagesLoaded if loaded by other Plugins 11795 imagesLoaded.prototype.abort = function() { 11796 this.progress = this.complete = function() { }; 11797 }; 11798 }; 11799 11800 11801 11802 // 11803 // Shared methods 11804 // 11805 // ///////////////////////////////////////////////////////// 11806 11807 MK.ui.Slider.prototype = { 11808 11809 init : function() { 11810 this.setPerViewItems(); 11811 this.cacheElements(); 11812 this.getSlideSize(); 11813 this.bindEvents(); 11814 this.setSize(); 11815 this.setPos(); 11816 11817 // Hack for preparing 'prev' on first click if needed 11818 this.updateId( -1 ); 11819 this.updateId( 1 ); 11820 11821 this.val = this.dynamicVal(); 11822 this.timeline = this.prepareTimeline( this.config.transitionTime ); 11823 11824 this.timeline.build(); 11825 11826 if( this.config.hasPagination ) { this.buildPagination(); } 11827
11828 if( this.config.autoplay && document.hasFocus() ) { this.setTimer(); } 11829 11830 if( typeof this.config.onInitialize === 'function' ) { 11831 this.config.onInitialize( this.slides ); 11832 } 11833 11834 if( this.config.fluidHeight === true ) { 11835 $( this.slides ).height( 'auto' ); 11836 $( this.container ).css( 'transition', 'height ' + 200 + 'ms ease-out' ); 11837 this.setHeight( 0 ); 11838 } 11839 11840 11841 if( this.config.fluidHeight === 'toHighest' ) { 11842 this.setHeightToHighest(); 11843 } 11844 11845 // Create timer per slide if required 11846 $(this.slides).each(this.createTimer); 11847 11848 // If it's Edge Slider and Lazy Load is enabled 11849 if ( this.config.lazyload && this.config.edgeSlider ) { 11850 11851 // If It's not a Video Slide 11852 if ( $(this.slides[this.state.id]).find('video').length === 0 ) { 11853 // Set the first slide's BG image 11854 var $slideImg = $(this.slides[this.state.id]).children('[data-mk-img-set]'); 11855 MK.component.BackgroundImageSetter.init( $slideImg ); 11856 } 11857 $(this.config.spinnerTpl).prependTo( this.$slides ); 11858 11859 } else { 11860 11861 // Set all slides's BG images 11862 MK.component.BackgroundImageSetter.init( $(this.slides).children('[data-mk-img-set]') ); 11863 11864 } 11865 11866 11867 11868 }, 11869 11870 11871 cacheElements : function () { 11872 this.container = this.isNode( this.container ) ? this.container 11873 : document.querySelectorAll( this.container )[0]; 11874 this.slides = this.container.querySelectorAll( this.config.slide ); 11875 this.$slides = $(this.slides); 11876 11877 if( this.config.hasNav ) { this.$nav = $( this.config.nav ); } 11878 if( this.config.hasPagination ) { this.$pagination = $( this.config.paginationEl ); } 11879 }, 11880 11881 11882 bindEvents : function() { 11883 var $window = $( window ); 11884 11885 if( this.config.slidesPerView > 1 ) { $window.on( 'resize', this.setPerViewItems.bind( this ) ); } 11886 if( this.config.hasNav ) { this.eventsNav(); } 11887 if( this.config.hasPagination ) { this.eventsPag(); } 11888 if( this.config.draggable ) { this.dragHandler(); } 11889 if( this.config.autoplay ) { 11890 $window.on( 'focus', this.windowActive.bind( this ) ); 11891 $window.on( 'blur', this.windowInactive.bind( this ) ); 11892 } 11893 if( this.config.pauseOnHover ) { 11894 $(this.container).on( 'mouseleave', this.setTimer.bind( this ) ); 11895 $(this.container).on( 'mouseenter', this.unsetTimer.bind( this ) ); 11896 } 11897 if( this.config.fluidHeight === 'toHighest' ) { 11898 $window.on( 'resize', this.setHeightToHighest.bind( this ) ); 11899 } 11900 }, 11901 11902 11903 setPerViewItems: function() { 11904 if(window.matchMedia( '(max-width: 500px)' ).matches) { this.config.slidesPerView = 1; } 11905 else if(window.matchMedia( '(max-width: 767px)' ).matches && this.initPerView >= 2 ) { this.config.slidesPerView = 2; } 11906 else if(window.matchMedia( '(max-width: 1024px)' ).matches && this.initPerView >= 3 ) { this.config.slidesPerView = 3; } 11907 else { this.config.slidesPerView = this.initPerView; } 11908 11909 if( typeof this.slides === 'undefined' ) return; 11910 this.getSlideSize(); 11911 this.setSize(); 11912 this.setPos(); 11913 this.timeline = this.prepareTimeline( this.config.transitionTime ); 11914 this.timeline.build(); 11915 }, 11916 11917 11918 eventsNav : function() { 11919 this.$nav.on( 'click', 'a', this.handleNav.bind( this ) ); 11920 }, 11921 11922 11923 eventsPag : function() { 11924 this.$pagination.on( 'click', 'a', this.handlePagination.bind( this ) ); 11925 }, 11926 11927 11928 handleNav : function( e ) { 11929 e.preventDefault(); 11930 11931 if( this.state.running ) { return; } 11932 this.state.running = true; 11933 11934 var $this = $( e.currentTarget ), 11935 moveForward = $this.data( 'direction' ) === 'next'; 11936 11937 11938 if( this.config.autoplay ) { 11939 this.unsetTimer(); 11940 setTimeout( this.setTimer.bind( this ), this.config.transitionTime ); 11941 } 11942 11943 this.state.moveForward = moveForward; 11944 this.timeline.build(); 11945 this.timeline.play(); 11946 11947 this.setActive( this.nextId( moveForward ? 1 : -1 ) ); 11948 if( this.config.fluidHeight ) { this.setHeight( this.nextId( moveForward ? 1 : -1 ) ); } 11949 }, 11950 11951 11952 handlePagination : function( e ) { 11953 e.preventDefault(); 11954 11955 var $this = $( e.currentTarget ), 11956 id = $this.index(); 11957 11958 this.goTo( id ); 11959 }, 11960 11961 11962 reset: function() { 11963 this.state.stop = true; 11964 this.state.id = 0; 11965 this.setPos(); 11966 this.unsetTimer(); 11967 this.setTimer(); 11968 }, 11969 11970 11971 goTo : function(id) { 11972 if( this.state.running ) { return; } 11973 this.state.running = true; 11974 11975 var lastId = this.state.id; 11976 11977 if( lastId === id ) { 11978 return; 11979 } else if( lastId < id ) { 11980 this.state.moveForward = true; 11981 } else { 11982 this.state.moveForward = false;
11983 } 11984 11985 if( this.config.autoplay ) { 11986 this.unsetTimer(); 11987 setTimeout( this.setTimer.bind( this ), this.config.transitionTime ); 11988 } 11989 11990 this.timeline.build( Math.abs( lastId - id ) ); 11991 this.timeline.play(); 11992 11993 this.setActive( id ); 11994 if( this.config.fluidHeight ) { this.setHeight( id ); } 11995 }, 11996 11997 11998 windowActive : function() { 11999 this.setTimer(false, true); 12000 $(this.container).removeClass('is-paused'); 12001 }, 12002 12003 12004 windowInactive : function() { 12005 this.unsetTimer(); 12006 $(this.container).addClass('is-paused'); 12007 }, 12008 12009 12010 updateId : function( val ) { 12011 this.state.id = this.nextId(val); 12012 }, 12013 12014 nextId : function( val ) { 12015 var len = this.slides.length, 12016 insertVal = this.state.id + val; 12017 insertVal = ( insertVal >= 0 ) ? insertVal : len + val; 12018 insertVal = ( insertVal >= len ) ? 0 : insertVal; 12019 12020 return insertVal; 12021 }, 12022 12023 12024 setStyle : function( obj, style ) { 12025 var hasT = style.transform, 12026 t = { 12027 x : ( hasT ) ? style.transform.translateX : null, 12028 y : ( hasT ) ? style.transform.translateY : null, 12029 scale : ( hasT ) ? style.transform.scale : null, 12030 rotate : ( hasT ) ? style.transform.rotate : null, 12031 rotateX : ( hasT ) ? style.transform.rotateX : null, 12032 rotateY : ( hasT ) ? style.transform.rotateY : null 12033 }, 12034 z = 'translateZ(0)', 12035 x = (t.x) ? 'translateX(' + t.x + '%)' : 'translateX(0)', 12036 y = (t.y) ? 'translateY(' + t.y + '%)' : 'translateY(0)', 12037 s = (t.scale) ? 'scale(' + t.scale + ')' : 'scale(1)', 12038 r = (t.rotate) ? 'rotate(' + t.rotate + 'deg)' : 'rotate(0)', 12039 rX = (t.rotateX) ? 'rotateX(' + t.rotateX + 'deg)' : '', 12040 rY = (t.rotateY) ? 'rotateY(' + t.rotateY + 'deg)' : '', 12041 12042 o = style.opacity, 12043 h = style.height, 12044 w = style.width; 12045 12046 var c = z + x + y + s + r + rX + rY; 12047 12048 if( c.length ) { 12049 obj.style.webkitTransform = c; 12050 obj.style.msTransform = c; 12051 obj.style.transform = c; 12052 } 12053 12054 if( typeof o === 'number' ) { obj.style.opacity = o; } 12055 if( h ) { obj.style.height = h + '%'; } 12056 if( w ) { obj.style.width = w + '%'; } 12057 }, 12058 12059 12060 setPos : function() { 12061 if( typeof this.slides === 'undefined' ) return; 12062 var id = this.state.id, 12063 i = 0, 12064 len = this.slides.length, 12065 animation = this.animation[ this.config.effect ], 12066 axis = animation.axis, 12067 animNext = animation.next, 12068 animActi = animation.active, 12069 animPrev = animation.prev, 12070 perView = this.config.slidesPerView, 12071 slideId = null, 12072 zIFlow = null, 12073 style = {}; 12074 12075 style.transform = {}; 12076 12077 12078 for( ; i < len; i += 1 ) { 12079 if(i < perView) { 12080 // Position for visible slides. Apply active styles 12081 style = animActi; 12082 style.transform[ 'translate' + axis ] = i * 100; 12083 } else { 12084 // Rest slides move after edge based on axis and moveForward. Apply Next / Prev styles 12085 style = this.state.moveForward ? animNext : animPrev; 12086 style.transform[ 'translate' + axis ] = this.state.moveForward ? perView * 100 : -100; 12087 } 12088 12089 this.slides[ i ].style.zIndex = 0; 12090 12091 slideId = ( i + id ) % len; 12092 this.setStyle( this.slides[ slideId ], style ); 12093 } 12094 }, 12095 12096 12097 // When we're setting animation along Y axis we're going to set up height 12098 // otherwise width. It is shared amongst all slides 12099 setSize : function() { 12100 if( typeof this.slides === 'undefined' ) return; 12101 var i = 0, 12102 len = this.slides.length, 12103 axis = this.animation[ this.config.effect ].axis, 12104 slideSize = this.slideSize, 12105 style = {}; 12106 12107 if( axis === 'Y' ) { 12108 style.height = slideSize[ axis ]; 12109 } else { 12110 style.width = slideSize[ axis ]; 12111 } 12112 12113 for( ; i < len; i += 1 ) { 12114 this.setStyle( this.slides[ i ], style ); 12115 } 12116 }, 12117 12118 12119 setHeight : function( id ) { 12120 var $slides = $( this.slides ), 12121 $activeSlide = $slides.eq( id ); 12122 12123 var currentHeight = $activeSlide.height(); 12124 $( this.container ).height( currentHeight ); 12125 }, 12126 12127 12128 setHeightToHighest : function() { 12129 // this is becouse of alliginig woocommrece carousel. Too much DOM 12130 // Refactor someday 12131 var $slides = $( this.slides ), 12132 height = 0; 12133 12134 $slides.each(function() { 12135 height = Math.max(height, $(this).find('> div').outerHeight()); 12136 }); 12137 12138 $( this.container ).height( height ); 12139 }, 12140 12141 12142 // Little utility inspired by GreenSock. 12143 // We export this to this.timeline on init. 12144 prepareTimeline : function( time ) { 12145 var self = this, 12146 iteration = 0, 12147 totalIter = time / (1000 / 60), 12148 animLoop = [], 12149 aL = 0, // animation length 12150 loops = 1, 12151 ease = this.config.ease, 12152 currentStyle, timeProg, 12153 build, move, add, play, reverse, progress, kill; 12154 12155 12156 // Build constants, run them only once 12157 // take out possibly 12158 var len = this.slides.length, 12159 perView = this.config.slidesPerView, 12160 animation = this.animation[ this.config.effect ], 12161 animAxis = animation.axis, 12162 animNext = animation.next, 12163 animActi = animation.active, 12164 animPrev = animation.prev, 12165 style = {}, 12166 slideId = null, 12167 zIFlow = null; 12168 12169 style.transform = {}; 12170 12171 12172 build = function( repeats ) { 12173 var currentEase = ease; 12174 loops = repeats || loops; 12175 12176 // console.log('build', loops); 12177 12178 if( !loops ) { return; } 12179 if( loops > 1 ) { 12180 currentEase = 'linearEase'; 12181 } 12182 12183 // clean before running new build 12184 kill(); 12185 // set new positions 12186 self.setPos(); 12187 12188 var id = self.state.id, 12189 moveForward = self.state.moveForward, 12190 i = 0, 12191 axisMove = (moveForward) ? -100 : 100; 12192
12193 for( ; i <= perView; i += 1 ) { 12194 slideId = ( (moveForward) ? i + id : i + id - 1 ) % len; 12195 slideId = ( slideId < 0 ) ? len + slideId : slideId; 12196 12197 if( i === 0 ) { 12198 style = moveForward ? animPrev : animActi; 12199 } else if( i === perView ) { 12200 style = moveForward ? animActi : animNext; 12201 } else { 12202 style = animActi; 12203 } 12204 12205 zIFlow = (self.state.moveForward) ? animNext.zIndex : animPrev.zIndex; 12206 if( zIFlow ) { 12207 // console.log( zIFlow ); 12208 self.slides[ slideId ].style.zIndex = (zIFlow === '+') ? i + 1 : len - i; 12209 } 12210 12211 style.transform[ 'translate' + animAxis ] = axisMove; 12212 add( self.slides[ slideId ], style, currentEase ); 12213 } 12214 }; 12215 12216 add = function( slide, toStyles, ease ) { 12217 if( typeof slide === 'undefined' ) { 12218 throw 'Add at least one slide'; 12219 } 12220 12221 var fromStyles = slide.style, 12222 style = self.refStyle( toStyles, fromStyles ); 12223 12224 animLoop.push( [slide, style, ease] ); 12225 aL += 1; 12226 }; 12227 12228 move = function( startProg, mode ) { 12229 if (isTest) return; 12230 var currentTotalIter = totalIter; 12231 12232 if( loops > 1 ) { 12233 currentTotalIter = totalIter / 5; 12234 } 12235 12236 if( !self.state.running ) { self.state.running = true; } 12237 12238 if( startProg ) { 12239 // update iteration val to cached outside var 12240 // ceil to handle properly play after mouse up / touch end 12241 iteration = Math.ceil(startProg * currentTotalIter); 12242 } 12243 12244 timeProg = iteration / currentTotalIter; 12245 progress( timeProg ); 12246 12247 // Break loop 12248 if( iteration >= currentTotalIter && mode === 'play' || 12249 iteration <= 0 && mode === 'reverse' ) { 12250 12251 self.state.running = false; 12252 iteration = 0; 12253 kill(); 12254 self.updateId( self.state.moveForward ? 1 : -1 ); 12255 // If we're creating multiple animation loop we trigger outside only first pass to start all game. 12256 // the rest are triggered as callback 12257 loops -= 1; 12258 if( loops > 0 ) { 12259 build(); 12260 play(); 12261 } 12262 12263 // if we run all loops reset back the default value 12264 if( !loops ) { 12265 loops = 1; 12266 self.timerRemaining = parseInt(self.config.displayTime); 12267 self.config.onAfterSlide( self.state.id ); 12268 } 12269 12270 return; 12271 } 12272 12273 // Run in given mode 12274 if( mode === 'play') { 12275 iteration += 1; 12276 } else { 12277 iteration -= 1; 12278 } 12279 12280 requestAnimationFrame( function() { 12281 if(self.state.stop) return; 12282 move( 0, mode ); 12283 }); 12284 }; 12285 12286 play = function( startProg ) { 12287 12288 var $nextSlide = $(self.slides[ self.nextId(self.state.moveForward ? 1 : -1) ] ); 12289 12290 // If it's Edge Slider and Lazy Load is enabled and It's not a Video Slide 12291 if ( self.config.lazyload && self.config.edgeSlider ) { 12292 12293 // Set the next slide's BG Image 12294 var $slideImg = $nextSlide.find('[data-mk-img-set]'); 12295 if ( $slideImg.length ) { 12296 MK.component.BackgroundImageSetter.init( $slideImg ); 12297 } 12298 12299 } 12300 12301 self.config.onBeforeSlide( self.nextId(self.state.moveForward ? 1 : -1) ); 12302 var start = startProg || 0; 12303 iteration = 0; 12304 self.state.stop = false; 12305 move( start, 'play' ); 12306 12307 }; 12308 12309 reverse = function( startProg ) { 12310 var start = startProg || 1; 12311 move( start, 'reverse' ); 12312 }; 12313 12314 progress = function( progVal ) { 12315 var aI = 0, 12316 currentStyle; 12317 12318 for( aI; aI < aL; aI++ ) { 12319 if( progVal !== 1 && progVal !== 0 ) { 12320 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], animLoop[ aI ][ 2 ] ); 12321 } else if( progVal === 1) { 12322 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' ); 12323 } else if ( progVal === 0 ) { 12324 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' ); 12325 } 12326 self.setStyle( animLoop[ aI ][ 0 ], currentStyle ); 12327 } 12328 }; 12329 12330 // Clear previous loop 12331 kill = function() { 12332 animLoop = []; 12333 aL = 0; 12334 }; 12335 12336 12337 return { 12338 build : build, 12339 add : add, 12340 play : play, 12341 reverse : reverse, 12342 progress : progress 12343 }; 12344 }, 12345 12346 12347 // Build reference styles. 12348 // Return object with array containig initial style and change of its value 12349 // as required for easing functions 12350 refStyle : function( toStyles, fromStyles ) { 12351 var axis = this.animation[ this.config.effect ].axis, 12352 style = {}, 12353 initVal, changeVal, endVal, dynamicEnd, styleProp, transProp, transform; 12354 12355 for( styleProp in toStyles ) { 12356 12357 if( styleProp === 'transform' ) { 12358 transform = this.getTransforms( fromStyles ); 12359 style.transform = {}; 12360 12361 for( transProp in toStyles.transform ) { 12362 // don't care about z 12363 if( transProp === 'translateZ' ) { continue; } 12364 12365 initVal = transform[ transProp ] || 0; // if it is undefined it means it's 0 12366 dynamicEnd = ( transProp === 'translate' + axis ) ? initVal : 0; 12367 endVal = toStyles.transform[ transProp ] + dynamicEnd; // it is dynamic, based on slide position in current set 12368 changeVal = endVal - initVal; 12369 style.transform[ transProp ] = [ initVal, changeVal ]; 12370 } 12371 } else if( styleProp === 'zIndex' ) { 12372 // console.log( 'z' ); 12373 continue; 12374 } else { 12375 initVal = parseFloat( fromStyles[ styleProp ] ) || 0; // if it is undefined it means it's 0 12376 endVal = toStyles[ styleProp ]; 12377 changeVal = endVal - initVal; 12378 style[ styleProp ] = [ initVal, changeVal ]; 12379 } 12380 } 12381 12382 return style; 12383 }, 12384 12385 12386 currentStyle : function( progress, style, ease ) { 12387 var self = this, 12388 currentStyle = {}, 12389 currentVals, styleProp, transProp, prog; 12390 12391 // Redo same loop but construct currentStyle object out of cached values 12392 for( styleProp in style ) { 12393 12394 if( styleProp === 'transform' ) { 12395 currentStyle.transform = {}; 12396 12397 for( transProp in style.transform ) { 12398 // remove this line. double check first if needed by logging 12399 if( transProp === 'translateZ' ) { continue; } 12400 12401 currentVals = style.transform[ transProp ]; 12402 currentStyle.transform[ transProp ] = 12403 // (currentIteration, startValue, changeInValue, totalIterations) 12404 self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 ); 12405 } 12406 } else { 12407 currentVals = style[ styleProp ]; 12408 currentStyle[ styleProp ] = 12409 self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 ); 12410 } 12411 } 12412 12413 return currentStyle; 12414 }, 12415 12416 12417 setActive : function( id ) { 12418 var $slides = $( this.slides ), 12419 className = this.config.activeClass; 12420 12421 $slides.removeClass( className ); 12422 12423 if( this.config.hasPagination ) { 12424 var $pagination = this.$pagination.find( 'a' ); 12425 $pagination.removeClass( className ); 12426 $pagination.eq( id ).addClass( className ); 12427 } 12428 12429 if( this.activeTimer ) { 12430 clearTimeout( this.activeTimer ); 12431 if ( this.imageLoader ) { 12432 this.imageLoader.abort(); 12433 } 12434 } 12435 12436 12437 var self = this; 12438 12439 this.activeTimer = setTimeout( function() { 12440 12441 var $currentSlide = $slides.eq( id ); 12442 12443 if ( self.config.lazyload && self.config.edgeSlider ) { // If it's Edge Slider and Lazy Load is enabled 12444
12445 if ( $currentSlide.find('.mk-section-video').length && $currentSlide.children('.mk-video-section-touch').length ) { // If it's a Video Slide and has a Preview image 12446 12447 var imgSet = $currentSlide.children('.mk-video-section-touch').data('mk-img-set'); 12448 var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet ); 12449 var $bgImage = $('<img>').attr('src', exactImg ); 12450 12451 self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) { 12452 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12453 setTimeout( function() { 12454 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12455 }, 200); 12456 $currentSlide.addClass( className ); 12457 }); 12458 12459 } else if ( $currentSlide.find('.mk-section-video').length && $currentSlide.children('.mk-video-section-touch').length === 0 ) { // If it's a Video Slide and has NOT a Preview image 12460 12461 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12462 setTimeout( function() { 12463 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12464 }, 200); 12465 $currentSlide.addClass( className ); 12466 12467 } else { // If it's a Image Slide 12468 12469 if ( $currentSlide.children('[data-mk-img-set]').length ) { 12470 // Get the matching Image URL to start lazy loading 12471 var imgSet = $currentSlide.children('[data-mk-img-set]').data('mk-img-set'); 12472 var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet ); 12473 var $bgImage = $('<img>').attr('src', exactImg ); 12474 12475 // Prevent counting time on slide until the image loads 12476 self.unsetTimer(); 12477 self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) { 12478 // Hide spinner, Continue counting time on slide and show the content 12479 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12480 setTimeout( function() { 12481 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12482 }, 200); 12483 self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) ); 12484 $currentSlide.addClass( className ); 12485 }); 12486 } else { 12487 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12488 setTimeout( function() { 12489 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12490 }, 200); 12491 self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) ); 12492 $currentSlide.addClass( className ); 12493 } 12494 12495 } 12496 12497 } else { 12498 12499 $currentSlide.addClass( className ); 12500 12501 } 12502 12503 12504 }, this.config.transitionTime ); 12505 }, 12506 12507 createTimer : function() { 12508 12509 var $slide = $(this), 12510 video = $slide.find('video').get(0); 12511 12512 if(video) { 12513 // A hacky but reliable way to ge the video duration 12514 var interval = setInterval( function() { 12515 // If the metadata is ready 12516 if ( video.readyState > 0 ) { 12517 $slide.data('timer', (video.duration * 1000)); 12518 $slide.attr('data-timer', (video.duration * 1000)); 12519 clearInterval(interval); 12520 } 12521 }, 100); 12522 } 12523 12524 }, 12525 12526 setTimer : function( isFirst, isPaused, fixed_time ) { 12527 // check for custom timer 12528 var customTimer = this.$slides.eq(this.nextId(this.state.moveForward ? 1 : -1)).data('timer'), 12529 trans = parseInt( this.config.transitionTime ), 12530 interval = customTimer ? customTimer : parseInt( this.config.displayTime ), 12531 timer = interval + trans; 12532 12533 var self = this, 12534 first = isFirst || true, 12535 fixed_time = fixed_time || 0, 12536 create, run; 12537 12538 this.timer = true; 12539 this.lastSetTimer = Date.now(); 12540 12541 create = function() { 12542 12543 if( self.autoplay ) { clearTimeout( self.autoplay ); } 12544 if( !self.timer ) { 12545 return; 12546 } 12547 self.state.moveForward = true; 12548 self.timeline.build(); 12549 self.timeline.play(); 12550 self.setActive( self.nextId( 1 ) ); 12551 if( self.config.fluidHeight ) { self.setHeight( self.nextId( 1 ) ); } 12552 first = false; 12553 self.lastSetTimer = Date.now(); 12554 12555 run(); 12556 }; 12557 12558 run = function(newInterval) { 12559 // check for custom timer 12560 customTimer = self.$slides.eq(self.nextId(self.state.moveForward ? 1 : -1)).data('timer'); 12561 interval = customTimer ? customTimer : parseInt( self.config.displayTime ); 12562 timer = interval + trans; // update timer with current val 12563 12564 var time = newInterval || timer; 12565 self.autoplay = setTimeout( create, time ); 12566 }; 12567 12568 if ( fixed_time ) { 12569 run( fixed_time ); 12570 } else if (isPaused) { 12571 run( this.timerRemaining ); 12572 } else { 12573 run(); 12574 } 12575 }, 12576 12577 12578 unsetTimer : function() { 12579 this.timer = false;
12580 this.lastUnsetTimer = Date.now(); 12581 this.timerRemaining -= this.lastUnsetTimer - this.lastSetTimer; 12582 if( this.autoplay ) { clearTimeout( this.autoplay ); } 12583 }, 12584 12585 12586 buildPagination : function() { 12587 var i = 0, 12588 len = this.slides.length, 12589 tpl = ''; 12590 12591 for( ; i < len; i += 1 ) { 12592 tpl += '<a href="javascript:;">' + this.config.paginationTpl + '</a>'; 12593 } 12594 12595 this.$pagination.html( tpl ); 12596 this.setActive( 0 ); 12597 }, 12598 12599 12600 getSlideSize : function() { 12601 this.slideSize = { 12602 X: 100 / this.config.slidesPerView, 12603 Y: 100 / this.config.slidesPerView 12604 }; 12605 }, 12606 12607 12608 getTransforms : function( style ) { 12609 // console.log( style ); 12610 var transform = style.transform || style.webkitTransform || style.mozTransform, 12611 regex = /(\w+)\(([^)]*)\)/g, 12612 match, 12613 T = {}; 12614 12615 if( typeof transform !== 'string' ) { 12616 throw 'Transform prop is not a string.'; 12617 } 12618 12619 if( !transform ) { return; } 12620 12621 // Run regex assignment 12622 while( match = regex.exec( transform ) ) { 12623 T[ match[ 1 ] ] = parseFloat( match[ 2 ] ); 12624 } 12625 12626 return T; 12627 }, 12628 12629 isNode : function( o ) { 12630 return ( 12631 typeof Node === "object" ? o instanceof Node : 12632 o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string" 12633 ); 12634 }, 12635 12636 12637 dragHandler : function() { 12638 var self = this, 12639 $container = $( this.container ), 12640 prevBuild = false, 12641 nextBuild = false, 12642 dragging = false, 12643 buffor = 5, // helpful for decoupling with click events 12644 dragStart, dragMove, dragEnd, progress; 12645 12646 progress = function( moveX ) { 12647 return moveX / self.val.viewportW(); 12648 }; 12649 12650 dragStart = function( moveX, startX ) { 12651 // console.log( 'start', moveX, startX ); 12652 }; 12653 12654 dragMove = function( moveX ) { 12655 // console.log('move'); 12656 if( self.state.running ) return; 12657 12658 // Don't need to check for existance here 12659 12660 if( moveX < -buffor ) { 12661 12662 if( !nextBuild ) { 12663 self.state.moveForward = true; 12664 self.timeline.build(); 12665 nextBuild = true; 12666 prevBuild = false; 12667 self.unsetTimer(); 12668 } else { 12669 // turn progress into positive val 12670 self.timeline.progress( -progress( moveX ) ); 12671 } 12672 dragging = true; 12673 } else if( moveX > buffor ) { 12674 12675 if( !prevBuild ) { 12676 self.state.moveForward = false; 12677 self.timeline.build(); 12678 prevBuild = true; 12679 nextBuild = false; 12680 self.unsetTimer(); 12681 } else { 12682 self.timeline.progress( progress( moveX ) ); 12683 } 12684 dragging = true; 12685 } 12686 }; 12687 12688 dragEnd = function( moveX ) { 12689 if( dragging ) { 12690 var prog = progress( moveX ), 12691 absProg = prog < 0 ? -prog : prog; 12692 12693 if( absProg > 0.1 ) { 12694 self.timeline.play( absProg ); 12695 self.setActive( self.nextId( prog < 0 ? 1 : -1 ) ); 12696 if( self.config.fluidHeight ) { self.setHeight( self.nextId( prog < 0 ? 1 : -1 ) ); } 12697 } else { 12698 self.timeline.reverse( absProg ); 12699 // eventually move this to reverse callbacks 12700 if(prog < 0) { 12701 self.updateId( -1 ); 12702 } else { 12703 self.updateId( 1 ); 12704 } 12705 } 12706 12707 prevBuild = false; 12708 nextBuild = false; 12709 dragging = false; 12710 if( self.config.autoplay ) { self.setTimer( false ); } 12711 } 12712 }; 12713 12714 this.drag( $container, dragStart, dragMove, dragEnd ); 12715 }, 12716 12717 12718 drag : function( $el, startFn, moveFn, stopFn ) { 12719 12720 var touchX, touchY, movX, movY, go, evt, 12721 prevent, start, move, stop; 12722 12723 prevent = function( e ) { 12724 e.preventDefault(); 12725 }; 12726 12727 start = function( e ) { 12728 // $el.on("touchmove", prevent); 12729 $el.on("mousemove", prevent); 12730 $el.on("touchmove", move); 12731 $el.on("mousemove", move); 12732 12733 evt = (e.type === 'touchstart') ? e.originalEvent.touches[0] : e; 12734 touchX = evt.pageX; 12735 12736 if(typeof startFn === 'function') { 12737 startFn(movX, touchX); 12738 } 12739 }; 12740 12741 move = function( e ) { 12742 evt = (e.type === 'touchmove') ? e.originalEvent.touches[0] : e; 12743 movX = evt.pageX - touchX; 12744 12745 if(typeof moveFn === 'function') { 12746 moveFn(movX); 12747 } 12748 }; 12749 12750 stop = function( e ) { 12751 // $el.off("touchmove", prevent); 12752 $el.off("mousemove", prevent); 12753 $el.off("touchmove", move); 12754 $el.off("mousemove", move); 12755 12756 if(typeof stopFn === 'function') { 12757 stopFn(movX); 12758 } 12759 }; 12760 12761 $el.on("touchstart", start); 12762 $el.on("mousedown", start); 12763 $el.on("touchend", stop); 12764 $el.on("touchleave", stop); 12765 $el.on("touchcancel", stop);
12766 $el.on("mouseup", stop); 12767 $el.on("mouseleave", stop); 12768 }, 12769 12770 12771 dynamicVal : function() { 12772 var $window = $( window ), 12773 update, 12774 getViewportW, viewportW; 12775 12776 update = function() { 12777 viewportW = $window.width(); 12778 }; 12779 12780 getViewportW = function() { 12781 return viewportW; 12782 }; 12783 12784 update(); 12785 $window.on( 'load', update ); 12786 $window.on( 'resize', update ); 12787 12788 return { 12789 viewportW : getViewportW 12790 }; 12791 } 12792 }; 12793 12794 12795 12796 // 12797 // Set of default animations 12798 // 12799 // ///////////////////////////////////////////////////////// 12800 12801 MK.ui.Slider.prototype.animation = { 12802 12803 slide : { 12804 axis : 'X', 12805 next : { transform: {} }, 12806 active : { transform: {} }, 12807 prev : { transform: {} } 12808 }, 12809 12810 vertical_slide : { 12811 axis : 'Y', 12812 next : { transform: {} }, 12813 active : { transform: {} }, 12814 prev : { transform: {} } 12815 }, 12816 12817 perspective_flip : { 12818 axis : 'Y', 12819 next : { 12820 transform: { 12821 rotateX : 80 12822 } 12823 }, 12824 active : { 12825 transform: { 12826 rotateX : 0 12827 } 12828 }, 12829 prev : { 12830 transform: { 12831 rotateX : 0 12832 } 12833 } 12834 }, 12835 12836 zoom : { 12837 axis : 'Z', 12838 next: { 12839 opacity : 0, 12840 transform : { 12841 scale : 0.9 12842 } 12843 }, 12844 active: { 12845 opacity : 1, 12846 transform : { 12847 scale : 1 12848 } 12849 }, 12850 prev: { 12851 opacity : 0, 12852 transform : { 12853 scale : 1.1 12854 } 12855 } 12856 }, 12857 12858 fade : { 12859 axis : 'Z', 12860 next: { 12861 opacity : 0, 12862 transform : {} 12863 }, 12864 active: { 12865 opacity : 1, 12866 transform : {} 12867 }, 12868 prev: { 12869 opacity : 0, 12870 transform : {} 12871 } 12872 }, 12873 12874 kenburned : { 12875 axis : 'Z', 12876 next: { 12877 opacity : 0, 12878 transform : {} 12879 }, 12880 active: { 12881 opacity : 1, 12882 transform : {} 12883 }, 12884 prev: { 12885 opacity : 0, 12886 transform : {} 12887 } 12888 }, 12889 12890 zoom_out : { 12891 axis : 'Z', 12892 next: { 12893 zIndex : '+', 12894 opacity : 1, 12895 transform : { 12896 translateY : 100, 12897 scale : 1 12898 } 12899 }, 12900 active: { 12901 opacity : 1, 12902 transform : { 12903 translateY : 0, 12904 scale : 1 12905 } 12906 }, 12907 prev: { 12908 zIndex : '+', 12909 opacity : 0, 12910 transform : { 12911 translateY : 0, 12912 scale : 0.5 12913 } 12914 } 12915 }, 12916 12917 // Problem with Z-Flow 12918 horizontal_curtain : { 12919 axis : 'Z', 12920 next: { 12921 zIndex : '+', 12922 transform : { 12923 translateX : 100, 12924 } 12925 }, 12926 active: { 12927 transform : { 12928 translateX : 0, 12929 } 12930 }, 12931 prev: { 12932 zIndex : '+', 12933 transform : { 12934 translateX : -70, 12935 } 12936 } 12937 }, 12938 12939 roulete : { 12940 axis : 'X', 12941 next: { 12942 opacity : 0.5, 12943 transform : { 12944 scale : 0.5, 12945 rotate : 10, 12946 translateY : 20 12947 } 12948 }, 12949 active: { 12950 opacity : 1, 12951 transform : { 12952 scale : 1, 12953 rotate : 0, 12954 translateY : 0 12955 } 12956 }, 12957 prev: { 12958 opacity : 0.3, 12959 transform : { 12960 scale : 0.5, 12961 rotate : -10, 12962 translateY : 20 12963 } 12964 } 12965 } 12966 }; 12967 12968 12969 12970 // 12971 // Penner's easing library 12972 // 12973 // ///////////////////////////////////////////////////////// 12974 12975 MK.ui.Slider.prototype.ease = { 12976 /* 12977 *
12978 * TERMS OF USE - EASING EQUATIONS 12979 * 12980 * Open source under the BSD License. 12981 * 12982 * Copyright © 2001 Robert Penner 12983 * All rights reserved. 12984 * 12985 * Redistribution and use in source and binary forms, with or without modification, 12986 * are permitted provided that the following conditions are met: 12987 * 12988 * Redistributions of source code must retain the above copyright notice, this list of 12989 * conditions and the following disclaimer. 12990 * Redistributions in binary form must reproduce the above copyright notice, this list 12991 * of conditions and the following disclaimer in the documentation and/or other materials 12992 * provided with the distribution. 12993 * 12994 * Neither the name of the author nor the names of contributors may be used to endorse 12995 * or promote products derived from this software without specific prior written permission. 12996 * 12997 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 12998 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 12999 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 13000 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 13001 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 13002 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 13003 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 13004 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 13005 * OF THE POSSIBILITY OF SUCH DAMAGE. 13006 * 13007 */ 13008 linearEase : function(currentIteration, startValue, changeInValue, totalIterations) { 13009 return changeInValue * currentIteration / totalIterations + startValue; 13010 }, 13011 13012 easeInQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13013 return changeInValue * (currentIteration /= totalIterations) * currentIteration + startValue; 13014 }, 13015 13016 easeOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13017 return -changeInValue * (currentIteration /= totalIterations) * (currentIteration - 2) + startValue; 13018 }, 13019 13020 easeInOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13021 if ((currentIteration /= totalIterations / 2) < 1) { 13022 return changeInValue / 2 * currentIteration * currentIteration + startValue; 13023 } 13024 return -changeInValue / 2 * ((--currentIteration) * (currentIteration - 2) - 1) + startValue; 13025 }, 13026 13027 easeInCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13028 return changeInValue * Math.pow(currentIteration / totalIterations, 3) + startValue; 13029 }, 13030 13031 easeOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13032 return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue; 13033 }, 13034 13035 easeInOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13036 if ((currentIteration /= totalIterations / 2) < 1) { 13037 return changeInValue / 2 * Math.pow(currentIteration, 3) + startValue; 13038 } 13039 return changeInValue / 2 * (Math.pow(currentIteration - 2, 3) + 2) + startValue; 13040 }, 13041 13042 easeInQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13043 return changeInValue * Math.pow (currentIteration / totalIterations, 4) + startValue; 13044 }, 13045 13046 easeOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13047 return -changeInValue * (Math.pow(currentIteration / totalIterations - 1, 4) - 1) + startValue; 13048 }, 13049 13050 easeInOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13051 if ((currentIteration /= totalIterations / 2) < 1) { 13052 return changeInValue / 2 * Math.pow(currentIteration, 4) + startValue; 13053 } 13054 return -changeInValue/2 * (Math.pow(currentIteration - 2, 4) - 2) + startValue; 13055 }, 13056 13057 easeInQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13058 return changeInValue * Math.pow (currentIteration / totalIterations, 5) + startValue; 13059 }, 13060 13061 easeOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13062 return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 5) + 1) + startValue; 13063 }, 13064 13065 easeInOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13066 if ((currentIteration /= totalIterations / 2) < 1) { 13067 return changeInValue / 2 * Math.pow(currentIteration, 5) + startValue; 13068 } 13069 return changeInValue / 2 * (Math.pow(currentIteration - 2, 5) + 2) + startValue; 13070 }, 13071 13072 easeInSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13073 return changeInValue * (1 - Math.cos(currentIteration / totalIterations * (Math.PI / 2))) + startValue; 13074 }, 13075 13076 easeOutSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13077 return changeInValue * Math.sin(currentIteration / totalIterations * (Math.PI / 2)) + startValue; 13078 }, 13079 13080 easeInOutSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13081 return changeInValue / 2 * (1 - Math.cos(Math.PI * currentIteration / totalIterations)) + startValue; 13082 }, 13083 13084 easeInExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13085 return changeInValue * Math.pow(2, 10 * (currentIteration / totalIterations - 1)) + startValue; 13086 }, 13087 13088 easeOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13089 return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue; 13090 }, 13091 13092 easeInOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13093 if ((currentIteration /= totalIterations / 2) < 1) { 13094 return changeInValue / 2 * Math.pow(2, 10 * (currentIteration - 1)) + startValue; 13095 } 13096 return changeInValue / 2 * (-Math.pow(2, -10 * --currentIteration) + 2) + startValue; 13097 }, 13098 13099 easeInCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13100 return changeInValue * (1 - Math.sqrt(1 - (currentIteration /= totalIterations) * currentIteration)) + startValue; 13101 }, 13102 13103 easeOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13104 return changeInValue * Math.sqrt(1 - (currentIteration = currentIteration / totalIterations - 1) * currentIteration) + startValue; 13105 }, 13106 13107 easeInOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13108 if ((currentIteration /= totalIterations / 2) < 1) { 13109 return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue; 13110 } 13111 return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue; 13112 } 13113 }; 13114 13115})(jQuery); 13116/* Social Share */ 13117/* -------------------------------------------------------------------- */ 13118(function($) { 13119 'use strict'; 13120 13121 MK.component.SocialShare = function( el ) { 13122 var networks = { 13123 twitter : 'http://twitter.com/intent/tweet?text={title}&url={url}', 13124 pinterest : 'http://pinterest.com/pin/create/button/?url={url}&media={image}&description={title}', 13125 facebook : 'https://www.facebook.com/sharer/sharer.php?u={url}', 13126 googleplus : 'https://plus.google.com/share?url={url}', 13127 linkedin : 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&summary={desc}', 13128 digg : 'http://digg.com/submit?url={url}&title={title}', 13129 reddit : 'http://reddit.com/submit?url={url}&title={title}', 13130 }; 13131 13132 this.networks = networks; 13133 this.el = el; 13134 }; 13135 13136
13137 MK.component.SocialShare.prototype = { 13138 13139 init : function() { 13140 this.cacheElements(); 13141 this.bindEvents(); 13142 }, 13143 13144 cacheElements : function() { 13145 this.$this = $( this.el ); 13146 13147 13148 }, 13149 13150 bindEvents : function() { 13151 var thisObject = this; 13152 var tempClass = ""; 13153 $.each(this.networks, function( key, value ) { 13154 thisObject.$tempClass = $('.' + key + '-share'); 13155 thisObject.$tempClass.click(thisObject.openSharingDialog.bind(self, this, key)); 13156 13157 }); 13158 }, 13159 13160 openSharingDialog : function(url, site, args) { 13161 var urlWrapper = url; 13162 var rx = new RegExp('\{[a-z]*\}','g'), res; 13163 var match = rx.exec(url); 13164 while (match != null) { 13165 var pureAttr = match[0].replace("{", "").replace("}" , ""); 13166 var attValue = $(args.currentTarget).attr('data-' + pureAttr); 13167 if (attValue === undefined || attValue === null) { 13168 attValue = ""; 13169 } 13170 attValue = attValue.replace('#', '%23'); // fix for twitter description 13171 urlWrapper = urlWrapper.replace(match, attValue); 13172 match = rx.exec(url); 13173 } 13174 13175 window.open(urlWrapper, site + "Window", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13176 13177 }, 13178 13179 13180 }; 13181 13182 13183 ////////////////////////////////////////// 13184 // 13185 // Apply to: 13186 // 13187 // /////////////////////////////////////// 13188 13189 var $body = $('body'); 13190 13191 if(!$body.length) return; 13192 13193 $body.each(function() { 13194 var socialShare = new MK.component.SocialShare(this); 13195 socialShare.init(); 13196 }); 13197 13198})(jQuery); 13199 13200 13201 13202//function mk_social_share() { 13203// 13204// "use strict";
13205// 13206// $('.twitter-share').on('click', function () { 13207// var $url = $(this).attr('data-url'), 13208// $title = $(this).attr('data-title'); 13209// 13210// window.open('http://twitter.com/intent/tweet?text=' + $title + ' ' + $url, "twitterWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13211// return false; 13212// }); 13213// 13214// $('.pinterest-share').on('click', function () { 13215// var $url = $(this).attr('data-url'), 13216// $title = $(this).attr('data-title'), 13217// $image = $(this).attr('data-image'); 13218// window.open('http://pinterest.com/pin/create/button/?url=' + $url + '&media=' + $image + '&description=' + $title, "twitterWindow", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13219// return false; 13220// }); 13221// 13222// $('.facebook-share').on('click', function () { 13223// var $url = $(this).attr('data-url'); 13224// window.open('https://www.facebook.com/sharer/sharer.php?u=' + $url, "facebookWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13225// return false; 13226// }); 13227// 13228// $('.googleplus-share').on('click', function () { 13229// var $url = $(this).attr('data-url'); 13230// window.open('https://plus.google.com/share?url=' + $url, "googlePlusWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13231// return false; 13232// }); 13233// 13234// $('.linkedin-share').on('click', function () { 13235// var $url = $(this).attr('data-url'), 13236// $title = $(this).attr('data-title'), 13237// $desc = $(this).attr('data-desc'); 13238// window.open('http://www.linkedin.com/shareArticle?mini=true&url=' + $url + '&title=' + $title + '&summary=' + $desc, "linkedInWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13239// return false; 13240// }); 13241//} 13242 13243 13244 13245 13246(function($) { 13247 'use strict'; 13248 13249 MK.component.Sortable = function(el) { 13250 this.el = el; 13251 }; 13252 13253 MK.component.Sortable.prototype = { 13254 init: function init() { 13255 this.cacheElements(); 13256 this.bindEvents(); 13257 }, 13258 13259 cacheElements: function cacheElements() { 13260 this.unique = Date.now(); 13261 this.$filter = $(this.el); 13262 this.config = this.$filter.data('sortable-config'); 13263 13264 this.ajaxLoader = new MK.utils.ajaxLoader(this.config.container); 13265 this.ajaxLoader.init(); 13266 13267 this.$container = $( this.config.container ); 13268 this.$navItems = this.$filter.find('a'); 13269 this.$filterItems = this.$container.find(this.config.item); 13270 }, 13271 13272 bindEvents: function bindEvents() { 13273 this.$navItems.on('click', this.handleClick.bind(this)); 13274 MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this)); 13275 }, 13276 13277 handleClick: function handleClick(e) { 13278 e.preventDefault(); 13279 13280 var $item = $(e.currentTarget); 13281 var term = $item.data('filter'); 13282 13283 this.$navItems.removeClass('current'); 13284 $item.addClass('current'); 13285 13286 if(this.config.mode === 'ajax') this.inDB(term, $item); 13287 else this.inPage(term); 13288 }, 13289 13290 inDB: function inDB(term, $item) { 13291 // Add load indicator only for long requests 13292 MK.ui.loader.remove(this.$filter); 13293 MK.ui.loader.add($item); 13294 13295 // If mk-ajax-loaded-posts span exists and one of the filter is clicked, 13296 // clear post ids 13297 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 13298 this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', ''); 13299 } 13300 13301 this.ajaxLoader.setData({ 13302 paged: 1, 13303 term: term 13304 }); 13305 this.ajaxLoader.load(this.unique); 13306 }, 13307 13308 inPage: function inPage(term) { 13309 var $filterItems = this.$container.find(this.config.item); 13310 $filterItems.removeClass('is-hidden'); // show all first 13311 // Replace all ', ' with ', .'. It's used to add '.' as class selector of each category. 13312 var className = term.replace( /, /g, ", ." ); 13313 if(term !== '*') $filterItems.not( '.' + className ).addClass('is-hidden'); // hide filtered 13314 MK.utils.eventManager.publish('staticFilter'); 13315 }, 13316 13317 onLoad: function onLoad(e, response) { 13318 if(this.config.mode === 'static') { 13319 this.$navItems.removeClass('current').first().addClass('current'); 13320 } 13321 if( typeof response !== 'undefined' && response.id === this.config.container) { 13322 MK.ui.loader.remove(this.$filter); 13323 if(response.unique === this.unique) { 13324 this.$container.html(response.content); 13325 this.ajaxLoader.setData({paged: 1}); 13326 } 13327 } 13328 } 13329 }; 13330 13331})(jQuery); 13332(function($) { 13333 'use strict'; 13334 13335 MK.component.Tabs = function( el ) { 13336 var defaults = { 13337 activeClass : 'is-active' 13338 }; 13339 13340 this.config = defaults; 13341 this.el = el; 13342 }; 13343 13344 MK.component.Tabs.prototype = { 13345 13346 init : function() { 13347 this.cacheElements(); 13348 this.bindEvents(); 13349 }, 13350 13351 cacheElements : function() { 13352 this.$this = $( this.el ); 13353 this.$tabs = this.$this.find( '.mk-tabs-tab' ); 13354 this.$panes = this.$this.find( '.mk-tabs-pane' ); 13355 this.currentId = 0; 13356 }, 13357 13358 bindEvents : function() { 13359 var self = this; 13360 13361 this.$tabs.on( 'click', this.switchPane.bind( this ) ); 13362 }, 13363 13364 switchPane : function( evt ) { 13365 evt.preventDefault(); 13366 13367 var clickedId = $( evt.currentTarget ).index(); 13368 13369 this.hide( this.currentId ); 13370 this.show( clickedId ); 13371 13372 // Update current id 13373 this.currentId = clickedId; 13374 13375 // Notify rest of the app 13376 MK.utils.eventManager.publish('item-expanded'); 13377 }, 13378 13379 show : function( id ) { 13380 this.$tabs.eq( id ).addClass( this.config.activeClass ); 13381 this.$panes.eq( id ).addClass( this.config.activeClass ); 13382 }, 13383 13384 hide : function( id ) { 13385 this.$tabs.eq( id ).removeClass( this.config.activeClass ); 13386 this.$panes.eq( id ).removeClass( this.config.activeClass ); 13387 } 13388 }; 13389 13390})(jQuery); 13391 13392 13393/* Tabs */ 13394/* -------------------------------------------------------------------- */ 13395 13396function mk_tabs() { 13397 13398 // "use strict"; 13399 13400 // if ($.exists('.mk-tabs, .mk-news-tab, .mk-woo-tabs')) { 13401 // $(".mk-tabs, .mk-news-tab, .mk-woo-tabs").tabs(); 13402 13403 // $('.mk-tabs').on('click', function () { 13404 // $('.mk-theme-loop').isotope('layout'); 13405 // }); 13406 13407 // $('.mk-tabs.vertical-style').each(function () { 13408 // $(this).find('.mk-tabs-pane').css('minHeight', $(this).find('.mk-tabs-tabs').height() - 1); 13409 // }); 13410 13411 // } 13412} 13413 13414function mk_tabs_responsive(){ 13415 // $('.mk-tabs, .mk-news-tab').each(function () { 13416 // $this = $(this); 13417 // if ($this.hasClass('mobile-true')) { 13418 // if (window.matchMedia('(max-width: 767px)').matches) 13419 // { 13420 // $this.tabs("destroy"); 13421 // } else { 13422 // $this.tabs(); 13423 // } 13424 // } 13425 // }); 13426 13427} 13428 13429 13430(function($) { 13431 'use strict'; 13432 13433 $(document).on('click', function(e) { 13434 $('.mk-toggle-trigger').removeClass('mk-toggle-active'); 13435 }); 13436 13437 function toggle(e) { 13438 e.preventDefault(); 13439 e.stopPropagation(); 13440 var $this = $(e.currentTarget); 13441 13442 if (!$this.hasClass('mk-toggle-active')) { 13443 13444 $('.mk-box-to-trigger').fadeOut(200); 13445 $this.parent().find('.mk-box-to-trigger').fadeIn(250); 13446 $('.mk-toggle-trigger').removeClass('mk-toggle-active'); 13447 $this.addClass('mk-toggle-active'); 13448 13449 } else { 13450 13451 $('.mk-box-to-trigger').fadeOut(200); 13452 $this.removeClass('mk-toggle-active'); 13453 13454 } 13455 } 13456 13457 function assignToggle() { 13458 // wait for ajax response propagation and insertion 13459 setTimeout(function() { 13460 $('.mk-toggle-trigger').off('click', toggle); 13461 $('.mk-toggle-trigger').on('click', toggle); 13462 }, 100); 13463 } 13464 13465 assignToggle(); 13466 MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle); 13467 MK.utils.eventManager.subscribe('ajax-preview', assignToggle); 13468 13469 $(window).on('vc_reload', function(){ 13470 assignToggle(); 13471 MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle); 13472 MK.utils.eventManager.subscribe('ajax-preview', assignToggle); 13473 }); 13474 13475}(jQuery)); 13476(function($) { 13477 'use strict'; 13478 13479 var $iframes = $('iframe'); 13480 13481 $iframes.each(function() { 13482 var $iframe = $(this); 13483 var parent = $iframe.parent().get(0); 13484 var tagName = parent.tagName; 13485 13486 if(tagName === 'P') $iframe.wrap('<div class="mk-video-container"></div>'); 13487 }); 13488 13489}(jQuery)); 13490(function( $ ) { 13491 'use strict'; 13492 if( MK.utils.isMobile() ) { 13493 $('.mk-animate-element').removeClass('mk-animate-element'); 13494 return; 13495 }
13496 var init = function init() { 13497 var $rootLevelEls = $('.js-master-row, .widget'); 13498 $rootLevelEls.each( spyViewport ); 13499 $rootLevelEls.each( function rootLevelEl() { 13500 var $animateEl = $(this).find( '.mk-animate-element' ); 13501 $animateEl.each( spyViewport ); 13502 /** 13503 * Firefox has known issue where horizontal scrollbar will appear if an 13504 * element uses animation CSS. The solution should be set the element 13505 * position as fixed or overflow-x as hidden. Position fixed is not possible 13506 * to use because it's only cause other big problems. The best way is 13507 * set overflow-x as hidden in the page content container #theme-page. 13508 * 13509 * NOTE: The problem is spotted on Right To Left viewport only. So, it's 13510 * limited to '.right-to-left' selector only for now to avoid other 13511 * problems. Please extend the functionallity if it's happen in 13512 * other viewport animation effect. 13513 */ 13514 var browserName = MK.utils.browser.name; 13515 if ( browserName === 'Firefox' ) { 13516 var $rightToLeft = $( this ).find( '.right-to-left' ); 13517 if ( $rightToLeft.length > 0 ) { 13518 $( '#theme-page' ).css( 'overflow-x', 'hidden' ); 13519 } 13520 } 13521 }); 13522 }; 13523 var spyViewport = function spyViewport(i) { 13524 var self = this; 13525 MK.utils.scrollSpy( this, { 13526 position : 'bottom', 13527 threshold : 200, 13528 after : function() { 13529 animate.call(self, i); 13530 } 13531 }); 13532 }; 13533 var animate = function animate(i) { 13534 var $this = $(this); 13535 setTimeout(function() { 13536 $this.addClass( 'mk-in-viewport' ); 13537 }, 100 * i); 13538 }; 13539 $(window).on('load vc_reload', init); 13540}(jQuery)); 13541 13542function product_loop_add_cart() { 13543 var $body = $('body'); 13544 $body.on('click', '.add_to_cart_button', function() { 13545 var icon = '<svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M437.011 74.99c-46.326-46.328-110.318-74.99-181.011-74.99-109.744 0-203.345 69.064-239.749 166.094l59.938 22.477c27.302-72.773 97.503-124.571 179.811-124.571 53.02 0 101.01 21.5 135.753 56.247l-71.753 71.753h192v-192l-74.989 74.99zm-181.011 373.01c-53.02 0-101.013-21.496-135.756-56.244l71.756-71.756h-192v192l74.997-74.997c46.323 46.331 110.309 74.997 181.003 74.997 109.745 0 203.346-69.064 239.75-166.094l-59.938-22.477c-27.302 72.773-97.503 124.571-179.812 124.571z"/></svg>'; 13546 var $holder = $(this).parents('.product:eq(0)'); 13547 var $i = $holder.find('.product-loading-icon'); 13548 $holder.addClass('adding-to-cart').removeClass('added-to-cart'); 13549 $i.html(icon); 13550 }); 13551 $body.bind('added_to_cart', function() { 13552 var icon = '<svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M432 64l-240 240-112-112-80 80 192 192 320-320z"/></svg>'; 13553 var $holder = $('.adding-to-cart'); 13554 var $i = $holder.find('.product-loading-icon'); 13555 $holder.removeClass('adding-to-cart').addClass('added-to-cart'); 13556 $i.html(icon); 13557 }); 13558} 13559(function($) { 13560 'use strict'; 13561 13562 /** 13563 * Entry point of application. Runs all components 13564 */ 13565 $( window ).on( 'load', function() { 13566 MK.core.initAll( document ); 13567 MK.utils.scrollToURLHash(); 13568 // TODO move preloader to components and manage it state from within 13569 setTimeout( function() { 13570 MK.ui.preloader.hide(); // site wide 13571 $('.mk-preloader').hide(); // components 13572 $('body').removeClass('loading'); 13573 }, 150 ); 13574 }); 13575 13576 /** 13577 * VC frontend editor. Init all components. 13578 */ 13579 $( window ).on( 'vc_reload', function() { 13580 setTimeout(function(){ 13581 MK.core.initAll( document ); 13582 }, 100); 13583 }); 13584 13585 /** 13586 * Assign global click handlers 13587 */ 13588 $( document ).on( 'click', '.js-smooth-scroll, .js-main-nav a', smoothScrollToAnchor); 13589 $( '.side_dashboard_menu a' ).on( 'click', smoothScrollToAnchor); 13590 13591 function smoothScrollToAnchor( evt ) { 13592 var anchor = MK.utils.detectAnchor( this ); 13593 var $this = $(evt.currentTarget); 13594 var loc = window.location; 13595 var currentPage = loc.origin + loc.pathname; 13596 var href = $this.attr( 'href' ); 13597 var linkSplit = (href) ? href.split( '#' ) : ''; 13598 var hrefPage = linkSplit[0] ? linkSplit[0] : ''; 13599 var hrefHash = linkSplit[1] ? linkSplit[1] : ''; 13600 13601 if( anchor.length ) { 13602 if(hrefPage === currentPage || hrefPage === '') evt.preventDefault(); 13603 MK.utils.scrollToAnchor( anchor ); 13604 13605 } else if( $this.attr( 'href' ) === '#' ) { 13606 evt.preventDefault(); 13607 } 13608 } 13609 13610}(jQuery));})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.