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.toggle(that.open.bind(that), that.close.bind(that)); 6744 }; 6745 6746 Toggle.prototype.dom = { 6747 pane : 'mk-toggle-pane', 6748 active : 'active-toggle' 6749 }; 6750 6751 Toggle.prototype.open = function() { 6752 var $this = this.$el; 6753 $this.addClass(this.dom.active); 6754 $this.siblings('.' + this.dom.pane).slideDown(200); 6755 }; 6756 6757 Toggle.prototype.close = function() { 6758 var $this = this.$el; 6759 $this.removeClass(this.dom.active); 6760 $this.siblings('.' + this.dom.pane).slideUp(200); 6761 }; 6762 6763 // Apply to. 6764 var $toggle = $('.mk-toggle-title'); 6765 6766 if(!$toggle.length) return; 6767 6768 $toggle.each(function() { 6769 new Toggle(this); 6770 }); 6771 } 6772 $(window).on('load vc_reload', init); 6773 6774})(jQuery); 6775////////////////////////////////////////////////////////////////////////// 6776// 6777// Init all scripts 6778// 6779////////////////////////////////////////////////////////////////////////// 6780 6781// This is bad but we don't have other access to this scope. 6782// Ajax Portfolio is defined as plugin and on success needs these to be reinited 6783// We'll refactor all of this. 6784window.ajaxInit = function() { 6785 mk_lightbox_init(); 6786 mk_click_events(); 6787 mk_social_share_global(); 6788 // mk_social_share(); 6789 mk_gallery(); 6790 loop_audio_init(); 6791}; 6792 6793window.ajaxDelayedInit = function() { 6794 mk_flexslider_init(); 6795 // mk_portfolio_ajax(); 6796}; 6797 6798$(document).ready(function() { 6799 mk_lightbox_init(); 6800 mk_login_form(); 6801 mk_backgrounds_parallax(); 6802 mk_flexslider_init(); 6803 mk_event_countdown(); 6804 mk_skill_meter(); 6805 mk_milestone(); 6806 mk_ajax_search(); 6807 mk_hover_events(); 6808 mk_portfolio_ajax(); 6809 mk_love_post(); 6810 product_loop_add_cart(); 6811 // mk_social_share(); 6812 mk_portfolio_widget(); 6813 mk_contact_form(); 6814 mk_blog_carousel(); 6815 mk_header_searchform(); 6816 mk_click_events(); 6817 mk_text_typer(); 6818 mk_tab_slider_func(); 6819 6820 $(window).on('load', function() { 6821 mk_unfold_footer(); 6822 mk_tabs(); 6823 mk_accordion_toggles_tooltip(); 6824 mk_gallery(); 6825 mk_theatre_responsive_calculator(); 6826 mk_tabs_responsive(); 6827 mk_start_tour_resize(); 6828 mk_header_social_resize(); 6829 mk_page_section_social_video_bg(); 6830 loop_audio_init(); 6831 mk_one_page_scroller(); 6832 mkPositionSidebar(); 6833 6834 setTimeout(function() { 6835 /* 6836 Somehow the values are not correctly updated for the screens 6837 and we need to put setTimeout to fix the issue 6838 */ 6839 mk_mobile_tablet_responsive_calculator(); 6840 }, 300); 6841 6842 console.log("ready for rock"); 6843 }); 6844 6845 6846 var onDebouncedResize = function() { 6847 mk_theatre_responsive_calculator(); 6848 mk_mobile_tablet_responsive_calculator(); 6849 mk_tabs_responsive(); 6850 mk_accordion_toggles_tooltip(); 6851 mk_start_tour_resize(); 6852 mk_header_social_resize(); 6853 6854 setTimeout(function() { 6855 mk_unfold_footer(); 6856 }, 300); 6857 }; 6858 6859 var debounceResize = null; 6860 $(window).on("resize", function() { 6861 if( debounceResize !== null ) { clearTimeout( debounceResize ); } 6862 debounceResize = setTimeout( onDebouncedResize, 300 ); 6863 }); 6864 6865 var onDebouncedScroll = function() { 6866 mk_skill_meter(); 6867 //TODO: Ask to Bart how we can call javascript component 6868 //mk_charts(); 6869 mk_milestone(); 6870 }; 6871 6872 var debounceScroll = null; 6873 $(window).on("scroll", function() { 6874 if( debounceScroll !== null ) { clearTimeout( debounceScroll ); } 6875 debounceScroll = setTimeout( onDebouncedScroll, 100 ); 6876 }); 6877 6878 if (MK.utils.isMobile()) { 6879 $('body').addClass('no-transform'); 6880 } 6881 6882}); 6883 6884/* VC frontend editor */ 6885/* -------------------------------------------------------------------- */ 6886$(window).on("vc_reload",function () { 6887 mk_flexslider_init(); 6888 loop_audio_init(); 6889 mk_tab_slider_func();
6890 mk_event_countdown(); 6891 videoLoadState(); 6892 mk_page_section_social_video_bg(); 6893 mk_hover_events(); 6894 6895 setTimeout(function() { 6896 mkPositionSidebar(); 6897 }, 200); 6898}); 6899 6900// Replace this if new event for remove found. 6901$( document ).on( 'click', '.vc_control-btn-delete', function() { 6902 $( window ).trigger( 'vc_reload' ); 6903} ); 6904 6905$( document ).on( 'sortupdate', '.ui-sortable', function() { 6906 $( window ).trigger( 'vc_reload' ); 6907} ); 6908 6909/* Typer */ 6910/* -------------------------------------------------------------------- */ 6911function mk_text_typer() { 6912 6913 "use strict"; 6914 6915 $('[data-typer-targets]').each(function() { 6916 var that = this; 6917 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.typed.js' ], function() { 6918 var $this = $(that), 6919 $first_string = [$this.text()], 6920 $rest_strings = $this.attr('data-typer-targets').split(','), 6921 $strings = $first_string.concat($rest_strings); 6922 6923 $this.text(''); 6924 6925 $this.typed({ 6926 strings: $strings, 6927 typeSpeed: 30, // typing speed 6928 backDelay: 1200, // pause before backspacing 6929 loop: true, // loop on or off (true or false) 6930 loopCount: false, // number of loops, false = infinite 6931 }); 6932 }); 6933 }); 6934} 6935 6936 6937 6938/* Tab Slider */ 6939/* -------------------------------------------------------------------- */ 6940 6941function mk_tab_slider_func() { 6942 6943 "use strict"; 6944 6945 $('.mk-tab-slider').each(function() { 6946 var that = this; 6947 6948 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.swiper.js' ], function() { 6949 var $this = $(that), 6950 id = $this.data('id'), 6951 $autoplayTime = $this.data('autoplay'), 6952 $content = $('.mk-slider-content'); 6953 6954 var mk_tab_slider = $this.swiper({ 6955 wrapperClass: 'mk-tab-slider-wrapper', 6956 slideClass: 'mk-tab-slider-item', 6957 calculateHeight: true, 6958 speed: 500, 6959 autoplay: isTest ? false : $autoplayTime, 6960 onSlideChangeStart: function() { 6961 $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active') 6962 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").eq(mk_tab_slider.activeIndex).addClass('active') 6963 } 6964 }); 6965 6966 // Simple repaint for firefox issue (can't handle 100% height after plugin init) 6967 function repaintFirefox() { 6968 $content.css('display','block'); 6969 setTimeout(function() { 6970 mk_tab_slider.reInit(); 6971 $content.css('display','table'); 6972 },100); 6973 } 6974 6975 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").first().addClass('active'); 6976 6977 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").on('touchstart mousedown', function(e) { 6978 e.preventDefault() 6979 $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active') 6980 $(this).addClass('active') 6981 mk_tab_slider.swipeTo($(this).index()) 6982 }); 6983 6984 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").click(function(e) { 6985 e.preventDefault(); 6986 }); 6987 6988 repaintFirefox(); 6989 $(window).on('resize', repaintFirefox); 6990 }); 6991 6992 }); 6993 6994} 6995 6996 6997 6998/* Edge One Pager */ 6999/* -------------------------------------------------------------------- */ 7000function mk_one_page_scroller() { 7001 7002 "use strict"; 7003 7004 $('.mk-edge-one-pager').each(function() { 7005 var self = this; 7006 7007 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.fullpage.js' ], function() { 7008 7009 var $this = $(self), 7010 anchorArr = []; 7011 7012 $this.find('.section').each(function() { 7013 anchorArr.push($(this).attr('data-title')); 7014 }); 7015 7016 var scrollable = true; 7017 $this.find('.section').each(function() { 7018 var $section = $(this), 7019 $content = $section.find('.edge-slide-content'), 7020 sectionHeight = $section.height(),
7021 contentHeight = $content.innerHeight(); 7022 7023 if((contentHeight + 30) > $(window).height()) { 7024 scrollable = false; 7025 } 7026 }); 7027 7028 if(!scrollable){ 7029 $this.find('.section').each(function() { 7030 var $section = $(this); 7031 $section.addClass('active').css({ 7032 'padding-bottom': '50px' 7033 }); 7034 }); 7035 } 7036 7037 if(scrollable) { 7038 $this.fullpage({ 7039 verticalCentered: false, 7040 resize: true, 7041 slidesColor: ['#ccc', '#fff'], 7042 anchors: anchorArr, 7043 scrollingSpeed: 600, 7044 easing: 'easeInQuart', 7045 menu: false, 7046 navigation: true, 7047 navigationPosition: 'right', 7048 navigationTooltips: false, 7049 slidesNavigation: true, 7050 slidesNavPosition: 'bottom', 7051 loopBottom: false, 7052 loopTop: false, 7053 loopHorizontal: true, 7054 autoScrolling: true, 7055 scrollOverflow: false, 7056 css3: true, 7057 paddingTop: 0, 7058 paddingBottom: 0, 7059 normalScrollElements: '.mk-header, .mk-responsive-wrap', 7060 normalScrollElementTouchThreshold: 5, 7061 keyboardScrolling: true, 7062 touchSensitivity: 15, 7063 continuousVertical: false, 7064 animateAnchor: true, 7065 7066 onLeave: function(index, nextIndex, direction) { 7067 var currentSkin = $this.find('.one-pager-slide').eq(nextIndex - 1).attr('data-header-skin'); 7068 MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin ); 7069 $('#fullPage-nav').removeClass('light-skin dark-skin').addClass(currentSkin + '-skin'); 7070 7071 }, 7072 afterRender: function() { 7073 7074 var $nav = $('#fullPage-nav'); 7075 7076 setTimeout(function() { 7077 var currentSkin = $this.find('.one-pager-slide').eq(0).attr('data-header-skin'); 7078 MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin ); 7079 if($nav.length) $nav.removeClass('light-skin dark-skin').addClass(currentSkin + '-skin'); 7080 }, 300); 7081 7082 var $slide = $this.find('.section'), 7083 headerHeight = MK.val.offsetHeaderHeight(0), 7084 windowHeight = $(window).height(); 7085 7086 $slide.height(windowHeight - headerHeight); 7087 7088 if($nav.length) { 7089 $nav.css({ 7090 'top': 'calc(50% + ' + (headerHeight/2) + 'px)', 7091 'marginTop': 0 7092 }); 7093 7094 var style = $this.attr('data-pagination'); 7095 $nav.addClass('pagination-' + style); 7096 } 7097 7098 setTimeout(mk_one_pager_resposnive, 1000); 7099 }, 7100 afterResize: function() { 7101 var $slide = $this.find('.section'), 7102 headerHeight = MK.val.offsetHeaderHeight(0), 7103 windowHeight = $(window).height(); 7104 7105 $slide.height(windowHeight - headerHeight); 7106 7107 $('#fullPage-nav').css({ 7108 'top': 'calc(50% + ' + (headerHeight/2) + 'px)', 7109 'marginTop': 0 7110 }); 7111 7112 setTimeout(mk_one_pager_resposnive, 1000); 7113 console.log('Reposition pager content.'); 7114 }, 7115 }); 7116 } 7117 7118 // Linking to slides available for desktop and mobile scenarios 7119 function swipeTo(href, e) { 7120 href = '_' + href; // ensure a char before # 7121 if (!~href.indexOf('#')) return; 7122 var section = href.split('#')[1]; 7123 if (~anchorArr.indexOf(section)) { 7124 if (typeof e !== 'undefined') e.preventDefault(); 7125 if (scrollable) $.fn.fullpage.moveTo(section); 7126 else MK.utils.scrollToAnchor('[data-title="'+section+'"]'); 7127 } 7128 } 7129 7130 // onload 7131 var loc = window.location; 7132 if(loc.hash) swipeTo(loc.hash); 7133 7134 $(document).on('click', 'a', function(e) { 7135 var $link = $(e.currentTarget); 7136 swipeTo($link.attr('href'), e); 7137 }); 7138 }); 7139 }); 7140 7141 7142 7143} 7144 7145 7146function mk_one_pager_resposnive() { 7147 "use strict"; 7148 7149 $('.mk-edge-one-pager').each(function() { 7150 var $pager = $(this), 7151 headerHeight = MK.val.offsetHeaderHeight(0), 7152 windowHeight = $(window).height() - headerHeight; 7153 7154 $pager.find('.one-pager-slide').each(function() { 7155 var $slide = $(this), 7156 $content = $slide.find('.edge-slide-content'); 7157 7158 if ($slide.hasClass('left_center') || $slide.hasClass('center_center') || $slide.hasClass('right_center')) { 7159 var contentHeight = $content.height(), 7160 distanceFromTop = (windowHeight - contentHeight) / 2; 7161 7162 distanceFromTop = (distanceFromTop < 50) ? 50 + headerHeight : distanceFromTop; 7163 7164 $content.css('marginTop', distanceFromTop); 7165 } 7166 7167 if ($slide.hasClass('left_bottom') || $slide.hasClass('center_bottom') || $slide.hasClass('right_bottom')) { 7168 var distanceFromTop = windowHeight - $content.height() - 90; 7169 $content.css('marginTop', (distanceFromTop)); 7170 } 7171 }); 7172 7173 /** 7174 * Fix AM-2853 7175 * 7176 * @since 6.0.3 7177 * 7178 * At the init of Edge One Pager (EOP), EOP will render all image 7179 * background of each sections from top to bottom. In this case, 7180 * the page height will be more than screen height and the scroll 7181 * bar will appear. At the same time, the full width row will set 7182 * the container width into 100%. But, after all Slides are set up, 7183 * EOP height will be 100% of the screen height, so the scroll bar 7184 * will be disappeared. It's caused spacing issues on the left and 7185 * right side of the EOP container. To fix this, the row width 7186 * should be resized and row position should be readjusted. 7187 */ 7188 var $row = $pager.parents( '.vc_row.vc_row-fluid.mk-fullwidth-true' ); 7189 7190 // Run only if the Edge One Pager is wrapped inside full width row. 7191 if ( $row.length > 0 ) { 7192 // Set the wrapper and row width. 7193 var $wrapper = $( '.mk-main-wrapper-holder' ); 7194 var $grid = $row.children( '.mk-grid' ); 7195 var rowWidth = $row.width(); // Original width.
7196 var wrapperWidth = $wrapper.width(); // The new width. 7197 7198 // Run only if original width is smaller than the new width. 7199 if ( rowWidth >= wrapperWidth || $grid.length > 0 ) { 7200 return; 7201 } 7202 7203 // Get the content left offset. 7204 var $content = $wrapper.find( '.theme-content' ); 7205 var oriPos = $content.position(); 7206 var oriPadLeft = $content.css( 'padding-left' ); 7207 var oriLeft = parseInt( oriPos.left ) + parseInt( oriPadLeft ); 7208 7209 // Ensure the new width and left position is more than 0. 7210 if ( wrapperWidth <= 0 || oriLeft <= 0 ) { 7211 return; 7212 } 7213 7214 // Resize the width and left position of row full width. 7215 $row.css({ 7216 'width': wrapperWidth, 7217 'left': oriLeft * -1, 7218 }); 7219 } 7220 }); 7221} 7222 7223/* Image Gallery */ 7224/* -------------------------------------------------------------------- */ 7225 7226function mk_gallery() { 7227 7228 "use strict"; 7229 7230 $('.mk-gallery .mk-gallery-item.hover-overlay_layer .item-holder').each(function() { 7231 var itemHolder = $(this), 7232 galleryDesc = itemHolder.find('.gallery-desc'); 7233 7234 function updatePosition() { 7235 var parentHeight = itemHolder.outerHeight(), 7236 contentHeight = galleryDesc.innerHeight(); 7237 7238 var paddingVal = (parentHeight - contentHeight) / 2; 7239 galleryDesc.css({ 7240 'top': paddingVal, 7241 // 'padding-bottom': paddingVal 7242 }); 7243 7244 // console.log(parentHeight); 7245 // console.log(contentHeight); 7246 7247 7248 } 7249 updatePosition(); 7250 7251 $(window).on('resize', function() { 7252 setTimeout(function() { 7253 updatePosition(); 7254 }, 1000); 7255 }); 7256 }); 7257 // Execute hover state for mk gallery item 7258 if ($(window).width() <= 1024) { 7259 $('.mk-gallery .mk-gallery-item').on('click', function (e) { 7260 var clicks = $(this).data('clicks'); 7261 if (clicks) { 7262 // First click 7263 $(this).toggleClass('hover-state'); 7264 } else { 7265 // Second click 7266 $(this).toggleClass('hover-state'); 7267 } 7268 $(this).data("clicks", !clicks); 7269 }); 7270 } 7271} 7272 7273/* Theatre Slider Responsive Calculator */ 7274/* -------------------------------------------------------------------- */ 7275 7276function mk_theatre_responsive_calculator() { 7277 var $laptopContainer = $(".laptop-theatre-slider"); 7278 var $computerContainer = $(".desktop-theatre-slider"); 7279 $laptopContainer.each(function() { 7280 var $this = $(this), 7281 $window = $(window), 7282 $windowWidth = $window.outerWidth(), 7283 $windowHeight = $window.outerHeight(), 7284 $width = $this.outerWidth(), 7285 $height = $this.outerHeight(), 7286 $paddingTop = 38, 7287 $paddingRight = 143, 7288 $paddingBottom = 78, 7289 $paddingLeft = 143; 7290 7291 var $player = $this.find('.player-container'); 7292 7293 if ($windowWidth > $width) { 7294 $player.css({ 7295 'padding-left': parseInt(($width * $paddingLeft) / 1200), 7296 'padding-right': parseInt(($width * $paddingRight) / 1200), 7297 'padding-top': parseInt(($height * $paddingTop) / 690), 7298 'padding-bottom': parseInt(($height * $paddingBottom) / 690), 7299 }); 7300 } 7301 7302 }); 7303 7304 $computerContainer.each(function() { 7305 var $this = $(this), 7306 $window = $(window), 7307 $windowWidth = $window.outerWidth(), 7308 $windowHeight = $window.outerHeight(), 7309 $width = $this.outerWidth(), 7310 $height = $this.outerHeight(), 7311 $paddingTop = 60, 7312 $paddingRight = 52, 7313 $paddingBottom = 290, 7314 $paddingLeft = 49; 7315 7316 var $player = $this.find('.player-container'); 7317 7318 if ($windowWidth > $width) { 7319 $player.css({ 7320 'padding-left': parseInt(($width * $paddingLeft) / 1200), 7321 'padding-right': parseInt(($width * $paddingRight) / 1200), 7322 'padding-top': parseInt(($height * $paddingTop) / 969), 7323 'padding-bottom': parseInt(($height * $paddingBottom) / 969), 7324 }); 7325 } 7326 7327 }); 7328 7329} 7330 7331/* Mobile and Tablet Slideshow Responsive Calculator */ 7332/* -------------------------------------------------------------------- */ 7333function mk_mobile_tablet_responsive_calculator() { 7334 var $laptopSlideshow = $(".mk-laptop-slideshow-shortcode"); 7335 var $lcdSlideshow = $(".mk-lcd-slideshow"); 7336 7337 if ($.exists(".mk-laptop-slideshow-shortcode")) { 7338 $laptopSlideshow.each(function() { 7339 var $this = $(this), 7340 $window = $(window), 7341 $windowWidth = $window.outerWidth(), 7342 $windowHeight = $window.outerHeight(), 7343 $width = $this.outerWidth(), 7344 $height = $this.outerHeight(), 7345 $paddingTop = 28, 7346 $paddingRight = 102, 7347 $paddingBottom = 52, 7348 $paddingLeft = 102; 7349 7350 var $player = $this.find(".slideshow-container"); 7351 7352 $player.css({ 7353 "padding-left": parseInt(($width * $paddingLeft) / 836), 7354 "padding-right": parseInt(($width * $paddingRight) / 836), 7355 "padding-top": parseInt(($height * $paddingTop) / 481), 7356 "padding-bottom": parseInt(($height * $paddingBottom) / 481), 7357 }); 7358 7359 }); 7360 } 7361 7362 if ($.exists(".mk-lcd-slideshow")) {
7363 $lcdSlideshow.each(function() { 7364 var $this = $(this), 7365 $window = $(window), 7366 $windowWidth = $window.outerWidth(), 7367 $windowHeight = $window.outerHeight(), 7368 $width = $this.outerWidth(), 7369 $height = $this.outerHeight(), 7370 $paddingTop = 35, 7371 $paddingRight = 39, 7372 $paddingBottom = 213, 7373 $paddingLeft = 36; 7374 7375 var $player = $this.find(".slideshow-container"); 7376 $player.css({ 7377 "padding-left": parseInt(($width * $paddingLeft) / 886), 7378 "padding-right": parseInt(($width * $paddingRight) / 886), 7379 "padding-top": parseInt(($height * $paddingTop) / 713), 7380 "padding-bottom": parseInt(($height * $paddingBottom) / 713), 7381 }); 7382 }); 7383 } 7384} 7385 7386 7387/* Start a tour resize function */ 7388/* -------------------------------------------------------------------- */ 7389function mk_start_tour_resize() { 7390 7391 $('.mk-header-start-tour').each(function() { 7392 7393 var $windowWidth = $(document).width(), 7394 $this = $(this), 7395 $linkWidth = $this.width() + 15, 7396 $padding = ($windowWidth - mk_responsive_nav_width) / 2; 7397 7398 7399 7400 function updateStartTour(){ 7401 if($windowWidth < mk_responsive_nav_width){ 7402 $this.removeClass('hidden'); 7403 $this.addClass('show'); 7404 }else{ 7405 if($padding < $linkWidth){ 7406 $this.removeClass('show'); 7407 $this.addClass('hidden'); 7408 }else{ 7409 $this.removeClass('hidden'); 7410 $this.addClass('show'); 7411 } 7412 } 7413 } 7414 7415 setTimeout(function() { 7416 updateStartTour(); 7417 }, 300); 7418 }); 7419} 7420 7421/* Header social resize function */ 7422/* -------------------------------------------------------------------- */ 7423function mk_header_social_resize() { 7424 7425 $('.mk-header-social.header-section').each(function() { 7426 7427 var $windowWidth = $(document).width(), 7428 $this = $(this), 7429 $linkWidth = $this.width() + 15, 7430 $padding = ($windowWidth - mk_responsive_nav_width) / 2; 7431 7432 7433 7434 function updateStartTour(){ 7435 if($windowWidth < mk_responsive_nav_width){ 7436 $this.removeClass('hidden'); 7437 $this.addClass('show'); 7438 }else{ 7439 if($padding < $linkWidth){ 7440 $this.removeClass('show'); 7441 $this.addClass('hidden'); 7442 }else{ 7443 $this.removeClass('hidden'); 7444 $this.addClass('show'); 7445 } 7446 } 7447 } 7448 7449 setTimeout(function() { 7450 updateStartTour(); 7451 }, 300); 7452 }); 7453} 7454 7455/* Page Section Socail Video Player Controls */ 7456/* -------------------------------------------------------------------- */ 7457 7458function mk_page_section_social_video_bg() { 7459 $(".mk-page-section.social-hosted").each(function() { 7460 var $container = $(this), 7461 $sound = $container.data('sound'), 7462 $source = $container.data('source'), 7463 player, 7464 timer = 1000; 7465 7466 if ( $( 'body' ).hasClass( '.compose-mode' ) ) { 7467 timer = 2000; 7468 } 7469 7470 if ($source == 'youtube') { 7471 var youtube = $container.find('iframe')[0]; 7472 try { 7473 player = new YT.Player(youtube, { 7474 events: { 7475 'onReady': function () { 7476 player.playVideo(); 7477 if($sound == false) { 7478 player.mute(); 7479 } 7480 } 7481 } 7482 }); 7483 7484 7485 } catch (e) { 7486 console.log( e ); 7487 } 7488 } 7489 if ($source == 'vimeo') { 7490 var vimeo = $container.find('iframe')[0]; 7491 player = $f(vimeo); 7492 setTimeout(function() { 7493 player.api('play'); 7494 if($sound === false) {
7495 player.api('setVolume', 0); 7496 } 7497 }, timer); 7498 } 7499 7500 }); 7501} 7502 7503// Pre RequireJS hot bug fixing 7504 7505function videoLoadState() { 7506 $('.mk-section-video video').each(function() { 7507 var mkVideo = this; 7508 7509 mkVideo.play(); 7510 this.onload = fire(); 7511 7512 function fire() { 7513 setTimeout(function() { 7514 $(mkVideo).animate({ 7515 'opacity': 1 7516 }, 300); 7517 }, 1000); 7518 } 7519 }); 7520} 7521videoLoadState(); 7522 7523 7524// Gmap Widget 7525(function($) { 7526 7527 $(window).on('load vc_reload', initialize); 7528 7529 function initialize() { 7530 var $gmap = $('.gmap_widget'); 7531 if($gmap.length && typeof google !== 'undefined') $gmap.each(run); 7532 } 7533 7534 function run() { 7535 var $mapHolder = $(this); 7536 var myLatlng = new google.maps.LatLng($mapHolder.data('latitude'), $mapHolder.data('longitude')); 7537 var mapOptions = $mapHolder.data('options'); 7538 mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP; 7539 mapOptions.center = myLatlng; 7540 var map = new google.maps.Map(this, mapOptions); 7541 7542 new google.maps.Marker({ 7543 position: myLatlng, 7544 map: map 7545 }); 7546 } 7547 7548}(jQuery)); 7549 7550// Instagram Widget 7551(function($) { 7552 7553 $(window).on('load', function() { 7554 var $feeds = $('.mk-instagram-feeds'); 7555 if($feeds.length) $feeds.each(run); 7556 }); 7557 7558 function run() { 7559 var options = $(this).data('options'); 7560 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>'; 7561 var feed = new Instafeed(options); 7562 feed.run(); 7563 } 7564}(jQuery)); 7565 7566 7567// Flipbox backface visibility fix for chrome 7568(function($) { 7569 $(window).on('load', function() { 7570 setTimeout( function() { 7571 $('.chrome-flipbox-backface-fix').removeClass('chrome-flipbox-backface-fix'); 7572 }, 300); 7573 }); 7574}(jQuery)); 7575 7576 7577/* Product in VC Tab Bug Fix 7578/* -------------------------------------------------------------------- */ 7579(function($) { 7580 $(window).on('load', function() { 7581 $('.vc_tta-tab a').on('click', function() { 7582 setTimeout( function() { 7583 $(window).trigger('resize'); 7584 }, 100); 7585 }); 7586 }); 7587}(jQuery)); 7588 7589 7590/* Vertical menu fix when childrens exceed screen height 7591/* -------------------------------------------------------------------- */ 7592(function($) { 7593 $(window).on('load', function() { 7594 $('#mk-vm-menu .menu-item-has-children, #mk-vm-menu .mk-vm-back').on('mouseenter', function() { 7595 var $header_inner = $(this).closest('.mk-header-inner'), 7596 $header_inner_height = $header_inner.outerHeight(), 7597 $header_bg = $header_inner.find('.mk-header-bg'), 7598 total_height = 0; 7599 $header_bg.css('height', '100%'); 7600 setTimeout( function() { 7601 $header_inner.children(':visible').each(function() { 7602 total_height += $(this).outerHeight(true); 7603 }); 7604 total_height -= $header_bg.height(); 7605 if ( total_height < $header_inner_height ) { 7606 $header_bg.css('height', '100%'); 7607 } else { 7608 $header_bg.css('height', total_height + 'px'); 7609 } 7610 }, 600); 7611 }); 7612 }); 7613}(jQuery)); 7614 7615 7616/* Woocommerce varitions lightbox fix 7617/* -------------------------------------------------------------------- */ 7618(function($) { 7619 $(window).on('load', function() { 7620 7621 var $variations_form = $('.variations_form'); 7622 7623 if ( $variations_form.length ) { 7624 7625 var $varitions_selects = $variations_form.find('.variations').find('.value').find('select'); 7626 $varitions_selects.on('change', function() { 7627 7628 // Woocommerce variations lightbox with galleries 7629 var $all_img_container = $('.mk-product-image .mk-woocommerce-main-image'); 7630 if ( $all_img_container.length ) { 7631 $( $all_img_container ).each( set_lightbox_href ); 7632 } 7633 7634 }); 7635 $varitions_selects.trigger('change'); 7636 7637 } 7638 7639 }); 7640 7641 function set_lightbox_href() { 7642 7643 var $product_img = $( this ).find( 'img' ), 7644 $lightbox = $( this ).find( '.mk-lightbox' ); 7645 7646 setTimeout( function() { 7647 var image_url = $product_img.attr( 'src' ), 7648 image_suffix = image_url.substr( image_url.lastIndexOf('.') - image_url.length ), // Get image suffix 7649 image_url = image_url.slice( 0 , image_url.lastIndexOf('-') ); // Remove image size 7650 $lightbox.attr('href', image_url + image_suffix ); 7651 }, 300); 7652 } 7653 7654}(jQuery)); 7655 7656 7657/* Remove video section when on mobile */ 7658/* -------------------------------------------------------------------- */ 7659(function($) { 7660 if ( MK.utils.isMobile() ) {
7661 $('.mk-section-video video').remove(); 7662 } 7663}(jQuery)); 7664 7665 7666/* Yith AJAX Product Filter & Yith Infinite Scrolling Plugin Fix 7667/* -------------------------------------------------------------------- */ 7668(function($) { 7669 $(window).on('load', function() { 7670 7671 $(document).on( 'yith-wcan-ajax-filtered yith_infs_added_elem yith-wcan-ajax-reset-filtered', function(){ 7672 setTimeout( function() { 7673 MK.utils.eventManager.publish('ajaxLoaded'); 7674 MK.core.initAll( document ); 7675 }, 1000 ); 7676 }); 7677 7678 // Fixed YITH Filter plugin causes issue for dropdown sort 7679 $(document).on( 'yith-wcan-ajax-filtered yith-wcan-ajax-reset-filtered', function(){ 7680 setTimeout( function() { 7681 $( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() { 7682 $( this ).closest( 'form' ).submit(); 7683 }); 7684 }, 1000 ); 7685 }); 7686 7687 }); 7688}(jQuery)); 7689 7690 7691/* Toggle loading state in URL for anchor links. 7692 * - Add a filter to escape meta-chars from hash string. 7693/* -------------------------------------------------------------------- */ 7694!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); 7695 7696 7697/* Determine the top spacing of sidebar for full-width page section & row. 7698/* -------------------------------------------------------------------- */ 7699function mkPositionSidebar() { 7700 7701 var themeContent = $( '.theme-content' ), 7702 lastFullWidthChild = themeContent.find( '.vc_row-full-width' ).last(), 7703 top, 7704 sidebar = $( '#theme-page > .mk-main-wrapper-holder > .theme-page-wrapper > #mk-sidebar' ); 7705 7706 if ( ! lastFullWidthChild.length ) { 7707 sidebar.removeAttr( 'style' ); 7708 return; 7709 } 7710 7711 top = lastFullWidthChild.offset().top - themeContent.offset().top; 7712 sidebar.css( 'padding-top', top ); 7713} 7714 7715function mk_accordion_toggles_tooltip() { 7716 7717 "use strict"; 7718 7719 7720 /* Message Boxes */ 7721 /* -------------------------------------------------------------------- */ 7722 7723 $('.box-close-btn').on('click', function() { 7724 $(this).parent().fadeOut(300); 7725 return false; 7726 7727 }); 7728 7729} 7730 7731function mk_portfolio_ajax() { 7732 "use strict"; 7733 7734 var headerHeight = 0; 7735 if ($.exists("#wpadminbar")) { 7736 headerHeight += $("#wpadminbar").height(); 7737 } 7738 if (!$.exists('.mk-vm-menuwrapper')) { 7739 headerHeight += parseInt($('.mk-header').attr('data-sticky-height')); 7740 } 7741 7742 function init() { 7743 var $portfolio = $('.portfolio-grid.portfolio-ajax-enabled'); 7744 if (!$portfolio.length) return; // quit if no portfolio wrappers 7745 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.ajax.portfolio.js' ], function() { 7746 // wait for ajax response propagation and insertion 7747 setTimeout(function() { 7748 $portfolio.each( function() { 7749 $(this).ajaxPortfolio({ extraOffset: headerHeight }); 7750 }); 7751 }, 100); 7752 }); 7753 } 7754 7755 init(); 7756 7757 // Reinit when ajax loaded stuff 7758 // We have global reinit on Components. so move the ajaxPortfolio to component namespace as a standalone module to get it right. 7759 MK.utils.eventManager.subscribe('ajaxLoaded', init); 7760} 7761 7762/** 7763 * Ajax Search on header nav. 7764 */ 7765function mk_ajax_search() { 7766 "use strict"; 7767 7768 // Check if ajax search box enabled. 7769 if (mk_ajax_search_option !== "beside_nav") { 7770 return; 7771 } 7772 7773 // Set minimum length of text to get ajax result. 7774 var minimumLengthToSearch = 3; 7775 var $mkAjaxSearchInput = $('#mk-ajax-search-input'); 7776 var security = $mkAjaxSearchInput.siblings('input[name="security"]').val(); 7777 var wpHttpReferer = $mkAjaxSearchInput.siblings('input[name="_wp_http_referer"]').val(); 7778 var querySpliter = (ajaxurl.indexOf('?') > -1) ? '&' : '?'; 7779 var ul = document.getElementById('mk-nav-search-result'); 7780 var searchTerm; // Search term 7781 var requestCounter = 0; 7782 var responseCounter = 0; 7783 7784 // Add listener for getting result quickly while user entering text, past text and etc. 7785 $mkAjaxSearchInput.on('paste input propertychange', onSearchBoxInput); 7786 7787 /** 7788 * Callback function for entering search term listener (e.g. keyup). 7789 * It will generate AJAX request to get data. 7790 * 7791 * @param e 7792 */ 7793 function onSearchBoxInput(e) { 7794 var target = e.target || e.srcElement; 7795 var newValue = target.value; 7796 7797 // Check if user change the value of text box 7798 if (searchTerm !== newValue) { 7799 searchTerm = newValue; 7800 ul.innerHTML = ''; 7801 if (searchTerm.length >= minimumLengthToSearch) { 7802 // Show loading icon 7803 $mkAjaxSearchInput.addClass('ajax-searching'); 7804 requestCounter++; 7805 $.getJSON(ajaxurl + querySpliter + 'callback=?&action=mk_ajax_search&security=' + security + '&_wp_http_referer=' + wpHttpReferer + '&term=' + searchTerm) 7806 .done(showSearchResult) 7807 .fail(showErrorMessage); 7808 } 7809 } 7810 } 7811 7812 /** 7813 * Callback function for the response of the search request. 7814 * 7815 * @param data 7816 */ 7817 function showSearchResult(data) { 7818 responseCounter++; 7819 7820 // Only show response of latest request. 7821 if (isCorrectResponse()) { 7822 if (data.length > 0) { 7823 // Append result to result container 7824 for (var i = 0; i < data.length; i++) { 7825 var item = data[i]; 7826 $('<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); 7827 } 7828 } else { 7829 // Show no result message 7830 ul.innerHTML = '<li class="mk-nav-search-result-zero">No Result.</li>'; 7831 } 7832 7833 // Hide loading icon 7834 $mkAjaxSearchInput.parent('form').removeClass('ajax-searching').addClass('ajax-search-complete'); 7835 } 7836 } 7837 7838 /** 7839 * If any errors, we need a handler to show error message. 7840 */ 7841 function showErrorMessage() { 7842 responseCounter++; 7843 7844 if (isCorrectResponse()) { 7845 ul.innerHTML = '<li class="mk-nav-search-error-message">Can not search! Please try again.</li>'; 7846 } 7847 } 7848 7849 /** 7850 * Check if the response is right for the request. we show latest response only. 7851 * 7852 * @returns {boolean} 7853 */ 7854 function isCorrectResponse() { 7855 return requestCounter === responseCounter; 7856 } 7857}
7858/* Background Parallax Effects */ 7859/* -------------------------------------------------------------------- */ 7860 7861function mk_backgrounds_parallax() { 7862 7863 "use strict"; 7864 7865 if (mk_header_parallax == true) { 7866 $('.mk-header-bg').addClass('mk-parallax-enabled'); 7867 } 7868 if (mk_body_parallax == true) { 7869 $('body').addClass('mk-parallax-enabled'); 7870 } 7871 if (mk_banner_parallax == true) { 7872 $('.mk-header').addClass('mk-parallax-enabled'); 7873 } 7874 if (mk_footer_parallax == true) { 7875 $('#mk-footer').addClass('mk-parallax-enabled'); 7876 } 7877 7878 $('.mk-parallax-enabled').each(function () { 7879 var $this = $( this ); 7880 if (!MK.utils.isMobile()) { 7881 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() { 7882 $this.parallax("49%", 0.3); 7883 }); 7884 } 7885 }); 7886 7887 $('.mk-fullwidth-slideshow.parallax-slideshow').each(function () { 7888 var $this = $( this ); 7889 if (!MK.utils.isMobile()) { 7890 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() { 7891 var speed_factor = $this.attr('data-speedFactor'); 7892 $this.parallax("49%", speed_factor); 7893 }); 7894 } 7895 }); 7896 7897} 7898/* Blog, Portfolio Audio */ 7899/* -------------------------------------------------------------------- */ 7900 7901function loop_audio_init() { 7902 if ($.exists('.jp-jplayer')) { 7903 $('.jp-jplayer.mk-blog-audio').each(function () { 7904 var $this = $( this ); 7905 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.jplayer.js' ], function() { 7906 var css_selector_ancestor = "#" + $this.siblings('.jp-audio').attr('id'); 7907 var ogg_file, mp3_file, mk_theme_js_path; 7908 ogg_file = $this.attr('data-ogg'); 7909 mp3_file = $this.attr('data-mp3'); 7910 $this.jPlayer({ 7911 ready: function () { 7912 $this.jPlayer("setMedia", { 7913 mp3: mp3_file, 7914 ogg: ogg_file 7915 }); 7916 }, 7917 play: function () { // To avoid both jPlayers playing together. 7918 $this.jPlayer("pauseOthers"); 7919 }, 7920 swfPath: mk_theme_js_path, 7921 supplied: "mp3, ogg", 7922 cssSelectorAncestor: css_selector_ancestor, 7923 wmode: "window" 7924 }); 7925 }); 7926 }); 7927 } 7928} 7929 7930 7931/* Blog Loop Carousel Shortcode */ 7932/* -------------------------------------------------------------------- */ 7933 7934 7935function mk_blog_carousel() { 7936 7937 "use strict"; 7938 7939 if (!$.exists('.mk-blog-showcase')) { 7940 return; 7941 } 7942 $('.mk-blog-showcase ul li').each(function () { 7943 7944 $(this).on('hover', function () { 7945 7946 $(this).siblings('li').removeClass('mk-blog-first-el').end().addClass('mk-blog-first-el'); 7947 7948 }); 7949 7950 }); 7951 7952 7953} 7954 7955 7956 7957 7958/** 7959 * Contact Form 7960 * 7961 * Mostly implemented in Vanilla JS instead of jQuery. 7962 */ 7963 7964function mk_contact_form() { 7965 "use strict"; 7966 7967 var mkContactForms = document.getElementsByClassName('mk-contact-form'); 7968 7969 if (mkContactForms.length === 0) { 7970 return; 7971 } 7972 7973 var captchaImageHolder = $('.captcha-image-holder'); 7974 var activeClassName = 'is-active'; 7975 var invalidClassName = 'mk-invalid'; 7976 7977 for (var i = 0; i < mkContactForms.length; i++) { 7978 initializeForm(mkContactForms[i], activeClassName, invalidClassName); 7979 } 7980 7981 if(captchaImageHolder.length > 0) { 7982 $(window).on('load', initializeCaptchas); 7983 } 7984 7985 /** 7986 * Initialize mk forms. e.g add activeClassName for inputs. 7987 * 7988 * @param form 7989 * @param activeClassName 7990 * @param invalidClassName 7991 */ 7992 function initializeForm(form, activeClassName, invalidClassName) { 7993 var inputs = getFormInputs(form); 7994 7995 for (var i = 0; i < inputs.length; i++) { 7996 markActiveClass(inputs[i]); 7997 } 7998 7999 form.addEventListener('submit', function (e) { 8000 validateForm(e, invalidClassName); 8001 }); 8002 8003 /** 8004 * Set activeClassName for the parent node of the inout 8005 */ 8006 function setActiveClass() { 8007 addClass(this.parentNode, activeClassName); 8008 } 8009 8010 /** 8011 * Unset activeClassName from the parent node of the input. 8012 * We need to unset activeClassName only if the data was empty. 8013 * e.g. in the line style of the mk-contact-form, we set labels position based on activeClassName. 8014 */ 8015 function unsetActiveClass() { 8016 if (this.value === '') { 8017 removeClass(this.parentNode, activeClassName); 8018 } 8019 } 8020 8021 /** 8022 * Add event listeners (focus,blur) for input to set and unset activeClassName. 8023 * 8024 * @param input 8025 */ 8026 function markActiveClass(input) { 8027 input.addEventListener('focus', setActiveClass); 8028 input.addEventListener('blur', unsetActiveClass); 8029 } 8030 } 8031 8032 /** 8033 * Validate form when it's submitted. If everything was valid, we with post form in ajax request. 8034 * 8035 * @param e 8036 * @param invalidClassName 8037 */ 8038 function validateForm(e, invalidClassName) { 8039 e.preventDefault(); 8040 var form = e.target || e.srcElement; 8041 var inputs = getFormInputs(form); 8042 var isValidForm = true; 8043 var hasCaptchaField = false;
8044 8045 for (var i = 0; i < inputs.length; i++) { 8046 var input = inputs[i]; 8047 input.value = String(input.value).trim(); 8048 switch (input.type) { 8049 case 'hidden': 8050 break; 8051 case 'email': 8052 isValidForm = validateEmail(input, invalidClassName) && isValidForm; 8053 break; 8054 case 'textarea': 8055 isValidForm = validateText(input, invalidClassName) && isValidForm; 8056 break; 8057 case 'text': 8058 /** 8059 * Some old browsers such as IE 8 and 9 detect email type as text. 8060 * So, we need to extra check for data-type attribute 8061 */ 8062 if (input.dataset.type === 'captcha') { 8063 isValidForm = validateText(input, invalidClassName) && isValidForm; 8064 hasCaptchaField = true; 8065 } else if (input.dataset.type === 'email') { 8066 isValidForm = validateEmail(input, invalidClassName) && isValidForm; 8067 } else { 8068 isValidForm = validateText(input, invalidClassName) && isValidForm; 8069 } 8070 break; 8071 default: 8072 /** 8073 * e.g. validating for radiobox, selectbox and etc. 8074 */ 8075 console.warn('Implement validation for ' + input.name + ':' + input.type); 8076 break; 8077 } 8078 } 8079 8080 if (isValidForm) { 8081 if (hasCaptchaField) { 8082 validateCaptcha(form, invalidClassName, sendForm); 8083 } else { 8084 sendForm(form); 8085 } 8086 } 8087 } 8088 8089 /** 8090 * Validate captcha of form. If everything was, we will execute captchaIsValidCallback which as sendForm(). 8091 * 8092 * @param form 8093 * @param invalidClassName 8094 * @param captchaIsValidCallback 8095 * @returns boolean 8096 */ 8097 function validateCaptcha(form, invalidClassName, captchaIsValidCallback) { 8098 var input = form.querySelectorAll('[data-type="captcha"]')[0]; 8099 8100 if (input.value.length === 0) { 8101 addClass(input, invalidClassName); 8102 return false; 8103 } else { 8104 window.get.captcha(input.value).done(function (data) { 8105 loadCaptcha(); 8106 input.value = ''; 8107 8108 if (data !== 'ok') { 8109 addClass(input, invalidClassName); 8110 addClass(input, 'contact-captcha-invalid'); 8111 removeClass(input, 'contact-captcha-valid'); 8112 input.placeholder = mk_captcha_invalid_txt; 8113 } else { 8114 removeClass(input, invalidClassName); 8115 removeClass(input, 'contact-captcha-invalid'); 8116 addClass(input, 'contact-captcha-valid'); 8117 input.placeholder = mk_captcha_correct_txt; 8118 captchaIsValidCallback(form); 8119 } 8120 }); 8121 } 8122 } 8123 8124 /** 8125 * Send submitted form. 8126 * 8127 * @param form 8128 */ 8129 function sendForm(form) { 8130 var $form = $(form); 8131 var data = getFormData(form); 8132 8133 progressButton.loader($form); 8134 $.post(ajaxurl, data, function (response) { 8135 var res = JSON.parse(response); 8136 if (res.action_Status) { 8137 progressButton.success($form); 8138 $form.find('.text-input').val(''); 8139 $form.find('textarea').val(''); 8140 $form.find('.contact-form-message').addClass('state-success').html(res.message); 8141 } else { 8142 progressButton.error($form); 8143 $form.find('.contact-form-message').removeClass('state-success').html(res.message); 8144 } 8145 }); 8146 } 8147 8148 /** 8149 * Initialize all captcha images for first time. All captcha images is always same. e.g. if we have multiple form, 8150 * all of them will have the same image. 8151 * It will also add event listener for '.captcha-change-image' objects to reload the captcha. 8152 */ 8153 function initializeCaptchas() { 8154 var captchaChangeImageButtons = document.getElementsByClassName('captcha-change-image'); 8155 for (var i = 0; i < captchaChangeImageButtons.length; i++) { 8156 captchaChangeImageButtons[i].addEventListener('click', loadCaptcha); 8157 } 8158 } 8159 8160 /** 8161 * Load captcha text and append the image to captcha container. 8162 * If it used as a callback, it will prevent default behave of the event. 8163 * e.g. loading new captcha by click on <a> without changing url. 8164 */ 8165 function loadCaptcha(e) { 8166 if (e) { 8167 e.preventDefault(); 8168 } 8169 8170 $.post(ajaxurl, {action: 'mk_create_captcha_image'}, appendImage); 8171 8172 /** 8173 * The callback function for append or change old image src based on response. T 8174 * The captchaImageURL is the url of the captcha which is provided in ajax response of mk_create_captcha_image. 8175 * @param captchaImageURL 8176 */ 8177 function appendImage(captchaImageURL) { 8178 if (captchaImageHolder.find('.captcha-image').length === 0) { 8179 captchaImageHolder.html('<img src="' + captchaImageURL + '" class="captcha-image" alt="captcha txt">'); 8180 } else { 8181 captchaImageHolder.find('.captcha-image').attr("src", captchaImageURL+'?'+ new Date().getTime()); 8182 } 8183 } 8184 } 8185 8186 8187 /** 8188 * Get form inputs using querySelectorAll(). 8189 * It returns <input> and <textarea> tags. If you need any other tags such as <select>, please update this function. 8190 * 8191 * @param form 8192 * @returns {NodeList} 8193 */ 8194 function getFormInputs(form) { 8195 return form.querySelectorAll('input,textarea'); 8196 } 8197 8198 8199 /** 8200 * Get data of the form inputs and textareas as a object. 8201 * 8202 * @param form 8203 * @returns {{action: string}} 8204 */ 8205 function getFormData(form) { 8206 var data = {action: 'mk_contact_form'}; 8207 var inputs = getFormInputs(form); 8208 for (var i = 0; i < inputs.length; i++) {
8209 data[inputs[i].name] = inputs[i].value; 8210 } 8211 return data; 8212 } 8213} 8214 8215 8216/* Ajax Login Form */ 8217/* -------------------------------------------------------------------- */ 8218 8219function mk_login_form() { 8220 8221 $('form.mk-login-form').each(function () { 8222 var $this = $(this); 8223 $this.on('submit', function (e) { 8224 $('p.mk-login-status', $this).show().text(ajax_login_object.loadingmessage); 8225 $.ajax({ 8226 type: 'POST', 8227 dataType: 'json', 8228 url: ajax_login_object.ajaxurl, 8229 data: { 8230 'action': 'ajaxlogin', 8231 'username': $('#username', $this).val(), 8232 'password': $('#password', $this).val(), 8233 'security': $('#security', $this).val() 8234 }, 8235 success: function (data) { 8236 $('p.mk-login-status', $this).text(data.message); 8237 if (data.loggedin === true) { 8238 document.location.href = ajax_login_object.redirecturl; 8239 } 8240 } 8241 }); 8242 e.preventDefault(); 8243 }); 8244 }); 8245} 8246 8247 8248/* Progress Button */ 8249/* -------------------------------------------------------------------- */ 8250 8251var progressButton = { 8252 loader: function (form) { 8253 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function () { 8254 var $form = form, 8255 progressBar = $form.find(".mk-progress-button .mk-progress-inner"), 8256 buttonText = $form.find(".mk-progress-button .mk-progress-button-content"), 8257 progressButton = new TimelineLite(); 8258 8259 progressButton 8260 .to(progressBar, 0, { 8261 width: "100%", 8262 scaleX: 0, 8263 scaleY: 1 8264 }) 8265 .to(buttonText, .3, { 8266 y: -5 8267 }) 8268 .to(progressBar, 1.5, { 8269 scaleX: 1, 8270 ease: Power2.easeInOut 8271 }, "-=.1") 8272 .to(buttonText, .3, { 8273 y: 0 8274 }) 8275 .to(progressBar, .3, { 8276 scaleY: 0 8277 }); 8278 }); 8279 }, 8280 8281 success: function (form) { 8282 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function () { 8283 var $form = form, 8284 buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"), 8285 successIcon = $form.find(".mk-progress-button .state-success"), 8286 progressButtonSuccess = new TimelineLite({ 8287 onComplete: hideSuccessMessage 8288 }); 8289 8290 progressButtonSuccess 8291 .to(buttonText, .3, { 8292 paddingRight: 20, 8293 ease: Power2.easeInOut 8294 }, "+=1") 8295 .to(successIcon, .3, { 8296 opacity: 1 8297 }) 8298 .to(successIcon, 2, { 8299 opacity: 1 8300 }); 8301 8302 function hideSuccessMessage() { 8303 progressButtonSuccess.reverse() 8304 } 8305 }); 8306 }, 8307 8308 error: function (form) { 8309 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function () { 8310 var $form = form, 8311 buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"), 8312 errorIcon = $form.find(".mk-progress-button .state-error"), 8313 progressButtonError = new TimelineLite({ 8314 onComplete: hideErrorMessage 8315 }); 8316 8317 progressButtonError 8318 .to(buttonText, .3, { 8319 paddingRight: 20 8320 }, "+=1") 8321 .to(errorIcon, .3, { 8322 opacity: 1 8323 }) 8324 .to(errorIcon, 2, { 8325 opacity: 1 8326 }); 8327 8328 function hideErrorMessage() { 8329 progressButtonError.reverse() 8330 } 8331 }); 8332 } 8333}; 8334function mk_click_events() { 8335 "use strict"; 8336 8337 var eventtype = 'click'; 8338 8339 $(".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) { 8340 if (event.stopPropagation) { 8341 event.stopPropagation(); 8342 } else if (window.event) { 8343 window.event.cancelBubble = true; 8344 } 8345 }); 8346 $("html").on(eventtype, function() {
8347 $(".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); 8348 $('.mk-quick-contact-link').removeClass('quick-contact-active'); 8349 // Removed By Maki for repairing fullnav scroll issue. Hope it odesnt break anything 8350 // $('body').css('overflow', 'visible'); 8351 }); 8352 8353 $('.mk-fullscreen-search-overlay').on(eventtype,function(){ 8354 $(this).removeClass('mk-fullscreen-search-overlay-show'); 8355 }); 8356 8357 $('.mk-forget-password').on(eventtype, function() { 8358 $('.mk-forget-panel').siblings().hide().end().show(); 8359 }); 8360 8361 $('.mk-create-account').on(eventtype, function() { 8362 $('#mk-register-panel').siblings().hide().end().show(); 8363 }); 8364 8365 $('.mk-return-login').on(eventtype, function() { 8366 $('#mk-login-panel').siblings().hide().end().show(); 8367 }); 8368 8369 8370 $('.mk-quick-contact-link').on(eventtype, function() { 8371 var $this = $(this), 8372 $quickContact = $('#mk-quick-contact'); 8373 if (!$this.hasClass('quick-contact-active')) { 8374 $quickContact.addClass('quick-contact-anim').fadeIn(250); 8375 $this.addClass('quick-contact-active'); 8376 } else { 8377 $quickContact.removeClass('quick-contact-anim').fadeOut(100); 8378 $this.removeClass('quick-contact-active'); 8379 } 8380 return false; 8381 }); 8382 8383} 8384 8385function mk_social_share_global() { 8386 8387 "use strict"; 8388 8389 var eventtype = 'click'; 8390 8391 $('.twitter-share').on(eventtype, function() { 8392 var $this = $(this), 8393 $url = $this.attr('data-url'), 8394 $title = $this.attr('data-title'); 8395 8396 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"); 8397 return false; 8398 }); 8399 8400 $('.pinterest-share').on(eventtype, function() { 8401 var $this = $(this), 8402 $url = $this.attr('data-url'), 8403 $title = $this.attr('data-title'), 8404 $image = $this.attr('data-image'); 8405 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"); 8406 return false; 8407 }); 8408 8409 $('.facebook-share').on(eventtype, function() { 8410 var $url = $(this).attr('data-url'); 8411 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"); 8412 return false; 8413 }); 8414 8415 $('.googleplus-share').on(eventtype, function() { 8416 var $url = $(this).attr('data-url'); 8417 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"); 8418 return false; 8419 }); 8420 8421 $('.linkedin-share').on(eventtype, function() { 8422 var $this = $(this), 8423 $url = $this.attr('data-url'), 8424 $title = $this.attr('data-title'), 8425 $desc = $this.attr('data-desc'); 8426 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"); 8427 return false; 8428 }); 8429} 8430 8431 8432/* Event Count Down */ 8433/* -------------------------------------------------------------------- */ 8434 8435function mk_event_countdown() { 8436 if ($.exists('.mk-event-countdown')) { 8437 8438 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.countdown.js' ], function() { 8439 8440 $('.mk-event-countdown').each(function () { 8441 if (isTest) return; 8442 var $this = $(this), 8443 $date = $this.attr('data-date'), 8444 $offset = $this.attr('data-offset'); 8445 8446 $this.downCount({ 8447 date: $date, 8448 offset: $offset 8449 }); 8450 }); 8451 8452 }); 8453 } 8454} 8455/* Flexslider init */ 8456/* -------------------------------------------------------------------- */ 8457 8458function mk_flexslider_init() { 8459 8460 var $lcd = $('.mk-lcd-slideshow'), 8461 $laptop = $('.mk-laptop-slideshow-shortcode'); 8462 8463 if($lcd.length) $lcd.find('.mk-lcd-image').fadeIn(); 8464 if($laptop.length) $laptop.find(".mk-laptop-image").fadeIn(); 8465 8466 $('.js-flexslider').each(function () { 8467 8468 if ($(this).parents('.mk-tabs').length || $(this).parents('.mk-accordion').length) { 8469 $(this).removeData("flexslider"); 8470 } 8471 8472 var $this = $(this), 8473 $selector = $this.attr('data-selector'), 8474 $animation = $this.attr('data-animation'), 8475 $easing = $this.attr('data-easing'), 8476 $direction = $this.attr('data-direction'), 8477 $smoothHeight = $this.attr('data-smoothHeight') == "true" ? true : false,
8478 $slideshowSpeed = $this.attr('data-slideshowSpeed'), 8479 $animationSpeed = $this.attr('data-animationSpeed'), 8480 $controlNav = $this.attr('data-controlNav') == "true" ? true : false, 8481 $directionNav = $this.attr('data-directionNav') == "true" ? true : false, 8482 $pauseOnHover = $this.attr('data-pauseOnHover') == "true" ? true : false, 8483 $isCarousel = $this.attr('data-isCarousel') == "true" ? true : false; 8484 8485 8486 if ($selector !== undefined) { 8487 var $selector_class = $selector; 8488 } else { 8489 var $selector_class = ".mk-flex-slides > li"; 8490 } 8491 8492 if ($isCarousel === true) { 8493 var $itemWidth = parseInt($this.attr('data-itemWidth')), 8494 $itemMargin = parseInt($this.attr('data-itemMargin')), 8495 $minItems = parseInt($this.attr('data-minItems')), 8496 $maxItems = parseInt($this.attr('data-maxItems')), 8497 $move = parseInt($this.attr('data-move')); 8498 } else { 8499 var $itemWidth = $itemMargin = $minItems = $maxItems = $move = 0; 8500 } 8501 8502 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.flexslider.js' ], function() { 8503 $this.flexslider({ 8504 selector: $selector_class, 8505 animation: $animation, 8506 easing: $easing, 8507 direction: $direction, 8508 smoothHeight: $smoothHeight, 8509 slideshow: !isTest, // autoplay 8510 slideshowSpeed: $slideshowSpeed, 8511 animationSpeed: $animationSpeed, 8512 controlNav: $controlNav, 8513 directionNav: $directionNav, 8514 pauseOnHover: $pauseOnHover, 8515 prevText: "", 8516 nextText: "", 8517 itemWidth: $itemWidth, 8518 itemMargin: $itemMargin, 8519 minItems: $minItems, 8520 maxItems: $maxItems, 8521 move: $move 8522 }); 8523 }); 8524 8525 }); 8526 8527} 8528 8529/* Header Search Form */ 8530/* -------------------------------------------------------------------- */ 8531 8532function mk_header_searchform() { 8533 8534 $('.mk-search-trigger').click(function(){ 8535 setTimeout(function() { 8536 $('#mk-ajax-search-input').focus(); 8537 },500); 8538 }); 8539 8540 "use strict"; 8541 8542 $('.mk-header-toolbar .mk-header-searchform .text-input').on('focus', function () { 8543 8544 if ($('.mk-header-toolbar .mk-header-searchform .text-input').hasClass('on-close-state')) { 8545 $('.mk-header-toolbar .mk-header-searchform .text-input').removeClass('on-close-state').animate({ 8546 'width': '200px' 8547 }, 200); 8548 return false; 8549 } 8550 }); 8551 8552 $(".mk-header-toolbar .mk-header-searchform").click(function (event) { 8553 if (event.stopPropagation) { 8554 event.stopPropagation(); 8555 } else if (window.event) { 8556 window.event.cancelBubble = true; 8557 } 8558 }); 8559 8560 8561 $("html").click(function () { 8562 $(this).find(".mk-header-toolbar .mk-header-searchform .text-input").addClass('on-close-state').animate({ 8563 'width': 90 8564 }, 300); 8565 }); 8566 8567 // Fix search for edge browser 8568 if(MK.utils.browser.name === 'Edge') { 8569 $('#mk-fullscreen-search-input').on('keydown', function(e) { 8570 if (e.which == 13) { 8571 e.preventDefault(); 8572 $('#mk-fullscreen-searchform').submit(); 8573 } 8574 }); 8575 } 8576 8577} 8578 8579 8580 8581 8582/* Hover Events */ 8583/* -------------------------------------------------------------------- */ 8584 8585function mk_hover_events() { 8586 8587 "use strict"; 8588 8589 $('.shopping-cart-header').hover( 8590 function() { 8591 $(this).find('.mk-shopping-cart-box').stop(true, true).fadeIn(250); 8592 }, 8593 function() { 8594 $(this).find('.mk-shopping-cart-box').stop(true, true).fadeOut(250); 8595 } 8596 ); 8597 8598 8599 $('.widget-sub-navigation > ul > li, .widget_nav_menu ul.menu > li, .widget_product_categories ul > .cat-item').each(function() { 8600 8601 var $this = $(this), 8602 $subLevel = $this.find('ul').first(); 8603 8604 if ($this.hasClass('page_item_has_children') || $this.hasClass('menu-item-has-children') || $this.hasClass('cat-parent')) { 8605 $this.on('click', function() { 8606 if($this.hasClass('toggle-active')) { 8607 $subLevel.stop(true, true).slideUp(700); 8608 $this.removeClass('toggle-active'); 8609 } else { 8610 $subLevel.stop(true, true).slideDown(700); 8611 $this.addClass('toggle-active'); 8612 } 8613 }); 8614 8615 $subLevel.on('click', function(e){ 8616 e.stopPropagation(); 8617 }); 8618 } 8619 8620 }); 8621 8622 // var eventtype = mobilecheck() ? 'touchstart' : 'click'; 8623 var eventtype = 'click'; 8624 8625 $('.mk-fullscreen-trigger').on(eventtype, function(e) { 8626 $('.mk-fullscreen-search-overlay').addClass('mk-fullscreen-search-overlay-show'); 8627 setTimeout(function(){ 8628 $("#mk-fullscreen-search-input").focus(); 8629 }, 300); 8630 e.preventDefault(); 8631 }); 8632 8633 $('.mk-fullscreen-close').on(eventtype, function(e) { 8634 $('.mk-fullscreen-search-overlay').removeClass('mk-fullscreen-search-overlay-show'); 8635 e.preventDefault(); 8636 }); 8637 8638} 8639 8640function mk_unfold_footer() { 8641 var $this = $('#mk-footer'), 8642 $spacer = $('#mk-footer-unfold-spacer'), 8643 $footerHeight = $this.outerHeight(); 8644 8645 // Stick with CSS media query breakpoint to target exact screen width 8646 if( !window.matchMedia("(max-width: 767px)").matches ) { 8647 if ($this.hasClass('mk-footer-unfold')) { 8648 $spacer.css('height', $footerHeight); 8649 } 8650 } else { 8651 $spacer.css('height', 0); 8652 } 8653} 8654/* jQuery fancybox lightbox */ 8655/* -------------------------------------------------------------------- */ 8656function mk_lightbox_init() { 8657 8658var $lightbox = $(".mk-lightbox"); 8659 8660 $lightbox.fancybox({ 8661 padding: 15, 8662 margin: 15, 8663 8664 width: 800, 8665 height: 600, 8666 minWidth: 100, 8667 minHeight: 100, 8668 maxWidth: 9999, 8669 maxHeight: 9999,
8670 pixelRatio: 1, // Set to 2 for retina display support 8671 8672 autoSize: true, 8673 autoHeight: false, 8674 autoWidth: false, 8675 8676 autoResize: true, 8677 fitToView: true, 8678 aspectRatio: false, 8679 topRatio: 0.5, 8680 leftRatio: 0.5, 8681 8682 scrolling: 'auto', // 'auto', 'yes' or 'no' 8683 wrapCSS: '', 8684 8685 arrows: true, 8686 closeBtn: true, 8687 closeClick: false, 8688 nextClick: false, 8689 mouseWheel: true, 8690 autoPlay: false, 8691 playSpeed: 3000, 8692 preload: 3, 8693 modal: false, 8694 loop: true, 8695 // Properties for each animation type 8696 // Opening fancyBox 8697 openEffect: 'fade', // 'elastic', 'fade' or 'none' 8698 openSpeed: 200, 8699 openEasing: 'swing', 8700 openOpacity: true, 8701 openMethod: 'zoomIn', 8702 8703 // Closing fancyBox 8704 closeEffect: 'fade', // 'elastic', 'fade' or 'none' 8705 closeSpeed: 200, 8706 closeEasing: 'swing', 8707 closeOpacity: true, 8708 closeMethod: 'zoomOut', 8709 8710 // Changing next gallery item 8711 nextEffect: 'none', // 'elastic', 'fade' or 'none' 8712 nextSpeed: 350, 8713 nextEasing: 'swing', 8714 nextMethod: 'changeIn', 8715 8716 // Changing previous gallery item 8717 prevEffect: 'none', // 'elastic', 'fade' or 'none' 8718 prevSpeed: 350, 8719 prevEasing: 'swing', 8720 prevMethod: 'changeOut', 8721 helpers : { 8722 media : {}, 8723 overlay: { 8724 locked: true 8725 } 8726 }, 8727 8728 tpl: { 8729 wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 8730 image: '<img class="fancybox-image" src="{href}" alt="" />', 8731 error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 8732 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>', 8733 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>', 8734 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>', 8735 loading: '<div id="fancybox-loading"><div></div></div>' 8736 }, 8737 8738 afterLoad: function() { 8739 $('html').addClass('fancybox-lock'); 8740 $('.fancybox-wrap').appendTo('.fancybox-overlay'); 8741 }, 8742 beforeShow: function(){ 8743 this.locked = true; 8744 }, 8745 afterClose: function() { 8746 // Only for gallery shortcode. 8747 var galleryParent = this.element.parents( '.mk-gallery-item' ); 8748 8749 if ( galleryParent ) { 8750 galleryParent.removeClass('hover-state'); 8751 } 8752 } 8753 8754 }); 8755} 8756 8757 8758/* Love This */ 8759/* -------------------------------------------------------------------- */ 8760 8761function mk_love_post() { 8762 8763 "use strict"; 8764 8765 $('body').on('click', '.mk-love-this', function () { 8766 var $this = $(this), 8767 $id = $this.attr('id'); 8768 8769 if ($this.hasClass('item-loved')) return false;
8770 8771 if ($this.hasClass('item-inactive')) return false; 8772 8773 var $sentdata = { 8774 action: 'mk_love_post', 8775 post_id: $id 8776 } 8777 8778 $.post(ajaxurl, $sentdata, function (data) { 8779 $this.find('.mk-love-count').html(data); 8780 $this.addClass('item-loved'); 8781 }); 8782 8783 $this.addClass('item-inactive'); 8784 return false; 8785 }); 8786 8787} 8788 8789 8790 8791 8792/* Milestone Number Shortcode */ 8793/* -------------------------------------------------------------------- */ 8794 8795function mk_milestone() { 8796 8797 "use strict"; 8798 8799 if( isTest || !$.exists('.mk-milestone') ) return; 8800 8801 $('.mk-milestone').each(function () { 8802 var $this = $(this), 8803 stop_number = $this.find('.milestone-number').attr('data-stop'), 8804 animation_speed = parseInt($this.find('.milestone-number').attr('data-speed')); 8805 8806 var build = function() { 8807 if (!$this.hasClass('scroll-animated')) { 8808 $this.addClass('scroll-animated'); 8809 8810 $({ 8811 countNum: $this.find('.milestone-number').text() 8812 }).animate({ 8813 countNum: stop_number 8814 }, { 8815 duration: animation_speed, 8816 easing: 'linear', 8817 step: function () { 8818 $this.find('.milestone-number').text(Math.floor(this.countNum)); 8819 }, 8820 complete: function () { 8821 $this.find('.milestone-number').text(this.countNum); 8822 } 8823 }); 8824 } 8825 }; 8826 8827 if ( !MK.utils.isMobile() ) { 8828 // refactored only :in-viewport logic. rest is to-do 8829 MK.utils.scrollSpy( this, { 8830 position: 'bottom', 8831 after: build 8832 }); 8833 } else { 8834 build(); 8835 } 8836 8837 }); 8838 8839} 8840 8841 8842 8843 8844/* Recent Works Widget */ 8845/* -------------------------------------------------------------------- */ 8846 8847function mk_portfolio_widget() { 8848 8849 "use strict"; 8850 8851 $('.widget_recent_portfolio li').each(function () { 8852 8853 $(this).find('.portfolio-widget-thumb').hover(function () { 8854 8855 $(this).siblings('.portfolio-widget-info').animate({ 8856 'opacity': 1 8857 }, 200); 8858 }, function () { 8859 8860 $(this).siblings('.portfolio-widget-info').animate({ 8861 'opacity': 0 8862 }, 200); 8863 }); 8864 8865 }); 8866} 8867 8868 8869 8870/* Skill Meter and Charts */ 8871/* -------------------------------------------------------------------- */ 8872function mk_skill_meter() { 8873 "use strict"; 8874 if ($.exists('.mk-skill-meter')) { 8875 if (!MK.utils.isMobile()) { 8876 $(".mk-skill-meter .progress-outer").each(function() { 8877 var $this = $(this); 8878 8879 var build = function() { 8880 if (!$this.hasClass('scroll-animated')) { 8881 $this.addClass('scroll-animated'); 8882 $this.animate({ 8883 width: $this.attr("data-width") + '%' 8884 }, 2000); 8885 } 8886 }; 8887 8888 MK.utils.scrollSpy( this, { 8889 position: 'bottom', 8890 after: build 8891 }); 8892 }); 8893 } else { 8894 $(".mk-skill-meter .progress-outer").each(function() { 8895 var $this = $(this); 8896 if (!$this.hasClass('scroll-animated')) { 8897 $this.addClass('scroll-animated'); 8898 $this.css({ 8899 width: $(this).attr("data-width") + '%' 8900 }); 8901 } 8902 }); 8903 } 8904 } 8905} 8906 8907// function mk_charts() { 8908// "use strict"; 8909 8910// if( !$.exists('.mk-chart') ) return; 8911 8912// MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.easyPieChart.js' ], function() { 8913 8914// $('.mk-chart').each(function() { 8915 8916// var $this = $(this), 8917// $parent_width = $(this).parent().width(), 8918// $chart_size = parseInt($this.attr('data-barSize')); 8919 8920// if ($parent_width < $chart_size) { 8921// $chart_size = $parent_width; 8922// $this.css('line-height', $chart_size); 8923// $this.find('i').css({ 8924// 'line-height': $chart_size + 'px' 8925// }); 8926// $this.css({ 8927// 'line-height': $chart_size + 'px' 8928// }); 8929// } 8930 8931// var build = function() { 8932// $this.easyPieChart({ 8933// animate: 1300, 8934// lineCap: 'butt', 8935// lineWidth: $this.attr('data-lineWidth'), 8936// size: $chart_size, 8937// barColor: $this.attr('data-barColor'), 8938// trackColor: $this.attr('data-trackColor'), 8939// scaleColor: 'transparent', 8940// onStep: function(value) {
8941// this.$el.find('.chart-percent span').text(Math.ceil(value)); 8942// } 8943// }); 8944// }; 8945 8946// // refactored only :in-viewport logic. rest is to-do 8947// MK.utils.scrollSpy( this, { 8948// position: 'bottom', 8949// after: build 8950// }); 8951 8952 8953// }); 8954// }); 8955// } 8956/* Toolbar subscribe form */ 8957/* -------------------------------------------------------------------- */ 8958 8959$( "#mc-embedded-subscribe-form" ).submit(function( e ){ 8960 var $this = $(this); 8961 8962 e.preventDefault(); 8963 $.ajax({ 8964 url: MK.core.path.ajaxUrl, 8965 type: "POST", 8966 data: { 8967 action: "mk_ajax_subscribe", 8968 email: $this.find( ".mk-subscribe--email" ).val(), 8969 list_id: $this.find( ".mk-subscribe--list-id" ).val(), 8970 optin: $this.find( ".mk-subscribe--optin" ).val() 8971 }, 8972 success: function ( res ) { 8973 $this.parent().find( ".mk-subscribe--message" ).html( $.parseJSON( res ).message ); 8974 } 8975 }); 8976}); 8977/** 8978 * Add class to tag. It's vanilla js instead of jQuery. 8979 * @param tag 8980 * @param className 8981 */ 8982function addClass(tag, className) { 8983 tag.className += ' ' + className; 8984} 8985 8986/** 8987 * Remove class from tag. It's vanilla js instead of jQuery. 8988 * Replacing should be with g for replacing all occurrence. 8989 * 8990 * @param tag 8991 * @param className 8992 */ 8993function removeClass(tag, className) { 8994 tag.className = tag.className.replace(new RegExp(className, 'g'), ''); 8995} 8996 8997 8998/** 8999 * If we're running under Node for testing purpose. 9000 */ 9001if(typeof exports !== 'undefined') { 9002 exports.addClass = addClass; 9003 exports.removeClass = removeClass; 9004} 9005 9006/*! 9007* javascript-debounce 1.0.0 9008* 9009* A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function. 9010* 9011* Source code available at: https://github.com/jgarber623/javascript-debounce 9012* 9013* (c) 2015-present Jason Garber (http://sixtwothree.org) 9014* 9015* javascript-debounce may be freely distributed under the MIT license. 9016*/ 9017 9018(function(root, factory) { 9019 if (typeof define === "function" && define.amd) { 9020 define([], factory); 9021 } else if (typeof exports === "object") { 9022 module.exports = factory(); 9023 } else { 9024 root.debounce = factory(); 9025 } 9026})(this, function() { 9027 "use strict"; 9028 return function(callback, delay) { 9029 var timeout; 9030 return function() { 9031 var context = this, args = arguments; 9032 clearTimeout(timeout); 9033 timeout = setTimeout(function() { 9034 callback.apply(context, args); 9035 }, delay); 9036 }; 9037 }; 9038}); 9039 9040/** 9041 * Validate email address. 9042 * 9043 * @param input 9044 * @param invalidClassName 9045 * @returns boolean 9046 */ 9047function validateEmail(input, invalidClassName) { 9048 var value = input.value.trim(); 9049 if ((input.required || value.length > 0) && !/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,63})$/i.test(value)) { 9050 if (invalidClassName) { 9051 addClass(input, invalidClassName); 9052 } 9053 return false; 9054 } else { 9055 if (invalidClassName) { 9056 removeClass(input, invalidClassName); 9057 } 9058 return true; 9059 } 9060} 9061 9062/** 9063 * Validate text entry. 9064 * 9065 * @param input 9066 * @param invalidClassName 9067 * @returns boolean 9068 */ 9069function validateText(input, invalidClassName) { 9070 var value = input.value.trim(); 9071 9072 if (input.required && value.length === 0) { 9073 if (invalidClassName) { 9074 addClass(input, invalidClassName); 9075 } 9076 return false; 9077 } else { 9078 if (invalidClassName) { 9079 removeClass(input, invalidClassName); 9080 } 9081 return true; 9082 } 9083} 9084 9085 9086/** 9087 * If we're running under Node for testing purpose. 9088 */ 9089if(typeof exports !== 'undefined') { 9090 exports.validateEmail = validateEmail; 9091 exports.validateText = validateText; 9092} 9093(function( $ ) { 9094 'use strict'; 9095 9096 var $wrapper = $('.js-bottom-corner-btns'); 9097 var $contactBtn = $wrapper.find('.js-bottom-corner-btn--contact'); 9098 var $backBtn = $wrapper.find('.js-bottom-corner-btn--back'); 9099 var hasContactBtn = $contactBtn.length; 9100 var hasBackBtn = $backBtn.length; 9101 9102 if(!hasBackBtn) return; 9103 9104 function deactivate() { 9105 $contactBtn.removeClass('is-active'); 9106 $backBtn.removeClass('is-active'); 9107 } 9108 9109 function activate() { 9110 $contactBtn.addClass('is-active'); 9111 $backBtn.addClass('is-active'); 9112 } 9113 9114 MK.utils.scrollSpy( 400, {
9115 before: deactivate, 9116 after: activate 9117 }); 9118 9119})( jQuery ); 9120(function( $ ) { 9121 'use strict'; 9122 9123 MK.ui.preloader = { 9124 dom : { 9125 overlay: '.mk-body-loader-overlay' 9126 }, 9127 9128 hide : function hide() { 9129 $( this.dom.overlay ).fadeOut(600, "easeInOutExpo", function() { 9130 $('body').removeClass('loading'); 9131 //$( this ).remove(); 9132 }); 9133 } 9134 }; 9135 9136})( jQuery ); 9137(function($) { 9138 'use strict'; 9139 9140 $('.mk-fullscreen-nav-close, .mk-fullscreen-nav-wrapper, #fullscreen-navigation a').on('click', function(e) { 9141 9142 // Close nav with removing classes 9143 $('.mk-fullscreen-nav').removeClass('opened'); 9144 $('.mk-dashboard-trigger').removeClass('fullscreen-active'); 9145 $('body').removeClass('fullscreen-nav-opened'); 9146 9147 var anchor = MK.utils.detectAnchor( this ), 9148 $this = $( this ); 9149 9150 // Scroll to anchor if exists 9151 if( anchor.length ) { 9152 // Moved 4 these lines after anchor check because console error. If anchor 9153 // return false, split part will throw an error because $this is not a link. 9154 // Fix AM-2027 9155 var href = $this.attr( 'href' ).split( '#' )[0]; 9156 var url = window.location.href; 9157 var isSamePage = url.indexOf( href ) !== -1; 9158 9159 if ( isSamePage ) { 9160 e.preventDefault(); 9161 } 9162 MK.utils.scrollToAnchor( anchor ); 9163 9164 // Or do nothing if pointless # as href 9165 // BAD PRACTICE: it is very popular to use "#" for click elements that we listen to with js. 9166 // GOOD PRACTICE: prefer "javascript:;" as easier to handle and more readable version 9167 } else if( $this.attr( 'href' ) === '#' ) { 9168 e.preventDefault(); 9169 } 9170 }); 9171 9172 $('.fullscreen-navigation-ul .menu-sub-level-arrow').on('click', function(){ 9173 $(this).siblings('.sub-menu').slideToggle(); 9174 }); 9175 9176}(jQuery)); 9177(function($) { 9178 'use strict'; 9179 9180 /** 9181 * Mega menu 9182 */ 9183 var $navList = $(".main-navigation-ul"); 9184 var megaMenu = function megaMenu() { 9185 9186 $navList.MegaMenu({ 9187 type: "vertical", 9188 delay: 200 9189 }); 9190 }; 9191 9192 $(window).on('load', megaMenu); 9193 9194}(jQuery)); 9195(function($) { 9196 'use strict'; 9197 9198 /** 9199 * One pager menu hash update. 9200 * Smooth scroll is appended globally whenever the click element has corresponding #el 9201 */ 9202 var onePageNavItem = function onePageNavItem() { 9203 var $this = $( this ), 9204 link = $this.find( 'a' ), 9205 anchor = MK.utils.detectAnchor( link ); // anchor on current page 9206 9207 if( !anchor.length ) return; 9208 9209 $this.removeClass( 'current-menu-item current-menu-ancestor current-menu-parent' ); 9210 9211 var activeNav = function( state ) { 9212 return function() { 9213 $this[ state ? 'addClass' : 'removeClass' ]( 'current-menu-item' ); 9214 window.history.replaceState( undefined, undefined, [ state ? anchor : ' ' ] ); 9215 }; 9216 }; 9217 9218 MK.utils.scrollSpy( $( anchor )[0], { 9219 before : activeNav( false ), 9220 active : activeNav( true ), 9221 after : activeNav( false ), 9222 }); 9223 }; 9224 9225 var $navItems = $('.js-main-nav').find( 'li' ); 9226 9227 $(window).on('load', function() { 9228 // Wait with spying anchors so we do not assign anchor that is browser scroll to after page load 9229 // Especially when there are anchors on top - refreshing page can cause grabbing one of them into url 9230 // and force unwanted scroll 9231 setTimeout(function() { 9232 $navItems.each( onePageNavItem ); 9233 }, 1000); 9234 }); 9235 9236}(jQuery)); 9237(function($) { 9238 'use strict'; 9239 9240 var $window = $(window); 9241 var $body = $('body'); 9242 var $resMenuWrap = $('.mk-responsive-wrap'); 9243 var $post_nav = $('.mk-post-nav'); 9244 var $toolbar = $('.mk-header-toolbar'); 9245 var $resMenuLink = $('.mk-nav-responsive-link'); 9246 9247 // Flags 9248 var hasResMenu = ($resMenuWrap.length > 0); 9249 9250 //initial window and screen height 9251 var windowHeight = $window.height(); 9252 var screenHeight = screen.height; 9253 9254 // We keep this handler above hasResMenu flag. 9255 // Even if our header doesn't contain droppable responsive menu (in favor of fullscreen or side menu) 9256 // we still transform tollbar into collapsible menu part in responsive state 9257 $('.mk-toolbar-resposnive-icon').on('click', function(e) { 9258 e.preventDefault(); 9259 console.log('clicked'); 9260 if ($body.hasClass('toolbar-opened')) { 9261 $body.removeClass('toolbar-opened').addClass('toolbar-closed'); 9262 $toolbar.hide(); 9263 } else { 9264 $body.removeClass('toolbar-closed').addClass('toolbar-opened'); 9265 $toolbar.show(); 9266 } 9267 }); 9268 9269 9270 if ( ! hasResMenu && ! $('.vc_mk_header') ) return; 9271 9272 function toggleResMenu(e) { 9273 e.preventDefault(); 9274 var $this = $(this); 9275 var $headerInner = $this.parents('header'); 9276 var $resMenu = $headerInner.find('.mk-responsive-wrap'); 9277 var searchBox = $('.responsive-searchform .text-input'); 9278 var adminBarHeight = $('#wpadminbar').height(); /* Fix AM-1918 */ 9279 9280 if ($body.hasClass('mk-opened-nav')) { 9281 $this.removeClass('is-active'); 9282 $body.removeClass('mk-opened-nav').addClass('mk-closed-nav').trigger('mk-closed-nav'); 9283 $resMenu.hide(); 9284 $post_nav.removeClass('post-nav-backward'); 9285 } else { 9286 $this.addClass('is-active'); 9287 $body.removeClass('mk-closed-nav').addClass('mk-opened-nav').trigger('mk-opened-nav'); 9288 $resMenu.show(); 9289 $post_nav.addClass('post-nav-backward'); 9290 9291 } 9292 9293 //for iPhone 5 focus bug , remove search box focused class 9294 if(searchBox.hasClass('input-focused')){ 9295 searchBox.removeClass('input-focused'); 9296 } 9297 9298 } 9299 9300 $resMenuLink.each(function() { 9301 $(this).on('click', toggleResMenu); 9302 }); 9303 9304 $( window ).on( 'vc_reload', function () { 9305 $('.vc_mk_header .mk-nav-responsive-link').each(function() { 9306 $(this).on('click', toggleResMenu); 9307 }); 9308 } ) 9309 9310 var setResMenuHeight = function() { 9311 var height = $window.height() - MK.val.offsetHeaderHeight(0); 9312 $resMenuWrap.css('max-height', height); 9313 }; 9314 9315 // check if device virtual keyboard is active 9316 var isVirtualKeyboard = function() { 9317 var currentWindowHeight = $window.height(); 9318 var currentScreenHeight = screen.height; 9319 var searchBox = $('.responsive-searchform .text-input'); 9320 var searchBoxIsFocused = false; 9321 9322 //for iPhone 5 focus bug , add class for detect focus state 9323 searchBox.on('touchstart touchend', function(e) { 9324 searchBox.addClass('input-focused'); 9325 }); 9326 9327 searchBoxIsFocused = (searchBox.is(':focus') || searchBox.hasClass("input-focused")); 9328 9329 if ($body.hasClass('mk-opened-nav') && searchBoxIsFocused && currentScreenHeight == screenHeight && currentWindowHeight != windowHeight) { 9330 return true; 9331 } else { 9332 return false;
9333 } 9334 }; 9335 9336 var hideResMenu = function hideResMenu() { 9337 if (MK.utils.isResponsiveMenuState()) { 9338 9339 //when search box in responsive menu is focused , window resize fired but at this time responsive menu should be open 9340 if (!isVirtualKeyboard()) { 9341 // hide toggled menu and its states 9342 if ($body.hasClass('mk-opened-nav')) { 9343 $resMenuLink.filter('.is-active').trigger('click'); 9344 } 9345 // hide menu wrapper 9346 $resMenuWrap.hide(); 9347 9348 } 9349 } 9350 }; 9351 9352 $resMenuWrap.on('click', 'a', hideResMenu); 9353 9354}(jQuery)); 9355 9356(function($) { 9357 'use strict'; 9358 9359 var $header = $('.mk-header'); 9360 var hasHeader = ($header.length > 0); 9361 9362 if(!hasHeader && ! $('.vc_mk_header') ) return; 9363 9364 var $sticky_style = $header.attr('data-header-style'); 9365 9366 //if ($sticky_style !== 3) return; 9367 9368 $('.sidedash-navigation-ul > li').each(function() { 9369 var $this = $(this); 9370 9371 $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>'); 9372 }); 9373 9374 function toggleSubMenu(e) { 9375 e.preventDefault(); 9376 var $this = $(this); 9377 9378 if ($this.hasClass('mk-nav-sub-closed')) { 9379 $this.siblings('ul').slideDown(450).end().removeClass('mk-nav-sub-closed').addClass('mk-nav-sub-opened'); 9380 } else { 9381 $this.siblings('ul').slideUp(450).end().removeClass('mk-nav-sub-opened').addClass('mk-nav-sub-closed'); 9382 } 9383 }; 9384 9385 function toggleFullMenu(e) { 9386 e.preventDefault(); 9387 var $this = $(this), 9388 $body = $('body'), 9389 $fullscreen_box = $('.mk-fullscreen-nav'); 9390 9391 if ($this.hasClass('dashboard-style')){ 9392 if (!$this.hasClass('dashboard-active')) { 9393 $this.addClass('dashboard-active'); 9394 $body.addClass('dashboard-opened'); 9395 } else { 9396 $this.removeClass('dashboard-active'); 9397 $body.removeClass('dashboard-opened'); 9398 } 9399 }else if($this.hasClass('fullscreen-style')){ 9400 if (!$this.hasClass('fullscreen-active')) { 9401 $this.addClass('fullscreen-active'); 9402 $body.addClass('fullscreen-nav-opened'); 9403 $fullscreen_box.addClass('opened'); 9404 // MK.utils.scroll.disable(); 9405 } else { 9406 $this.removeClass('fullscreen-active'); 9407 $body.removeClass('fullscreen-nav-opened'); 9408 $fullscreen_box.removeClass('opened'); 9409 } 9410 } 9411 } 9412 9413 $('.mk-nav-arrow').each(function() { 9414 $(this).stop(true).on('click', toggleSubMenu); 9415 }); 9416 9417 $('.mk-dashboard-trigger').each(function() { 9418 $(this).on('click', toggleFullMenu); 9419 }); 9420 9421 $( window ).on( 'vc_reload', function () { 9422 $('.vc_mk_header .mk-dashboard-trigger').each(function() { 9423 $(this).on('click', toggleFullMenu); 9424 }); 9425 9426 $('.vc_mk_header .mk-nav-arrow').each(function() { 9427 $(this).stop(true).on('click', toggleSubMenu); 9428 }); 9429 } ); 9430 9431 $('html').on('click', function() { 9432 $('body').removeClass('dashboard-opened'); 9433 $('.mk-dashboard-trigger').removeClass('dashboard-active'); 9434 }); 9435 9436}(jQuery)); 9437 9438(function($) { 9439 'use strict'; 9440 9441 /** 9442 * Vertical menu 9443 */ 9444 var $verticalMenu = $('#mk-vm-menu'); 9445 var verticalMenu = function verticalMenu() { 9446 if(!$verticalMenu.data('vertical-menu') && !MK.utils.isResponsiveMenuState()) { 9447 $verticalMenu.dlmenu(); 9448 $verticalMenu.data('vertical-menu', true); 9449 } 9450 }; 9451 9452 verticalMenu(); 9453 $(window).on('resize', verticalMenu); 9454 9455}(jQuery)); 9456(function($) { 9457 'use strict'; 9458 9459 // WPML 9460 var $lang_item = $('.mk-main-navigation > .main-navigation-ul > .menu-item-language'); 9461 $lang_item.addClass('no-mega-menu').css('visibility', 'visible'); 9462 $('.mk-main-navigation .menu-item-language > a').addClass('menu-item-link'); 9463 9464})(jQuery); 9465(function($) { 9466 'use strict'; 9467 9468 var $header = $( '.mk-header' ).first(); // Theme header is always first, do not apply to shortcode headers. 9469 var hasHeader = ($header.length > 0); 9470 9471 if(!hasHeader) return; 9472 9473 var $window = $( window ); 9474 var $document = $( document ); 9475 var $headerHolder = $header.find( '.mk-header-holder' ); 9476 var $paddingWrapper = $header.find('.mk-header-padding-wrapper'); 9477 var config = $header.data(); 9478 9479 /** 9480 * Flags 9481 * @type {Boolean} 9482 */ 9483 var isStickyLazy = (config.stickyStyle === 'lazy'); 9484 var isStickyFixed = (config.stickyStyle === 'fixed'); 9485 var isStickySlide = (config.stickyStyle === 'slide'); 9486 9487 function isSticky() { // Check for sticky compatibility 9488 //return config.headerStyle !== 4; header style 4 needs sticky state for transparent header. 9489 return true; 9490 } 9491
9492 function isColorable() { // Check for coloring compatibility 9493 // TODO make it explicit in DOM that header is transparent as this is only scenario for colorable header 9494 // Monkey patch - exclude header styles that don't fit colorable 9495 return config.headerStyle !== 4; 9496 } 9497 9498 9499 /** 9500 * Change header skin 9501 */ 9502 function changeSkin( e, skin ) { 9503 $header.attr( 'data-transparent-skin', skin ); 9504 // Fix for class based skining 9505 var contrast = skin === 'light' ? 'dark' : 'light'; 9506 $header.addClass(skin + '-skin'); 9507 $header.removeClass(contrast + '-skin'); 9508 } 9509 9510 if(isColorable()) MK.utils.eventManager.subscribe( 'firstElSkinChange', changeSkin ); 9511 9512 9513 // Assign sticky scenarions 9514 if (isSticky() && isStickyLazy) { 9515 if(config.headerStyle !== 2) { 9516 lazySticky(); 9517 } 9518 } 9519 else if (isSticky() && isStickyFixed) fixedSticky(); 9520 else if (isSticky() && isStickySlide) slideSticky(); 9521 9522 /** 9523 * Sticky header behavior: Lazy 9524 */ 9525 function lazySticky() { 9526 var elClassHidden = 'header--hidden'; 9527 var elClassSticky = 'a-sticky'; 9528 var wScrollCurrent = 0; 9529 var wScrollBefore = 0; 9530 var wScrollDiff = 0; 9531 var wHeight = 0; 9532 var dHeight = 0; 9533 9534 var setSizes = function setSizes() { 9535 dHeight = $document.height(); 9536 wHeight = $window.height(); 9537 }; 9538 9539 var onScroll = function onScroll() { 9540 wScrollCurrent = MK.val.scroll(); 9541 wScrollDiff = wScrollBefore - wScrollCurrent; 9542 9543 if( wScrollCurrent <= 0 ) { // scrolled to the very top; element sticks to the top 9544 $headerHolder.removeClass( elClassHidden ); 9545 $header.removeClass( elClassSticky ); 9546 $('body').trigger('mk:header-unsticky'); 9547 9548 } else if( wScrollDiff > 0 && $headerHolder.hasClass( elClassHidden ) ) { // scrolled up; element slides in 9549 $headerHolder.removeClass( elClassHidden ); 9550 $header.addClass( elClassSticky ); 9551 $('body').trigger('mk:header-sticky'); 9552 9553 } else if( wScrollDiff < 0 ) { // scrolled down 9554 9555 if( wScrollCurrent + wHeight >= dHeight && $headerHolder.hasClass( elClassHidden ) ) { // scrolled to the very bottom; element slides in 9556 $headerHolder.removeClass( elClassHidden ); 9557 $header.addClass( elClassSticky ); 9558 $('body').trigger('mk:header-sticky'); 9559 } else { // scrolled down; element slides out 9560 $headerHolder.addClass( elClassHidden ); 9561 $header.removeClass( elClassSticky ); 9562 $('body').trigger('mk:header-unsticky'); 9563 } 9564 } 9565 9566 wScrollBefore = wScrollCurrent; 9567 }; 9568 9569 setSizes(); 9570 onScroll(); 9571 $window.on( 'resize', MK.utils.throttle( 100, setSizes ) ); 9572 $window.on( 'scroll', MK.utils.throttle( 500, onScroll ) ); 9573 } 9574 9575 9576 /** 9577 * Sticky header behavior: Fixed 9578 */ 9579 function fixedSticky() { 9580 var sticked = false; 9581 var scrollPos; 9582 9583 var toggleState = function toggleState() { 9584 scrollPos = MK.val.scroll() + MK.val.adminbarHeight(); 9585 9586 if( (scrollPos > MK.val.stickyOffset() ) && ! MK.utils.isResponsiveMenuState() ) { 9587 if(sticked) return; // stop if already sticked 9588 $header.addClass('a-sticky'); 9589 sticked = true; 9590 $('body').trigger('mk:header-sticky'); 9591 } else { 9592 if(!sticked) return; // stop if already unsticked 9593 $header.removeClass('a-sticky'); 9594 sticked = false; 9595 $('body').trigger('mk:header-unsticky'); 9596 } 9597 }; 9598 9599 toggleState(); 9600 $window.on( 'scroll', MK.utils.throttle( 100, toggleState) ); 9601 $window.on( 'resize', MK.utils.throttle( 100, toggleState) ); 9602 } 9603 9604 9605 /** 9606 * Sticky header behavior: Slide 9607 */ 9608 function slideSticky() { 9609 var sticked = false;
9610 var onScroll = function onScroll() { 9611 if (MK.val.scroll() > MK.val.stickyOffset()) { 9612 if(sticked) return; // stop if already sticked 9613 $header.addClass('pre-sticky'); 9614 $paddingWrapper.addClass('enable-padding'); 9615 setTimeout(function() { 9616 $header.addClass('a-sticky'); 9617 $('body').trigger('mk:header-sticky'); 9618 }, 1); 9619 sticked = true; 9620 } else { 9621 if(!sticked) return; // stop if already unsticked 9622 $header.removeClass('a-sticky'); 9623 $header.removeClass('pre-sticky'); 9624 $paddingWrapper.removeClass('enable-padding'); 9625 sticked = false; 9626 $('body').trigger('mk:header-unsticky'); 9627 } 9628 }; 9629 9630 onScroll(); 9631 $window.on( 'scroll', MK.utils.throttle( 100, onScroll) ); 9632 } 9633 9634 // TODO 9635 // var pageIntro = $('body').data('intro'); // block scrolling on page intro 9636 9637 9638})( jQuery ); 9639 9640(function($){ 9641 'use strict'; 9642 9643 // Do not assign at all if no touch events 9644 var hasTouchscreen = ('ontouchstart' in document.documentElement); 9645 if(!hasTouchscreen) return; 9646 9647 $('.mk-main-navigation .menu-item-has-children').each( normalizeClick ); 9648 9649 function normalizeClick() { 9650 $(this).on('click', handleClick); 9651 } 9652 9653 // 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. 9654 // 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 9655 function handleClick(e) { 9656 var $this = $(e.currentTarget); 9657 var $child = $this.find('> ul'); 9658 var isVisible = $child.css('display') !== 'none'; 9659 9660 if(!isVisible) { 9661 e.preventDefault(); 9662 e.stopPropagation(); 9663 } 9664 } 9665 9666}(jQuery)); 9667(function($) { 9668 'use strict'; 9669 9670 var _ajaxUrl = MK.core.path.ajaxUrl; 9671 var _instances = {}; 9672 9673 MK.utils.ajaxLoader = function ajaxLoader(el) { 9674 // retrun a cached instance to have control over state from within multiple places 9675 // we may need for example to reset pageId when do filtering. It is really one instance that controls both filtering and pagination / load more 9676 var id = '#' + ($(el).attr('id')); 9677 if(typeof _instances[id] !== 'undefined') return _instances[id]; 9678 9679 // else lets start new instance 9680 this.id = id; 9681 this.el = el; 9682 this.isLoading = false; 9683 this.xhrCounter = 0; 9684 }; 9685 9686 MK.utils.ajaxLoader.prototype = { 9687 init: function init() { 9688 // prevent double initialization of we return an instance 9689 if ( this.initialized && typeof window.vc_iframe === 'undefined' ) { 9690 return; 9691 } 9692 9693 this.createInstance(); 9694 this.cacheElements(); 9695 9696 this.initialized = true; 9697 }, 9698 9699 cacheElements: function cacheElements() { 9700 this.$container = $(this.el); 9701 this.id = '#' + (this.$container.attr('id')); 9702 this.categories = this.$container.data('loop-categories'); 9703 9704 this.data = {}; 9705 this.data.action = 'mk_load_more'; 9706 this.data.query = this.$container.data('query'); 9707 this.data.atts = this.$container.data('loop-atts'); 9708 this.data.loop_iterator = this.$container.data('loop-iterator'); 9709 this.data.author = this.$container.data('loop-author'); 9710 this.data.posts = this.$container.data('loop-posts'); 9711 this.data.safe_load_more = this.$container.siblings('#safe_load_more').val(); 9712 this.data._wp_http_referer = this.$container.siblings('input[name="_wp_http_referer"]').val(); 9713 this.data.paged = 1; 9714 this.data.maxPages = this.$container.data('max-pages'); 9715 this.data.term = this.categories; 9716 }, 9717 9718 createInstance: function() { 9719 _instances[this.id] = this; 9720 }, 9721 9722 load: function load(unique) { 9723 var self = this; 9724 var seq = ++this.xhrCounter; 9725 this.isLoading = true; 9726 9727 // If mk-ajax-loaded-posts span exists, get the post ids 9728 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 9729 var loaded_posts = this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts'); 9730
9731 // Do not send looaded posts for Classic Pagination Navigation 9732 if ( this.$container.attr('data-pagination-style') != 1 ) { 9733 self.data.loaded_posts = loaded_posts.split(','); 9734 } 9735 } 9736 9737 return $.when( 9738 $.ajax({ 9739 url : _ajaxUrl, 9740 type : "POST", 9741 data : self.data 9742 }) 9743 ).done(function(response) { 9744 self.onDone(response, unique, seq); 9745 }); 9746 }, 9747 9748 onDone: function(response, unique, seq) { 9749 if(seq === this.xhrCounter) { 9750 var self = this; 9751 9752 response = $.parseJSON(response); 9753 response.unique = unique; 9754 response.id = this.id; 9755 9756 // If mk-ajax-loaded-posts span exists, update current post ids 9757 // with new post ids from server's response 9758 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 9759 this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', response.loaded_posts); 9760 } 9761 9762 this.setData({ 9763 maxPages: response.maxPages, 9764 found_posts: response.found_posts, 9765 loop_iterator: response.i 9766 }); 9767 9768 // Preload images first by creating object from returned content. 9769 // mk_imagesLoaded() method will create a promise that gets resolved when all images inside are loaded. 9770 // Our ajaxLoad is somehow more similar to window.onload event now. 9771 $(response.content).mk_imagesLoaded().then(function() { 9772 MK.utils.eventManager.publish('ajaxLoaded', response); 9773 self.isLoading = false; 9774 self.initNewComponents(); 9775 }); 9776 9777 } else console.log('XHR request nr '+ seq +' aborted'); 9778 9779 }, 9780 9781 setData: function setData(atts) { 9782 for(var att in atts) { 9783 if(att === 'term' && atts[att] === '*') this.data.term = ''; 9784 else this.data[att] = atts[att]; 9785 } 9786 }, 9787 9788 getData: function getData(att) { 9789 return this.data[att]; 9790 }, 9791 9792 initNewComponents: function initNewComponents() { 9793 // Legacy scripts reinit 9794 window.ajaxInit(); 9795 setTimeout(window.ajaxDelayedInit, 1000); 9796 // New way to init apended things 9797 MK.core.initAll(this.el); 9798 } 9799 }; 9800 9801}(jQuery)); 9802MK.component.BackgroundImageSetter = (function ($) { 9803 9804 'use strict'; 9805 9806 var module = {}; 9807 9808 9809 /*---------------------------------------------------------------------------------*/ 9810 /* Private Variables 9811 /*---------------------------------------------------------------------------------*/ 9812 9813 /** 9814 * Take all elements with data-mk-img-set attribute and evaluate best image according to given device orientation and resolution, 9815 * sets style for backround-image on the same node element. * 9816 */ 9817 9818 var $win = $(window), 9819 // $layers = $('[data-mk-img-set]'), 9820 screen = getScreenSize(), 9821 orientation = getOrientation(), 9822 device = getDevice(), 9823 lastOrientation = orientation, 9824 lastDevice = device; 9825 9826 9827 /*---------------------------------------------------------------------------------*/ 9828 /* Private Methods 9829 /*---------------------------------------------------------------------------------*/ 9830 9831 function run($layers) { 9832 $layers.filter( function() { 9833 return !this.hasAttribute("mk-img-loaded"); 9834 }).each(applyBg); 9835 } 9836 9837 // Keep our main side effect out of calculations so they can be run once before loop of applying bg as a result 9838 function applyBg() { 9839 var $this = $(this), 9840 imgs = $this.data('mk-img-set'); 9841 9842 $this.css('background-image', 'url('+ module.getImage(imgs) +')'); 9843 $this.find('.mk-adaptive-image').attr('src', module.getImage(imgs)); 9844 } 9845 9846 // Keep track of current screen size while resizing but update device reference 9847 // and reapply backgrounds only when we discover switch point 9848 function handleResize($layers) { 9849 updateScreenSize(); 9850 if(hasSwitched()) { 9851 updateDevice(); 9852 run($layers); 9853 } 9854 } 9855 9856 function getScreenSize() { 9857 return { 9858 w: $win.width(), 9859 h: $win.height() 9860 }; 9861 } 9862 9863 // Name our device classes and add them id which simply means which one is wider 9864 function getDevice() { 9865 if (screen.w > 1024) return {class: 'desktop', id: 2}; 9866 else if(screen.w > 736) return {class: 'tablet', id: 1}; 9867 else return {class: 'mobile', id: 0}; 9868 } 9869 9870 function getOrientation() { 9871 if(screen.w > screen.h) return 'landscape'; 9872 else return 'portrait'; 9873 } 9874 9875 function updateScreenSize() { 9876 screen = getScreenSize(); 9877 } 9878 9879 function updateDevice() { 9880 if(lastOrientation !== orientation) orientation = lastOrientation; 9881 // Switch device only if going from smaller size to bigger. 9882 // Bigger to smaller is perfectly handled by browsers and doesn't require change and reupload 9883 if(lastDevice.id > device.id) device = lastDevice; 9884 } 9885 9886 function hasSwitched() { 9887 lastOrientation = getOrientation(); 9888 lastDevice = getDevice(); 9889 9890 if(lastOrientation !== orientation || lastDevice.class !== device.class) return true; 9891 else return false;
9892 } 9893 9894 9895 /*---------------------------------------------------------------------------------*/ 9896 /* Public Methods 9897 /*---------------------------------------------------------------------------------*/ 9898 9899 // As desired image might be not available we have to evaluate the best match. 9900 module.getImage = function (imgs) { 9901 if (imgs['responsive'] === 'false') { 9902 return (imgs['landscape']['desktop']) ? imgs['landscape']['desktop'] : (imgs['landscape']['external'] ? imgs['landscape']['external'] : ''); 9903 9904 } 9905 var hasOrientation = !!imgs[orientation]; 9906 // there are only two orientations now and we may get them by string name if both are there 9907 // 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. 9908 // 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 9909 var imgOriented = imgs[ (hasOrientation ? orientation : Object.keys(imgs)[0]) ], 9910 imgExact = (imgOriented[device.class]) ? imgOriented[device.class] : (imgOriented['external'] ? imgOriented['external'] : ''); 9911 return imgExact; 9912 } 9913 9914 module.init = function ($layers) { 9915 9916 // Run and bind 9917 run($layers); 9918 $layers.attr('mk-img-loaded', ''); 9919 }; 9920 9921 module.onResize = function ($layers) { 9922 $win.on('resize', MK.utils.throttle( 500, function() { 9923 handleResize($layers); 9924 })); 9925 }; 9926 9927 return module; 9928 9929}(jQuery)); 9930 9931 9932jQuery(function($) { 9933 9934 var init = function init() { 9935 // Get All Layers, Excluding Edge Slider and Page Section 9936 $allLayers = $('[data-mk-img-set]').filter(function(index) { 9937 return !$(this).hasClass('mk-section-image') && !$(this).hasClass('background-layer') && !$(this).hasClass('mk-video-section-touch'); 9938 });; 9939 9940 // Handle the resize 9941 MK.component.BackgroundImageSetter.onResize($allLayers); 9942 9943 // Set all the BG Layers 9944 MK.component.BackgroundImageSetter.init($allLayers); 9945 } 9946 init(); 9947 9948 $(window).on('vc_reload', init); 9949 9950}); 9951 9952(function( $ ) { 9953 'use strict'; 9954 9955 var val = MK.val; 9956 9957 MK.component.FullHeight = function( el ) { 9958 var $window = $( window ), 9959 $this = $( el ), 9960 config = $this.data( 'fullheight-config' ), 9961 container = document.getElementById( 'mk-theme-container' ), 9962 minH = (config && config.min) ? config.min : 0, 9963 winH = null, 9964 height = null, 9965 update_count = 0, 9966 testing = MK.utils.getUrlParameter('testing'), 9967 offset = null; 9968 9969 // We need to provide height on the same specificity level for workaround to IE bug 9970 // connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview 9971 // stackoverflow.com/questions/19371626/flexbox-not-centering-vertically-in-ie 9972 if(MK.utils.browser.name === ('IE' || 'Edge')) $this.css( 'height', '1px' ); 9973 9974 var update = function() { 9975 9976 if(update_count === 0) { 9977 winH = $window.height(); 9978 // for correct calculate 9979 offset = $this.offset().top - 1; 9980 height = Math.max(minH, winH - val.offsetHeaderHeight( offset )); 9981 $this.css( 'min-height', height ); 9982 if(testing !== undefined ) 9983 update_count++; 9984 } 9985 9986 }; 9987 9988 // TODO remove scroll listener by dynamic offset reader 9989 var init = function() { 9990 update(); 9991 $window.on( 'resize', update ); 9992 $window.on( 'scroll', update ); 9993 window.addResizeListener( container, update ); 9994 }; 9995 9996 return { 9997 init : init 9998 }; 9999 }; 10000 10001})( jQuery ); 10002 10003 10004(function( $ ) { 10005 'use strict'; 10006 10007 var core = MK.core, 10008 utils = MK.utils, 10009 path = MK.core.path; 10010 10011 10012 MK.ui.FullScreenGallery = function( element, settings ) { 10013 this.element = element; 10014 this.config = settings; 10015 10016 this.isFullScreen = false; 10017 }; 10018 10019 10020 // preload slick PLUGIN TO USE THIS 10021 MK.ui.FullScreenGallery.prototype = { 10022 dom : { 10023 fullScrBtn : '.slick-full-screen', 10024 exitFullScrBtn : '.slick-minimize', 10025 playBtn : '.slick-play', 10026 pauseBtn : '.slick-pause', 10027 shareBtn : '.slick-share', 10028 socialShare : '.slick-social-share', 10029 wrapper : '.slick-slider-wrapper', 10030 slider : '.slick-slides', 10031 slides : '.slick-slide', 10032 dots : '.slick-dot', 10033 active : '.slick-active', 10034 hiddenClass : 'is-hidden', 10035 dataId : 'slick-index' 10036 }, 10037 10038 tpl: { 10039 dot : '<div class="slick-dot"></div>', 10040 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>', 10041 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>' 10042 }, 10043 10044 init : function() { 10045 var self = this; 10046 10047 // core.loadDependencies([ path.plugins + 'slick.js' ], function() { 10048 self.cacheElements(); 10049 self.getViewportSizes(); 10050 self.updateSizes( 'window' ); 10051 self.create(); 10052 // update cache with elements propagated by plugin 10053 self.updateCacheElements(); 10054 self.createPagination(); 10055 self.bindEvents(); 10056 // }); 10057 }, 10058 10059 create : function() { 10060 var self = this; 10061 10062 this.slick = this.$gallery.slick({ 10063 dots: true, 10064 arrows: true, 10065 infinite: true, 10066 speed: 300, 10067 slidesToShow: 1, 10068 centerMode: true, 10069 centerPadding: '0px', 10070 variableWidth: true, 10071 autoplay: false, 10072 autoplaySpeed: 3000, 10073 useTransform: true, 10074 prevArrow: self.tpl.prev, 10075 nextArrow: self.tpl.next, 10076 customPaging: function(slider, i) { 10077 return self.tpl.dot; 10078 }, 10079 }); 10080 }, 10081 10082 cacheElements : function() { 10083 this.$window = $( window ); 10084 this.$gallery = $( this.element ); 10085 10086 this.$fullScrBtn = $( this.dom.fullScrBtn ); 10087 this.$exitFullScrBtn = $( this.dom.exitFullScrBtn ); 10088 this.$playBtn = $( this.dom.playBtn ); 10089 this.$pauseBtn = $( this.dom.pauseBtn ); 10090 this.$shareBtn = $( this.dom.shareBtn ); 10091 this.$socialShare = $( this.dom.socialShare ); 10092 10093 this.$wrapper = $( this.dom.wrapper ); 10094 this.$slider = $( this.dom.slider ); 10095 this.$slides = $( this.dom.slides ); 10096 this.$imgs = this.$slides.find( 'img' ); 10097 // store reference to initial images without slides appended by pugin 10098 // - needed for creating of pagination 10099 this.$originalImgs = this.$imgs; 10100 }, 10101 10102 updateCacheElements : function() { 10103 this.$slides = $( this.dom.slides ); 10104 this.$imgs = this.$slides.find( 'img' ); 10105 this.$dots = $( this.dom.dots ); 10106 }, 10107 10108 bindEvents : function() { 10109 var self = this; 10110 this.$fullScrBtn.on( 'click', this.toFullScreen.bind( this ) ); 10111 this.$exitFullScrBtn.on( 'click', this.exitFullScreen.bind( this ) ); 10112 this.$playBtn.on( 'click', this.play.bind( this ) ); 10113 this.$pauseBtn.on( 'click', this.pause.bind( this ) ); 10114 this.$shareBtn.on( 'click', this.toggleShare.bind( this ) ); 10115 this.$socialShare.on( 'click', 'a', this.socialShare.bind( this ) ); 10116 this.$window.on( 'resize', this.onResize.bind( this ) ); 10117 this.$window.on( 'keydown', function(e) { 10118 if(e.keyCode === 39) self.$gallery.slick('slickNext'); 10119 if(e.keyCode === 37) self.$gallery.slick('slickPrev'); 10120 }); 10121 $( document ).on( 'fullscreenchange mozfullscreenchange webkitfullscreenchange msfullcreenchange', this.exitFullScreen.bind( this ) ); 10122 }, 10123 10124 getViewportSizes : function() { 10125 this.screen = { 10126 w: screen.width, 10127 h: screen.height 10128 }; 10129 this.window = { 10130 w: this.$window.width(), 10131 h: this.$window.height() 10132 }; 10133 }, 10134 10135 updateSizes : function( viewport ) { 10136 this.$wrapper.width( this[ viewport ].w ); 10137 this.$wrapper.height( '100%' ); 10138 this.$imgs.height( '100%'); 10139 }, 10140 10141 createPagination : function() { 10142 var self = this; 10143 this.$dots.each( function( i ) { 10144 var img = self.$originalImgs.eq( i ).attr( 'src' ); 10145 10146 $( this ).css({ 10147 'background-image': 'url('+ img +')' 10148 }); 10149 }); 10150 }, 10151 10152 play : function(e) { 10153 e.preventDefault(); 10154 this.$playBtn.addClass( this.dom.hiddenClass ); 10155 this.$pauseBtn.removeClass( this.dom.hiddenClass ); 10156 $( this.element ).slick( 'slickPlay' ); 10157 }, 10158 10159 pause : function(e) { 10160 e.preventDefault(); 10161 this.$pauseBtn.addClass( this.dom.hiddenClass ); 10162 this.$playBtn.removeClass( this.dom.hiddenClass ); 10163 $( this.element ).slick( 'slickPause' ); 10164 }, 10165 10166 toggleShare : function(e) { 10167 e.preventDefault(); 10168 this.$socialShare.toggleClass( this.dom.hiddenClass ); 10169 }, 10170 10171 getCurentId : function() { 10172 return this.$slides.filter( this.dom.active ).data( this.dom.dataId ); 10173 }, 10174 10175 toFullScreen : function() { 10176 var self = this; 10177 10178 this.$fullScrBtn.addClass( this.dom.hiddenClass ); 10179 this.$exitFullScrBtn.removeClass( this.dom.hiddenClass ); 10180 10181 this.$slider.hide().fadeIn( 500 ); 10182 utils.launchIntoFullscreen( document.documentElement ); 10183 this.updateSizes( 'screen' ); 10184 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10185 10186 // Update state with delay so we avoid triggering exitFullScreen fn from 10187 // fullscreenchange event 10188 setTimeout( function() { 10189 self.isFullScreen = true; 10190 }, 1000); 10191 }, 10192 10193 exitFullScreen : function() { 10194 if( this.isFullScreen ) { 10195 this.$exitFullScrBtn.addClass( this.dom.hiddenClass ); 10196 this.$fullScrBtn.removeClass( this.dom.hiddenClass ); 10197 10198 utils.exitFullscreen(); 10199 this.updateSizes( 'window' ); 10200 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10201 10202 this.isFullScreen = false;
10203 } 10204 10205 }, 10206 10207 onResize : function() { 10208 this.getViewportSizes(); 10209 this.updateSizes( this.isFullScreen ? 'screen' : 'window' ); 10210 $( this.element ).slick( 'refresh' ); 10211 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10212 this.updateCacheElements(); 10213 this.createPagination(); 10214 }, 10215 10216 socialShare : function( e ) { 10217 e.preventDefault(); 10218 var $this = $( e.currentTarget ), 10219 network = $this.data( 'network' ), 10220 id = this.config.id, 10221 url = this.config.url, 10222 title = this.$wrapper.find( '.slick-title' ).text(), 10223 name; 10224 var picture = this.$slides.filter( this.dom.active ).children().first().attr( 'src' ); 10225 switch( network ) { 10226 case 'facebook': 10227 url = 'https://www.facebook.com/sharer/sharer.php?picture=' + picture+'&u=' + url + '#id=' + id; 10228 name = 'Facebook Share'; 10229 break; 10230 case 'twitter': 10231 url = 'http://twitter.com/intent/tweet?text=' + url + '#id=' + id; 10232 name = 'Twitter Share'; 10233 break; 10234 case 'pinterest': 10235 url = 'http://pinterest.com/pin/create/bookmarklet/?media=' + picture + '&url=' + url + '&is_video=false&description=' + title; 10236 // other available link paranmeters: media, description 10237 name = 'Pinterest Share'; 10238 break; 10239 10240 } 10241 10242 window.open( url, name, "height=380 ,width=660, resizable=0, toolbar=0, menubar=0, status=0, location=0, scrollbars=0" ); 10243 } 10244 }; 10245 10246})( jQuery ); 10247(function( $ ) { 10248 'use strict'; 10249 10250 /** 10251 * A fork from original VC function. 10252 * The original one is adding some padding which causes extra padding 10253 * on our templates so we customized the codes. 10254 * 10255 * @since 5.9.8 10256 * @since 6.0.1 Improve logic to handle LTR responsive state. 10257 */ 10258 function MkfullWidthRow() { 10259 var $elements = $('[data-mk-full-width="true"]'); 10260 var direction = $('body.rtl').length ? 'right' : 'left'; 10261 var verticalHeader = $('body.vertical-header-enabled').length ? true : false; 10262 var verticalHeaderWidth = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : 270; 10263 var verticalHeaderRtl = $('body.rtl').length ? -1 : 1; 10264 var verticalHeaderRtlWidth = $('body.rtl.vertical-header-enabled').length ? verticalHeaderWidth : 0; 10265 var verticalHeaderRight = $('body.vertical-header-right').length ? -1 : 1; 10266 var verticalHeaderWidthBoxed = 0; 10267 var boxed = $('body.mk-boxed-enabled').length; 10268 var boxedOffset = ( boxed ) ? ( $(window).width() - $('#theme-page').outerWidth() ) / 2 : 0; 10269 var boxedMaxWidth = ( boxed ) ? $('#theme-page').outerWidth() : 'auto'; 10270 10271 if ( verticalHeader && boxed ) { 10272 verticalHeaderWidthBoxed = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : verticalHeaderRtl * verticalHeaderRight * 135; 10273 } 10274 if ( $('.transparent-header').length > 0 ) { 10275 verticalHeaderWidthBoxed = 0; 10276 } 10277 10278 $.each($elements, function(key, item) { 10279 var $el = $(this); 10280 var css; 10281 $el.addClass("vc_hidden"); 10282 var $el_full = $el.next(".vc_row-full-width"); 10283 if ($el_full.length || ($el_full = $el.parent().next(".vc_row-full-width")), $el_full.length) { 10284 var el_margin_left = parseInt($el.css("margin-left"), 10), 10285 el_margin_right = parseInt($el.css("margin-right"), 10), 10286 offset = 0 - $el_full.offset().left - el_margin_left, 10287 width = $(window).width(); 10288 if (css = { 10289 position: "relative", 10290 "box-sizing": "border-box", 10291 width: $(window).width(), 10292 maxWidth: boxedMaxWidth 10293 }, 10294 css[direction] = offset + boxedOffset + verticalHeaderWidthBoxed + ( verticalHeaderRight * verticalHeaderRtlWidth ), 10295 $el.css(css), !$el.data("mkStretchContent")) { 10296 var padding = -1 * offset; 10297 0 > padding && (padding = 0); 10298 var paddingRight = width - padding - $el_full.width() + el_margin_left + el_margin_right; 10299 padding = padding - paddingRight; 10300 if ( 0 > paddingRight && (paddingRight = 0) ) { 10301 css = {}; 10302 if ( 'right' === direction ) { 10303 css["padding-left"] = padding + "px"; 10304 css["padding-right"] = 0; 10305 } else { 10306 css["padding-right"] = padding + "px"; 10307 css["padding-left"] = 0; 10308 } 10309 10310 $el.css(css) 10311 } 10312 } 10313 $el.attr("data-mk-full-width-init", "true"), $el.removeClass("vc_hidden"), $(document).trigger("vc-full-width-row-single", { 10314 el: $el, 10315 offset: offset, 10316 marginLeft: el_margin_left, 10317 marginRight: el_margin_right, 10318 elFull: $el_full, 10319 width: width 10320 }) 10321 } 10322 }
10322), $(document).trigger("mk-full-width-row", $elements) 10323 } 10324 10325 MkfullWidthRow(); 10326 var debounceResize = null; 10327 $(window).on("resize", function() { 10328 if( debounceResize !== null ) { clearTimeout( debounceResize ); } 10329 debounceResize = setTimeout( MkfullWidthRow, 50 ); 10330 }); 10331 10332})( jQuery ); 10333 10334(function($) { 10335 'use strict'; 10336 10337 MK.component.Grid = function( el ) { 10338 var $container = $(el); 10339 var config = $container.data( 'grid-config' ); 10340 var isSlideshow = $container.closest('[data-mk-component="SwipeSlideshow"]').length; 10341 var miniGridConfig = { 10342 container: el, 10343 item: config.item + ':not(.is-hidden)', 10344 gutter: 0 10345 }; 10346 10347 var init = function init(){ 10348 // Flags for cancelling usage goes first : 10349 // Quit early if we discover that Grid is used inside SwipeSlideshow as it brings bug with crossoverriding positioning 10350 // + grid is not really needed as we have single row all handled by slider. 10351 // It happens only in woocommerce carousel as of hardcoded Grid in loop-start.php 10352 if(isSlideshow) return; 10353 MK.core.loadDependencies([ MK.core.path.plugins + 'minigrid.js' ], create); 10354 }; 10355 10356 // Remove el hidden without adding proper class 10357 var prepareForGrid = function prepareForGrid() { 10358 var $item = $(this); 10359 var isHidden = ($item.css('display') === 'none'); 10360 if(isHidden) $item.addClass('is-hidden'); 10361 else $item.removeClass('is-hidden'); 10362 }; 10363 10364 var create = function create() { 10365 var timer = null; 10366 10367 function draw() { 10368 // Prevent plugin breaking when feeding it with hidden elements 10369 $container.find(config.item).each( prepareForGrid ); 10370 minigrid(miniGridConfig); 10371 } 10372 10373 function redraw() { 10374 if (timer) clearTimeout(timer); 10375 timer = setTimeout(draw, 100); 10376 } 10377 10378 // init 10379 draw(); 10380 // If reinitializing drop existing event handler 10381 $(window).off('resize', redraw); 10382 $(window).on('resize', redraw); 10383 MK.utils.eventManager.subscribe('item-expanded', redraw); 10384 MK.utils.eventManager.subscribe('ajaxLoaded', redraw); 10385 MK.utils.eventManager.subscribe('staticFilter', redraw); 10386 }; 10387 10388 return { 10389 init : init 10390 }; 10391 }; 10392 10393})(jQuery); 10394 10395 10396 10397 10398 10399 10400 10401 10402/** 10403 * ICON FACTORY @ Maki 10404 * 10405 * Javascript part that translates css styles into link to server side manufacturer. 10406 * By passing extra args we generate icons as needed on server and send them back with ajax and attch them to DOM here. 10407 * 10408 * 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. 10409 * 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. 10410 * 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. 10411 * 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. 10412 * 10413 * Prons: 10414 * - automated process where we can mimic old behaviour 10415 * - possible bugs are easy to patch 10416 * - 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) 10417 * - icon generation moved to server side where our main templating is already happening 10418 * - we can easily switch how our Icon should be outputed - inline, img, object, iframe. Whatever our situation requires (img for responsive icons for example) 10419 * 10420 * Cons: 10421 * - possible bugs based on different nature of svgs / fonts. Need to be manually fixed 10422 * - some manual work to straighten things - litle css refactors here and there 10423 * - as the mapping the icons happens in server side, it may cause CPU bottlenecks and should be cashed in DB for repetitve usage. 10424 * 10425 * 10426 * TODO Refactor to config obj as parameter for easier passing it. Also decouple more - especially loops 10427 */ 10428(function ($) { 10429 'use strict'; 10430 10431 // As long as we can manage this manually it is better like so. We avoid delay based on waiting for ajax to finish 10432 // $.get( MK.core.path.theme + '/assets/icons/icon-families.json', createAll); 10433 var families = [ 10434 ['awesome-icons' , 'mk-icon-'], // [family, prefix] 10435 ['icomoon' , 'mk-moon-'], 10436 ['pe-line-icons' , 'mk-li-'], 10437 ['theme-icons' , 'mk-jupiter-icon-'] 10438 ]; 10439 10440 // Our css contains this extends for particular families of fonts. For now we automate the process and extend it here as well 10441 var extend = { 10442 'awesome-icons' : [], 10443 'icomoon' : [], 10444 'pe-line-icons' : [], 10445 'theme-icons' : [] 10446 }; 10447 10448 // Cache holder for quick access to repeating icons. config / svg 10449 var _cache = {}; 10450 var _cacheId = 0;
10451 // Merge configs to call it with single ajax 10452 var _config = []; 10453 // Counter for all families. We merge all our families for single ajax request and countdown when to trigger the download. 10454 var _roundCount = 0; 10455 // Mapper for icons - config / array with nodes 10456 var _iconMap = {}; 10457 10458 10459 // Closure to merge $icons together and to run the download when we counted down icon families to 0 10460 var getIconsSprite = (function() { 10461 var $icons = null; 10462 var iterator = 0; 10463 10464 function run(callback) { 10465 var config = encodeURIComponent(JSON.stringify(_config)); 10466 10467 $.ajax({ 10468 url : MK.core.path.ajaxUrl, 10469 // dataType: 'xml', 10470 method: 'POST', 10471 data: {action : 'mk_get_icon', iterator: iterator++, config: config}, 10472 success: function(sprite) { 10473 callback(sprite, $icons); 10474 _config = []; 10475 _iconMap = {}; 10476 $icons = null; 10477 }, 10478 error: function(err) { 10479 console.log('Icon load problem'); 10480 } 10481 }); 10482 } 10483 10484 return function(callback, $els, count) { 10485 if(!$icons) $icons = $els; 10486 else $icons.add($els); 10487 // console.log(count); 10488 if(!count) run(callback); 10489 }; 10490 }()); 10491 10492 // Wait for DOM manipulations and run where really needed 10493 $(window).on('load', function() { 10494 setTimeout(function() { 10495 createAll(document); 10496 if($('.mk-header').length) createAll('.mk-header'); 10497 if($('.js-flexslider, .mk-flexslider').length) createAll('.js-flexslider, .mk-flexslider'); 10498 if($('.mk-accordion').length) createAll('.mk-accordion'); 10499 }, 1000); 10500 }); 10501 10502 MK.utils.eventManager.subscribe('ajaxLoaded', function() { 10503 // Wait for actuall DOM insertion 10504 setTimeout(createAll, 100, '.js-loop'); 10505 }); 10506 10507 MK.utils.eventManager.subscribe('ajax-preview', function() { 10508 setTimeout(createAll, 100, '.ajax-container'); 10509 }); 10510 10511 MK.utils.eventManager.subscribe('photoAlbum-open', function() { 10512 setTimeout(createAll, 100, '.gallery-share'); 10513 }); 10514 10515 MK.utils.eventManager.subscribe('quickViewOpen', function() { 10516 setTimeout(createAll, 300, '.mk-modal-content'); 10517 }); 10518 10519 // Our main runner that creates all icons in given scope 10520 function createAll(scope) { 10521 // iterate through families 10522 for(var i = 0, l = families.length; i < l; i++) { 10523 var family = families[i][0]; 10524 var prefix = families[i][1]; 10525 var $icons = getIcons(family, prefix, scope); 10526 if($icons.length) { 10527 _roundCount++; 10528 // 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. 10529 // We need it to pass all $icons first so we can merge all families before ajax request. 10530 setTimeout(createIcons, 0, $icons, family, prefix); 10531 } 10532 } 10533 } 10534 10535 // Grab all els in given scope that contains our prefix, anywhere in class attribute. Extend if needed 10536 function getIcons(family, prefix, scope) { 10537 var $scope = $(scope); 10538 var $icons = $scope.find('[class*='+ prefix +']'); 10539 var extraClassNames = extend[family]; 10540 // if nothing to extend just return what we have till now 10541 if(!extraClassNames) return $icons; 10542 // Extend it with our css garbish 10543 extraClassNames.forEach(function(className) { 10544 var $icon = $scope.find(className); 10545 $icons = $icons.add($icon); 10546 }); 10547 // serve all 10548 return $icons; 10549 } 10550 10551 10552 function createIcons($icons, family, prefix, i, unicode) { 10553 var id = i || 0; 10554 var icon = $icons[id]; 10555 10556 // quick check point, if no more icons break recursion 10557 if(!icon) { 10558 _roundCount--; 10559 getIconsSprite(insertIcons, $icons, _roundCount, _config); 10560 return; 10561 } 10562 10563 var css = getComputedStyle( icon, ':before'); 10564 var classAttr = icon.getAttribute('class'); 10565 var name = (classAttr) ? matchClass(classAttr.split(' '), prefix) : false; 10566 var h = getComputedStyle(icon).fontSize; 10567 var config = createConfig(css, name, family, unicode, h); 10568 var cache = JSON.stringify(config); 10569 10570 if(!config) { 10571 // 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) 10572 // As we expect empty response from server, we just skip to next icon 10573 10574 } else if(_cache[cache]) { 10575 // Use cached icon when possible 10576 // 10577 if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)]; 10578 else _iconMap[cache].push($icons.eq(id)); 10579 10580 } else { 10581 if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)]; 10582 else _iconMap[cache].push($icons.eq(id)); 10583 10584 _cache[cache] = _cacheId.toString(); // number as string so we could do [var] key lookup after reversal 10585 config.id = _cacheId; // extend config for server only 10586 _config.push(config); 10587 10588 _cacheId++; // increment after caching 10589 } 10590 10591 createIcons($icons, family, prefix, ++id); 10592 } 10593 10594 function insertIcons(sprite, $icons) { 10595 var $sprite = $(sprite); 10596 var $svgs = $sprite.find('svg'); 10597 var idMap = invert(_cache); 10598 10599 $sprite.each(function() { 10600 var $svg = $(this); 10601 var id = $svg.attr('data-cacheid'); // read as string 10602 var configKey = idMap[id]; 10603 10604 _cache[configKey] = this; 10605 // console.log(id, this) 10606 }); 10607 10608 // console.log('sprite',sprite) 10609 // 10610
10611 Object.keys(_iconMap).forEach(function (cacheKey) { 10612 _iconMap[cacheKey].forEach(function($icons) { 10613 $icons.each(function() { 10614 var $svg = $(_cache[cacheKey]).clone(); 10615 var $icon = $(this); 10616 10617 // console.log($icon[0], _cache[cacheKey]); 10618 10619 function remove() { 10620 // exclude problematic stuff 10621 if($icon.parents('.pricing-features')) return; 10622 $icon.not('.mk-jupiter-icon-xing') 10623 .not('.mk-jupiter-icon-square-xing') 10624 .not('.mk-jupiter-icon-simple-xing') 10625 .find('.mk-svg-icon') 10626 .not('[data-name="mk-moon-zoom-in"]') 10627 .remove(); // and remove else to reapply styles with new loaded svg 10628 } 10629 10630 if($svg.length ) remove(); 10631 10632 if(!$icon.find('svg').length) { 10633 if($icon.parents('.widget ul').length) $icon.prepend($svg); 10634 else $icon.append($svg); 10635 } 10636 }); 10637 }); 10638 }); 10639 10640 // Notify rest of app 10641 MK.utils.eventManager.publish('iconsInsert'); 10642 } 10643 10644 // Prepare configuration for server side. We need to grab icons and manipulate them a little there 10645 function createConfig(css, name, family, unicode, height) { 10646 var hasGradient = checkGradient(css); 10647 var hasDirection = extractGradient('direction', css.background); 10648 10649 var config = { 10650 family: family, 10651 // this is mostly for Extends. Because we've been customizing singular elements and assigning content unicode manually, 10652 // now we don't have any proper anchor for usage with our json map 10653 unicode: (unicode) ? unicode : decodeUnicode(css.content), 10654 name: name, 10655 // fill: css.color, 10656 gradient_type: hasGradient ? extractGradient('type' , css.background) : false, 10657 gradient_start: hasGradient ? extractGradient('start', css.background) : false, 10658 gradient_stop: hasGradient ? extractGradient('stop' , css.background) : false, 10659 gradient_direction: hasDirection ? extractGradient('direction', css.background).replace(' ', '-') : false, 10660 height: height 10661 }; 10662 10663 // If there is no name or unicode the whole config is invalid 10664 if(!config.name && !config.unicode) return false; 10665 else return config; 10666 } 10667 10668 // Extract class name that represents the icon that we try to generate
10669 function matchClass(classes, prefix) { 10670 // var missing = ''; 10671 for(var i = 0, l = classes.length; i < l; i++) { 10672 if(classes[i].indexOf(prefix) !== -1) return classes[i]; // return first matched class name 10673 // else missing += ' .' + classes[i]; // collect not matching classes 10674 } 10675 // if we didn't returned anything within loop we output notification here. Keep it for testing only 10676 // console.log('Possibility of missing icons for element with classes:' + missing); 10677 } 10678 10679 // Check if background conatains gradient declaration and return bg string if so or false 10680 function checkGradient(css) { 10681 var bg = css.background; 10682 if(bg.indexOf('radial') !== -1 || bg.indexOf('linear') !== -1) return bg; 10683 else return false; 10684 } 10685 10686 // Extract background attribiutes from bg string. 10687 // Multipurpose function which returns part we ask for 10688 function extractGradient(attr, grad) { 10689 // quit if gradient is falsy 10690 // console.log(grad); 10691 if(!grad) return false; 10692 10693 var isRadial = grad.indexOf('radial') !== -1; 10694 var isLinear = grad.indexOf('linear') !== -1; 10695 var hasDirection = grad.indexOf('(to') !== -1; 10696 var f, t; // from, to 10697 10698 if(attr === 'type') { 10699 if(isRadial) return 'radial'; 10700 if(isLinear) return 'linear'; 10701 10702 } else if(attr === 'start') { 10703 f = getStrPosition(grad, 'rgb(', 1); 10704 t = getStrPosition(grad, '0%' , 1); 10705 10706 } else if(attr === 'stop') { 10707 f = getStrPosition(grad, 'rgb(', 2); 10708 t = getStrPosition(grad, '100%', 1); 10709 10710 } else if(attr === 'direction') { 10711 if(!hasDirection) return false; 10712 f = getStrPosition(grad, '(to', 1) + 4; 10713 t = getStrPosition(grad, ', rgb(', 1); 10714 10715 } else { 10716 return false; 10717 } 10718 10719 return grad.slice(f, t); 10720 } 10721 10722 // Helper for getting indexOf but with lookup for instance of the string 10723 // str - string to search 10724 // m - what we're looking for 10725 // i - instance, starting at 1 10726 function getStrPosition(str, m, i) { 10727 return str.split(m, i).join(m).length; 10728 } 10729 10730 // JS outputs unicode results rather than code representation. This helper function does the job 10731 function decodeUnicode(content) { 10732 // escape() kills \ escape signature and outputs it as %u 10733 // str replace to drop special chars 10734 // and we bring it all to lowercase to match filenames we keep on server 10735 if(content && content !== 'none') return escape(content).replace(/%22/g, '').replace('%u', '').toLowerCase(); 10736 else return false; // just in case we haven't provided content to work with 10737 } 10738 10739 function invert(obj) { 10740 var new_obj = {}; 10741 for (var prop in obj) { 10742 if(obj.hasOwnProperty(prop)) { 10743 new_obj[obj[prop]] = prop; 10744 } 10745 } 10746 return new_obj; 10747 } 10748 10749}(jQuery)); 10750/*! 10751 * imagesLoaded PACKAGED v4.1.1 10752 * JavaScript is all like "You images are done yet or what?" 10753 * MIT License 10754 */ 10755 10756!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
10756h(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}); 10757 10758(function($, window){ 10759 'use strict'; 10760 10761 var scrollY = MK.val.scroll; 10762 var dynamicHeight = MK.val.dynamicHeight; 10763 10764 var $window = $(window); 10765 var $containers = $('.js-loop'); 10766 10767 $containers.each( pagination ); 10768 10769 $window.on( 'vc_reload', function() { 10770 $('.js-loop').each( pagination ); 10771 } ); 10772 10773 function pagination() { 10774 var unique = Date.now(); 10775 var $container = $(this); 10776 var $superContainer = $container.parent(); // should contain clearing so it stretches with floating children 10777 var $loadBtn = $container.siblings('.js-loadmore-holder').find('.js-loadmore-button'); 10778 var $loadScroll = $('.js-load-more-scroll'); 10779 var style = $container.data('pagination-style'); 10780 var maxPages = $container.data('max-pages'); 10781 var id = '#' + ($container.attr('id')); 10782 var ajaxLoader = new MK.utils.ajaxLoader(id); 10783 var isLoadBtn = (style === 2); 10784 var isInfiniteScroll = (style === 3); // add flag for last container 10785 var scrollCheckPoint = null; 10786 var isHandlerBinded = false;
10787 10788 ajaxLoader.init(); 10789 10790 init(); 10791 10792 function init() { 10793 MK.utils.eventManager.subscribe('ajaxLoaded', onLoad); 10794 bindHandlers(); 10795 if( isInfiniteScroll ) scrollCheckPoint = spyScrollCheckPoint(); 10796 10797 $window.on( 'vc_reload', function() { 10798 $window.off('scroll', handleScroll); 10799 } ); 10800 } 10801 10802 function bindHandlers() { 10803 if( isLoadBtn ) $loadBtn.on('click', handleClick); 10804 if( isInfiniteScroll ) $window.on('scroll', handleScroll); 10805 isHandlerBinded = true; 10806 } 10807 10808 function unbindHandlers() { 10809 if( isLoadBtn ) $loadBtn.off('click', handleClick); 10810 if( isInfiniteScroll ) $window.off('scroll', handleScroll); 10811 isHandlerBinded = false; 10812 } 10813 10814 function handleClick(e) { 10815 e.preventDefault(); 10816 if(!ajaxLoader.isLoading) loadMore(); 10817 } 10818 10819 function handleScroll() { 10820 if((scrollY() > scrollCheckPoint()) && !ajaxLoader.isLoading) loadMore(); 10821 } 10822 10823 function loadMore() { 10824 loadingIndicatorStart(); 10825 var page = ajaxLoader.getData('paged'); 10826 ajaxLoader.setData({paged: ++page}); 10827 ajaxLoader.load(unique); 10828 } 10829 10830 function onLoad(e, response) { 10831 if( typeof response !== 'undefined' && response.id === id) { 10832 // Checking found posts helps to fix all pagination styles 10833 if( ajaxLoader.getData('found_posts') <= 0 && ajaxLoader.getData('paged') >= ajaxLoader.getData('maxPages')) loadingIndicatorHide(); 10834 else loadingIndicatorShow(); 10835 if(response.unique === unique) $container.append(response.content); 10836 loadingIndicatorStop(); 10837 } 10838 } 10839 10840 function loadingIndicatorStart() { 10841 if(isLoadBtn) $loadBtn.addClass('is-active'); 10842 else if(isInfiniteScroll) MK.ui.loader.add('.js-load-more-scroll'); 10843 10844 } 10845 10846 function loadingIndicatorStop() { 10847 if(isLoadBtn) $loadBtn.removeClass('is-active'); 10848 else if(isInfiniteScroll) MK.ui.loader.remove('.js-load-more-scroll'); 10849 } 10850 10851 function loadingIndicatorShow() { 10852 if(isHandlerBinded) return; 10853 if(isLoadBtn) $loadBtn.show(); 10854 else if(isInfiniteScroll) $loadScroll.show(); 10855 bindHandlers(); 10856 } 10857 10858 function loadingIndicatorHide() { 10859 if(!isHandlerBinded) return; 10860 if(isLoadBtn) $loadBtn.hide(); 10861 else if(isInfiniteScroll) $loadScroll.hide(); 10862 unbindHandlers(); 10863 } 10864 10865 10866 function spyScrollCheckPoint() { 10867 var containerO = 0; 10868 var containerH = dynamicHeight( $superContainer ); 10869 var winH = dynamicHeight( window ); 10870 10871 var setVals = function() { 10872 containerO = $superContainer.offset().top; 10873 }; 10874 10875 setVals(); 10876 $window.on('resize', function() { requestAnimationFrame(setVals); }); 10877 10878 return function() { 10879 return (containerH() + containerO) - (winH() * 2); 10880 }; 10881 } 10882 } 10883 10884})(jQuery, window); 10885(function($) { 10886 'use strict'; 10887 10888 // Check if it's inside hidden parent 10889 // Cannot be position: fixed 10890 function isHidden(el) { 10891 return (el.offsetParent === null); 10892 } 10893 10894 MK.component.Masonry = function(el) { 10895 var $window = $(window); 10896 var $container = $(el); 10897 var config = $container.data( 'masonry-config' ); 10898 var $masonryItems = $container.find(config.item); 10899 var cols = config.cols || 8; 10900 var $filterItems = null; // assign only when apply filter 10901 var wall = null; 10902 10903 var init = function init() { 10904 MK.core.loadDependencies([ MK.core.path.plugins + 'freewall.js' ], onDepLoad); 10905 }; 10906 10907 var onDepLoad = function onDepLoad() { 10908 masonry(); 10909 10910 // Events 10911 $window.on('resize', onResize); 10912 MK.utils.eventManager.subscribe('ajaxLoaded', onPostAddition); 10913 MK.utils.eventManager.subscribe('staticFilter', resize); 10914 }; 10915 10916 var masonry = function masonry() { 10917 // Quit for hidden elements for now. 10918 if(isHidden(el)) return; 10919 10920 var newCols; 10921 if(window.matchMedia( '(max-width:600px)' ).matches) newCols = 2; 10922 else if(window.matchMedia( '(max-width:850px)' ).matches) newCols = 4; 10923 else newCols = cols; 10924 10925 var colW = $container.width() / newCols; 10926 10927 wall = new Freewall( config.container ); 10928 10929 // We need to pass settings to a plugin via reset method. Strange but works fine. 10930 wall.reset({
10931 selector: config.item + ':not(.is-hidden)', 10932 gutterX: 0, // set default gutter to 0 and again - apply margins to item holders in css 10933 gutterY: 0, 10934 cellW: colW, 10935 cellH: colW 10936 }); 10937 10938 wall.fillHoles(); 10939 wall.fitWidth(); 10940 10941 $masonryItems.each(function() { 10942 $(this).data('loaded', true); 10943 }); 10944 }; 10945 10946 10947 // Clear attributes after the plugin. It's API method dosn't handle it properly 10948 var destroyContainer = function destroyContainer() { 10949 $container.removeAttr('style') 10950 .removeData('wall-height') 10951 .removeData('wall-width') 10952 .removeData('min-width') 10953 .removeData('total-col') 10954 .removeData('total-row') 10955 .removeAttr('data-wall-height') 10956 .removeAttr('data-wall-width') 10957 .removeAttr('data-min-width') 10958 .removeAttr('data-total-col') 10959 .removeAttr('data-total-row'); 10960 }; 10961 10962 var destroyItem = function destroyItem() { 10963 var $item = $(this); 10964 $item.removeAttr('style') 10965 .removeData('delay') 10966 .removeData('height') 10967 .removeData('width') 10968 .removeData('state') 10969 .removeAttr('data-delay') 10970 .removeAttr('data-height') 10971 .removeAttr('data-width') 10972 .removeAttr('data-state'); 10973 }; 10974 10975 var destroyAll = function destroyAll() { 10976 if( !wall ) return; 10977 wall.destroy(); // API destroy 10978 destroyContainer(); 10979 $masonryItems.each( destroyItem ); // run our deeper destroy 10980 }; 10981 10982 var onResize = function onResize() { 10983 requestAnimationFrame(resize); 10984 }; 10985 10986 var refresh = function refresh() { 10987 if( !wall ) return; 10988 setTimeout(wall.fitWidth.bind(wall), 5); 10989 }; 10990 10991 var resize = function resize() { 10992 destroyAll(); 10993 masonry(); 10994 }; 10995 10996 var onPostAddition = function onPostAddition() { 10997 $masonryItems = $container.find(config.item); 10998 10999 $masonryItems.each(function() { 11000 var $item = $(this), 11001 isLoaded = $item.data('loaded'); 11002 11003 if(!isLoaded) $item.css('visibility', 'hidden'); 11004 }); 11005 11006 11007 $container.mk_imagesLoaded().then(function() { 11008 destroyAll(); 11009 masonry(); 11010 }); 11011 }; 11012 11013 return { 11014 init : init 11015 }; 11016 }; 11017 11018}(jQuery)); 11019(function($) { 11020 'use strict'; 11021 11022 MK.component.Pagination = function(el) { 11023 this.el = el; 11024 }; 11025 11026 MK.component.Pagination.prototype = { 11027 init: function init() { 11028 this.cacheElements(); 11029 this.bindEvents(); 11030 this.onInitLoad(); 11031 }, 11032 11033 cacheElements: function cacheElements() { 11034 this.lastId = 1; 11035 this.unique = Date.now(); 11036 this.$pagination = $(this.el); 11037 this.$container = this.$pagination.prev('.js-loop'); 11038 this.$pageLinks = this.$pagination.find('.js-pagination-page'); 11039 this.$nextLink = this.$pagination.find('.js-pagination-next'); 11040 this.$prevLink = this.$pagination.find('.js-pagination-prev'); 11041 this.$current = this.$pagination.find('.js-current-page'); 11042 this.$maxPages = this.$pagination.find('.pagination-max-pages'); // TODO change in DOM and here to js class 11043 this.containerId = '#' + this.$container.attr('id'); 11044 this.pagePathname = window.location.pathname; 11045 this.pageSearch = window.location.search; 11046 this.popState = false; 11047 this.ajaxLoader = new MK.utils.ajaxLoader('#' + this.$container.attr('id')); 11048 this.ajaxLoader.init(); 11049 }, 11050 11051 bindEvents: function bindEvents() { 11052 this.$pageLinks.on('click', this.pageClick.bind(this)); 11053 this.$nextLink.on('click', this.nextClick.bind(this)); 11054 this.$prevLink.on('click', this.prevClick.bind(this)); 11055 MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this)); 11056 }, 11057 11058 pageClick: function pageClick(e) { 11059 e.preventDefault(); 11060 var $this = $(e.currentTarget); 11061 var id = parseFloat($this.attr('data-page-id')); 11062 11063 if(id > this.ajaxLoader.getData('maxPages') || id < 1) return; 11064 this.load(id, $this); 11065 this.updatePagedNumUrl( id ); 11066 }, 11067 11068 nextClick: function nextClick(e) { 11069 e.preventDefault(); 11070 if(this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')) return; 11071 this.load(++this.lastId, $(e.currentTarget)); 11072 this.updatePagedNumUrl( this.lastId ); 11073 }, 11074 11075 prevClick: function prevClick(e) { 11076 e.preventDefault(); 11077 if(this.ajaxLoader.getData('paged') === 1) return; 11078 this.load(--this.lastId, $(e.currentTarget)); 11079 this.updatePagedNumUrl( this.lastId ); 11080 }, 11081 11082 load: function load(id, $el) { 11083 this.lastId = id; 11084 this.ajaxLoader.setData({paged: id}); 11085 this.ajaxLoader.load(this.unique); 11086 this.removeIndicator(); 11087 MK.ui.loader.add($el); 11088 }, 11089 11090 onLoad: function success(e, response) { 11091 if( typeof response !== 'undefined' && response.id === this.containerId) { 11092 this.updatePagination(); 11093 this.lastId = this.ajaxLoader.getData('paged'); 11094 11095 if(response.unique === this.unique) { 11096 this.removeIndicator(); 11097 this.scrollPage(); 11098 this.$container.html(response.content); 11099 } 11100 } 11101 }, 11102 11103 updatePagination: function updatePagination() { 11104 var self = this; 11105 11106 // Hide / show arrows 11107 var isFirst = (this.ajaxLoader.getData('paged') === 1); 11108 var isLast = (this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')); 11109 11110 if(isFirst) this.$prevLink.addClass('is-vis-hidden'); 11111 else this.$prevLink.removeClass('is-vis-hidden'); 11112 11113 if(isLast) this.$nextLink.addClass('is-vis-hidden'); 11114 else this.$nextLink.removeClass('is-vis-hidden'); 11115 11116 // X of Y 11117 this.$current.html(this.ajaxLoader.getData('paged')); 11118 this.$maxPages.html(this.ajaxLoader.getData('maxPages')); 11119 11120 // Move overfloating items 11121 var displayItems = 10; 11122 var centerAt = displayItems / 2; 11123 11124 if(this.ajaxLoader.getData('maxPages') > displayItems) { 11125 this.$pageLinks.each(function(i) { 11126 11127 var id = self.lastId - centerAt; 11128 id = Math.max(id, 1); 11129 id = Math.min(id, self.ajaxLoader.getData('maxPages') - displayItems + 1); 11130 id = id + i; 11131 11132 $(this).html( id ).attr('data-page-id', id).show(); 11133 11134 if(i === 0 && id > 1) $(this).html('...'); 11135 if(i === displayItems - 1 && id < self.ajaxLoader.getData('maxPages')) $(this).html('...'); 11136 }); 11137 } else { 11138 this.$pageLinks.each(function(i) { 11139 var $link = $(this); 11140 var id = i + 1; 11141 11142 $link.html(id).attr('data-page-id', id); 11143 11144 if( self.ajaxLoader.getData('maxPages') === 1) { 11145 self.$pageLinks.hide(); 11146 } else { 11147 if(i > self.ajaxLoader.getData('maxPages') - 1) $link.hide(); 11148 else $link.show(); 11149 } 11150 11151 }); 11152 } 11153 11154 // Highlight current only 11155 this.$pageLinks.filter('[data-page-id="' + this.ajaxLoader.getData('paged') + '"]' ).addClass('current-page') 11156 .siblings().removeClass('current-page'); 11157 11158 }, 11159 11160 scrollPage: function scrollPage() { 11161 var containerOffset = this.$container.offset().top; 11162 var offset = containerOffset - MK.val.offsetHeaderHeight( containerOffset ) - 20; 11163 MK.utils.scrollTo( offset ); 11164 }, 11165 11166 removeIndicator: function removeIndicator() { 11167 MK.ui.loader.remove('.js-pagination-page, .js-pagination-next, .js-pagination-prev'); 11168 }, 11169 11170 /** 11171 * Set some actions when archive/category page is loaded. Actions list: 11172 * - Select the correct paged ID on pagination list. 11173 * - Set current paged ID on the label. 11174 * - Add event listener onpopstate for handling prev/next button of Browser URL. 11175 * - Set info for updatePagedNumUrl() about request comes from popstate. 11176 * 11177 * @since 5.9.8 11178 */ 11179 onInitLoad: function onInitLoad() { 11180 var initPagedID = this.$pagination.data( 'init-pagination' ); 11181 if ( initPagedID && initPagedID > 1 ) { 11182 this.$current.html( initPagedID ); 11183 this.$pageLinks.filter( '[data-page-id="' + initPagedID + '"]' ).addClass( 'current-page' ).siblings().removeClass( 'current-page' ); 11184 } 11185 11186 // Run popstate only if it's supported by the browser. 11187 if ( 'onpopstate' in window ) { 11188 var thisPop = this; 11189 window.onpopstate = function( event ) { 11190 var id = 1; 11191 11192 // At start, state is always null. So, we should check it before processing. 11193 if ( typeof event.state === 'object' && event.state ) { 11194 var state = event.state; 11195 11196 // Set paged ID for updating page. 11197 if ( state.hasOwnProperty( 'MkPagination' ) ) { 11198 var currentState = state.MkPagination; 11199 if ( currentState.hasOwnProperty( 'paged' ) ) { 11200 id = parseFloat( currentState.paged ); 11201 } 11202 } 11203 } else { 11204 id = parseFloat( thisPop.getURLPagedID() ); 11205 } 11206 11207 // Tell updatePagedNumUrl() if request come from popstate. 11208 thisPop.popState = true; 11209 thisPop.$pageLinks.filter( '[data-page-id="' + id + '"]' ).trigger( 'click' ); 11210 } 11211 } 11212 }, 11213 11214 /** 11215 * Update current pagination browser URL by adding/changing paged number. Only run if 11216 * the browser support pushState and the request not coming from popstate. 11217 * 11218 * WordPress has some ways to set paged number: 11219 * 1. page/[number], paged=[number] will be directed here. 11220 * 2. page=[number] 11221 * So, we should check which one the request is used here. 11222 * 11223 * @since 5.9.8 11224 */ 11225 updatePagedNumUrl: function updatePagedNumUrl( id ) { 11226 // Check pushState browser support and ignore if request come from popstate. 11227 if ( 'history' in window && 'pushState' in history && id && ! this.popState ) { 11228 var fullPage = this.pagePathname + this.pageSearch; 11229 var isQueryPage = false;
11230 11231 // Style 1 - /page/[number], as default value. 11232 var newPage = 'page/' + id + '/'; 11233 var expPage = /page\/\d+\/?/; 11234 var result = this.pagePathname.match( /\/page\/\d+/ ); 11235 var isPagedExist = ( result ) ? true : false; 11236 11237 // Style 2 - ?page=[number], only run if /page/ is not exist and URL query var exist. 11238 if ( ! isPagedExist && this.pageSearch ) { 11239 isQueryPage = this.pageSearch.match( /page\=\d+/ ); 11240 if ( isQueryPage ) { 11241 newPage = 'page=' + id; 11242 expPage = /page\=\d+/; 11243 } 11244 } 11245 11246 // If page number is 1, remove paged number from URL. 11247 if ( id === 1 ) { 11248 newPage = ''; 11249 if ( isQueryPage ) { 11250 expPage = ( this.pageSearch.match( /\&+/ ) ) ? /page\=\d+\&?/ : /\?page\=\d+\&?/; 11251 } 11252 } 11253 11254 // Set new pathname. Do replacement only if the new pathname contains paged number. 11255 var newURL = this.pagePathname + newPage + this.pageSearch; 11256 if ( fullPage.match( expPage ) ) { 11257 newURL = fullPage.replace( expPage, newPage ); 11258 } 11259 11260 // Set history state and return popstate back to fal
11260se. 11261 var historyState = { 11262 MkPagination: { 11263 url: newURL, 11264 paged: id 11265 } 11266 } 11267 this.popState = false; 11268 11269 // Push new pathname to display/hide the paged number. 11270 window.history.pushState( historyState, null, newURL ); 11271 } 11272 this.popState = false; 11273 }, 11274 11275 /** 11276 * Get current URL page ID. Notes: 11277 * 1. page/[number], paged=[number] will be directed here. 11278 * 2. page=[number] 11279 * 11280 * @return {integer} Current paged ID. Default 1. 11281 */ 11282 getURLPagedID: function getURLPagedID() { 11283 var pathname = window.location.pathname; 11284 var search = window.location.search; 11285 var pagedId = 1; 11286 var result = ''; 11287 var isPagedExist = false; 11288 11289 // Search based on style 1. 11290 result = pathname.match( /\/page\/(\d+)/ ); 11291 if ( result ) { 11292 isPagedExist = true; 11293 pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1; 11294 } 11295 11296 // Search based on style 2. 11297 if ( ! isPagedExist && search ) { 11298 result = search.match( /page\=(\d+)/ ); 11299 if ( result ) { 11300 isPagedExist = true; 11301 pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1; 11302 } 11303 } 11304 11305 return pagedId; 11306 } 11307 }; 11308 11309}(jQuery)); 11310(function( $ ) { 11311 'use strict'; 11312 11313 var val = MK.val, 11314 utils = MK.utils; 11315 11316 MK.component.Parallax = function( el ) { 11317 var self = this, 11318 $this = $( el ), 11319 obj = $this[0], 11320 $window = $( window ), 11321 container = document.getElementById( 'mk-theme-container' ), 11322 config = $this.data( 'parallax-config' ), 11323 $holder = $( config.holder ), 11324 headerHeight = null, 11325 offset = null, 11326 elHeight = null, 11327 ticking = false, 11328 isMobile = null; 11329 11330 11331 var clientRect = null; 11332 11333 var update = function() { 11334 // Clear styles to check for natural styles 11335 // then apply position and size 11336 obj.style.transform = null; 11337 obj.style.top = null; 11338 obj.style.bottom = null; 11339 11340 isMobile = MK.utils.isMobile(); 11341 11342 if( isMobile ) { 11343 $this.css( 'height', '' ); 11344 return; 11345 } 11346 11347 clientRect = $this[ 0 ].getBoundingClientRect(); 11348 offset = clientRect.top; 11349 elHeight = clientRect.height; 11350 headerHeight = val.offsetHeaderHeight( offset ); 11351 offset = offset - headerHeight + val.scroll(); 11352 11353 setPosition(); 11354 setSize( ); 11355 }; 11356 11357 11358 var h = 0, 11359 winH = 0, 11360 proportion = 0, 11361 height = 0; 11362 11363 // Position and background attachement should me moved to CSS but we repair it high specificity here as styles are not reliable currently 11364 var setSize = function() { 11365 $this.css( 'height', '' ); 11366 winH = $window.height() - headerHeight; 11367 h = obj.getBoundingClientRect().height; 11368 11369 if( config.speed <= 1 && config.speed > 0 ) { 11370 if( offset === 0 ) { 11371 $this.css({ 11372 backgroundAttachment: 'scroll', 11373 'will-change': 'transform' 11374 }); 11375 } else { 11376 $this.css({ 11377 height : h + ( (winH - h) * config.speed ), 11378 backgroundAttachment: 'scroll', 11379 'will-change': 'transform' 11380 }); 11381 } 11382 11383 } else if ( config.speed > 1 && h <= winH ) { 11384 $this.css({ 11385 // good for full heights - 2 because it's viewable by 2 screen heights 11386 height: ( winH + ( ( winH * config.speed ) - winH ) * 2 ), 11387 top: -( ( winH * config.speed ) - winH ), 11388 backgroundAttachment: 'scroll', 11389 'will-change': 'transform' 11390 }); 11391 11392 } else if ( config.speed > 1 && h > winH ) { 11393 proportion = h / winH; 11394 height = ( winH + ( ( winH * config.speed ) - winH ) * (1 + proportion) ); 11395 11396 $this.css({ 11397 height: height, 11398 top: -( height - (winH * config.speed) ), 11399 backgroundAttachment: 'scroll', 11400 'will-change': 'transform' 11401 }); 11402 11403 } else if ( config.speed < 0 && h >= winH ) { 11404 height = h * (1 - config.speed); 11405 $this.css({ 11406 height: height + (height - h), 11407 top: h - height, 11408 backgroundAttachment: 'scroll', 11409 'will-change': 'transform' 11410 }); 11411 11412 } else if ( config.speed < 0 && h < winH ) { 11413 // candidate to change 11414 var display = (winH + h) / winH; 11415 height = h * -config.speed * display; 11416 $this.css({ 11417 height: h + (height * 2), 11418 top: -height, 11419 backgroundAttachment: 'scroll', 11420 'will-change': 'transform' 11421 }); 11422 } 11423 }; 11424 11425 11426 var currentPoint = null, 11427 progressVal = null, 11428 startPoint = null, 11429 endPoint = null, 11430 $opacityLayer = config.opacity ? $this.find( config.opacity ) : null, 11431 scrollY = null; 11432 11433 var setPosition = function() { 11434 startPoint = offset - winH; 11435 endPoint = offset + elHeight + winH - headerHeight; 11436 scrollY = val.scroll(); 11437 11438 if( scrollY < startPoint || scrollY > endPoint ) { 11439 ticking = false;
11440 return; 11441 } 11442 11443 currentPoint = (( -offset + scrollY ) * config.speed); 11444 11445 $this.css({ 11446 '-webkit-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11447 '-moz-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11448 '-ms-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11449 '-o-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11450 'transform': 'translateY(' + currentPoint + 'px) translateZ(0)' 11451 }); 11452 11453 ticking = false; 11454 }; 11455 11456 11457 var requestTick = function() { 11458 if( !ticking && !isMobile ) { 11459 ticking = true; 11460 window.requestAnimationFrame( setPosition ); 11461 } 11462 }; 11463 11464 11465 var init = function() { 11466 // Disable scroll effects when smooth scroll is disabled 11467 if( !MK.utils.isSmoothScroll ) { return; } 11468 11469 update(); 11470 setTimeout(update, 100); 11471 $window.on( 'load', update ); 11472 $window.on( 'resize', update ); 11473 window.addResizeListener( container, update ); 11474 11475 $window.on( 'scroll', requestTick ); 11476 }; 11477 11478 11479 return { 11480 init : init 11481 }; 11482 }; 11483 11484})( jQuery ); 11485(function($) { 11486 'use strict'; 11487 11488 MK.component.Preloader = function(el) { 11489 this.el = el; 11490 }; 11491 11492 MK.component.Preloader.prototype = { 11493 init: function init() { 11494 this.cacheElements(); 11495 this.bindEvents(); 11496 }, 11497 11498 cacheElements: function cacheElements() { 11499 this.$preloader = $(this.el); 11500 }, 11501 11502 bindEvents: function bindEvents() { 11503 this.onLoad(); // all components inited on page load 11504 }, 11505 11506 onLoad: function onLoad() { 11507 setTimeout(this.hidePreloader.bind(this), 300); 11508 }, 11509 11510 hidePreloader: function hidePreloader() { 11511 this.$preloader.hide(); 11512 } 11513 }; 11514 11515}(jQuery)); 11516 11517(function($) { 11518 'use strict'; 11519 11520 // Image added for proportional scaling 11521 MK.ui.loader = { 11522 tpl : function() { 11523 return '<div class="mk-loading-indicator">' + 11524 '<div class="mk-loading-indicator__inner">' + 11525 '<div class="mk-loading-indicator__icon"></div>' + 11526 '<img style="height:100%; width:auto;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">' + 11527 '</div>' + 11528 '</div>'; 11529 }, 11530 11531 add : function(item) { 11532 $(item).append(this.tpl); 11533 }, 11534 11535 remove : function(item) { 11536 if(item) $(item).find('.mk-loading-indicator').remove(); 11537 else $('.mk-loading-indicator').remove(); 11538 } 11539 }; 11540 11541}(jQuery)); 11542(function( $ ) { 11543 // IE / Edge fix for fixed positioned elements 11544 // MS clip path doesnt redraw properly so we expirience similar bug like with background attachement fixed on Chrome 11545 if (MK.utils.browser.name === 'Edge' || MK.utils.browser.name === 'IE') { 11546 var val = 1; 11547 var $edgeClipper = $('.mk-slider-slide'); // edge slider 11548 var $sectionClipper = $('.clipper-true'); // edge slider 11549 var $bgLayer = $('.background-layer'); // page section 11550 11551 var onScroll = function onScroll() { 11552 val *= -1; 11553 if( $edgeClipper.length ) $edgeClipper.each( redraw ); 11554 if( $sectionClipper.length ) $sectionClipper.each( redraw ); 11555 if( $bgLayer.length ) $bgLayer.each( redraw ); 11556 }; 11557 11558 var redraw = function redraw() { 11559 $(this).css('margin-top', val / 100); 11560 }; 11561 11562 $(window).on("scroll", function () { 11563 window.requestAnimationFrame(onScroll); 11564 }); 11565 } 11566}(jQuery)); 11567MK.component.ResponsiveImageSetter = (function ($) { 11568 11569 'use strict'; 11570 11571 var module = {}; 11572 11573 11574 /*---------------------------------------------------------------------------------*/ 11575 /* Private Variables 11576 /*---------------------------------------------------------------------------------*/ 11577 11578 var viewportClass = getViewportClass(); 11579 var isRetina = window.devicePixelRatio >= 2; 11580 11581 11582 /*---------------------------------------------------------------------------------*/ 11583 /* Private Methods 11584 /*---------------------------------------------------------------------------------*/ 11585 11586 function run($imgs) { 11587 $imgs.filter( function() { 11588 return !this.hasAttribute("mk-img-src-setted"); 11589 }).each(setSrcAttr); 11590 } 11591 11592 function setSrcAttr() { 11593 var $img = $(this); 11594 var set = $img.data('mk-image-src-set'); 11595 // Set src attribute to img link suitable for our logic. It will load the image. 11596 if(set['responsive'] === 'false' && isRetina && set['2x']) $img.attr('src', set['2x']); 11597 else if(set['responsive'] === 'false') $img.attr('src', set.default); 11598 else if(viewportClass === 1 && isRetina && set['2x']) $img.attr('src', set['2x']); // default x2 for retina 11599 else if(viewportClass === 0 && set.mobile) $img.attr('src', set.mobile); 11600 else $img.attr('src', set.default); 11601 } 11602 11603 function getViewportClass() { 11604 if(window.matchMedia('(max-width: 736px)').matches) return 0; 11605 else return 1; 11606 } 11607 11608 function handleResize($imgs) { 11609 if(!$imgs.length) return;
11609 // Do not run if empty collection 11610 var currentViewportClass = getViewportClass(); 11611 // We don't need to reload bigger images when screen size is decreasing as browser already performs resize operation. 11612 // Run update on for increasing screen size 11613 if( currentViewportClass > viewportClass) { 11614 viewportClass = currentViewportClass; // update for further reference 11615 run($imgs); 11616 } 11617 } 11618 11619 11620 /*---------------------------------------------------------------------------------*/ 11621 /* Public Methods 11622 /*---------------------------------------------------------------------------------*/ 11623 11624 module.init = function ($imgs) { 11625 11626 // Do not run if empty collection 11627 if(!$imgs.length) return; 11628 11629 // Run and bind to events 11630 run($imgs); 11631 $imgs.attr('mk-img-src-setted', ''); 11632 11633 }; 11634 11635 module.onResize = function ($imgs) { 11636 11637 $(window).on( 'resize', MK.utils.throttle( 500, function() { 11638 handleResize($imgs); 11639 })); 11640 11641 11642 }; 11643 11644 11645 module.handleAjax = function () { 11646 setTimeout(function ajaxDelayedCallback() { // give it a chance to insert content first 11647 var $newImgs = $('img[data-mk-image-src-set]').filter( function() { 11648 return !this.hasAttribute("mk-lazyload"); 11649 }); 11650 if(!$newImgs.length) return; 11651 run($newImgs); 11652 }, 100); 11653 } 11654 11655 11656 return module; 11657 11658}(jQuery)); 11659 11660 11661jQuery(function($) { 11662 11663 var init = function init() { 11664 // Get All Responsive Images 11665 $allImages = $('img[data-mk-image-src-set]').filter(function(index) { 11666 var isNotPortfolioImage = !$(this).hasClass('portfolio-image'), 11667 isNotBlogImage = $(this).closest('.mk-blog-container').length == 0, 11668 isNotSwiperImage = !$(this).hasClass('swiper-slide-image'), 11669 isNotGalleryImage = !$(this).hasClass('mk-gallery-image'); 11670 return isNotPortfolioImage && isNotBlogImage && isNotSwiperImage && isNotGalleryImage; 11671 });; 11672 11673 // Handle the resize 11674 MK.component.ResponsiveImageSetter.onResize($allImages); 11675 11676 MK.component.ResponsiveImageSetter.init($allImages); 11677 11678 MK.utils.eventManager.subscribe('ajaxLoaded', MK.component.ResponsiveImageSetter.handleAjax ); // ajax loops 11679 MK.utils.eventManager.subscribe('ajax-preview', MK.component.ResponsiveImageSetter.handleAjax ); // ajax portfolio 11680 MK.utils.eventManager.subscribe('quickViewOpen', MK.component.ResponsiveImageSetter.handleAjax ); 11681 } 11682 init(); 11683 $(window).on('vc_reload', init); 11684 11685}); 11686 11687 11688 11689(function( $ ) { 11690 'use strict'; 11691 11692 var utils = MK.utils; 11693 var val = MK.val; 11694 11695 /** 11696 * Keep track of top Level sections so we can easly skip to next one. 11697 * We must be explicit about DOM level to nested sections. 11698 * 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). 11699 * We keep track for the same sections in Footer for mutating window location with '!loading' to prevent native anchor behaviour. 11700 */ 11701 var $topLevelSections = $('#theme-page > .vc_row, #theme-page > .mk-main-wrapper-holder, #theme-page > .mk-page-section'); 11702 11703 $( document ).on( 'click', '.mk-skip-to-next', function() { 11704 var $this = $( this ), 11705 /** 11706 * Static height of button + the space to the bottom of the container. 11707 * 11708 * @TODO Possible to calculate dynamically. 11709 */ 11710 btnHeight = $this.hasClass( 'edge-skip-slider' ) ? 150 : 76, 11711 offset = $this.offset().top + btnHeight, 11712 nextOffset = utils.nextHigherVal( utils.offsets( $topLevelSections ), [offset] ); 11713 11714 utils.scrollTo( nextOffset - val.offsetHeaderHeight( nextOffset ) ); 11715 }); 11716 11717})( jQuery ); 11718 11719(function($) { 11720 'use strict'; 11721 11722 // 11723 // Constructor 11724 // 11725 // ///////////////////////////////////////////////////////// 11726 11727 MK.ui.Slider = function( container, config ) { 11728 11729 var defaults = { 11730 slide : '.mk-slider-slide', 11731 nav : '.mk-slider-nav', 11732 effect : 'roulete', 11733 ease : 'easeOutQuart', // should not be changed, remove 11734 slidesPerView : 1, 11735 slidesToView : 1, 11736 transitionTime : 700, 11737 displayTime : 3000, 11738 autoplay : true, 11739 hasNav : true, 11740 hasPagination : true, 11741 paginationTpl : '<span></span>', 11742 paginationEl : '#pagination', 11743 draggable : true, 11744 fluidHeight : false, 11745 pauseOnHover : false, 11746 lazyload : false, 11747 activeClass : 'is-active', 11748 edgeSlider : false, 11749 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>', 11750 onInitialize : function() {}, 11751 onAfterSlide : function( id ) {}, 11752 onBeforeSlide : function( id ) {} 11753 }; 11754 11755 this.state = { 11756 id : 0, 11757 moveForward : true, 11758 running : false, 11759 zIFlow : null, 11760 stop : false, 11761 }; 11762 11763 this.config = $.extend( defaults, config ); 11764 this.container = container; 11765 11766 this.initPerView = this.config.slidesPerView; 11767 11768 // Timer holder 11769 this.activeTimer = null; 11770 this.autoplay = null; 11771 this.timer = null; 11772 this.timerRemaining = parseInt(this.config.displayTime); 11773 11774 // Boolean 'Em All, Making sure it's not string 11775 this.config.lazyload = JSON.parse(this.config.lazyload); 11776 this.config.edgeSlider = JSON.parse(this.config.edgeSlider); 11777 11778 // Image Loader Instance 11779 this.imageLoader = null; 11780 11781 // Add abort command to imagesLoaded, Placing it inside script makes it to work with different versions 11782 // of imagesLoaded if loaded by other Plugins 11783 imagesLoaded.prototype.abort = function() { 11784 this.progress = this.complete = function() { }; 11785 }; 11786 }; 11787 11788 11789 11790 // 11791 // Shared methods 11792 // 11793 // ///////////////////////////////////////////////////////// 11794 11795 MK.ui.Slider.prototype = { 11796 11797 init : function() { 11798 this.setPerViewItems(); 11799 this.cacheElements();
11800 this.getSlideSize(); 11801 this.bindEvents(); 11802 this.setSize(); 11803 this.setPos(); 11804 11805 // Hack for preparing 'prev' on first click if needed 11806 this.updateId( -1 ); 11807 this.updateId( 1 ); 11808 11809 this.val = this.dynamicVal(); 11810 this.timeline = this.prepareTimeline( this.config.transitionTime ); 11811 11812 this.timeline.build(); 11813 11814 if( this.config.hasPagination ) { this.buildPagination(); } 11815 11816 if( this.config.autoplay && document.hasFocus() ) { this.setTimer(); } 11817 11818 if( typeof this.config.onInitialize === 'function' ) { 11819 this.config.onInitialize( this.slides ); 11820 } 11821 11822 if( this.config.fluidHeight === true ) { 11823 $( this.slides ).height( 'auto' ); 11824 $( this.container ).css( 'transition', 'height ' + 200 + 'ms ease-out' ); 11825 this.setHeight( 0 ); 11826 } 11827 11828 11829 if( this.config.fluidHeight === 'toHighest' ) { 11830 this.setHeightToHighest(); 11831 } 11832 11833 // Create timer per slide if required 11834 $(this.slides).each(this.createTimer); 11835 11836 // If it's Edge Slider and Lazy Load is enabled 11837 if ( this.config.lazyload && this.config.edgeSlider ) { 11838 11839 // If It's not a Video Slide 11840 if ( $(this.slides[this.state.id]).find('video').length === 0 ) { 11841 // Set the first slide's BG image 11842 var $slideImg = $(this.slides[this.state.id]).children('[data-mk-img-set]'); 11843 MK.component.BackgroundImageSetter.init( $slideImg ); 11844 } 11845 $(this.config.spinnerTpl).prependTo( this.$slides ); 11846 11847 } else { 11848 11849 // Set all slides's BG images 11850 MK.component.BackgroundImageSetter.init( $(this.slides).children('[data-mk-img-set]') ); 11851 11852 } 11853 11854 11855 11856 }, 11857 11858 11859 cacheElements : function () { 11860 this.container = this.isNode( this.container ) ? this.container 11861 : document.querySelectorAll( this.container )[0]; 11862 this.slides = this.container.querySelectorAll( this.config.slide ); 11863 this.$slides = $(this.slides); 11864 11865 if( this.config.hasNav ) { this.$nav = $( this.config.nav ); } 11866 if( this.config.hasPagination ) { this.$pagination = $( this.config.paginationEl ); } 11867 }, 11868 11869 11870 bindEvents : function() { 11871 var $window = $( window ); 11872 11873 if( this.config.slidesPerView > 1 ) { $window.on( 'resize', this.setPerViewItems.bind( this ) ); } 11874 if( this.config.hasNav ) { this.eventsNav(); } 11875 if( this.config.hasPagination ) { this.eventsPag(); } 11876 if( this.config.draggable ) { this.dragHandler(); } 11877 if( this.config.autoplay ) { 11878 $window.on( 'focus', this.windowActive.bind( this ) ); 11879 $window.on( 'blur', this.windowInactive.bind( this ) ); 11880 } 11881 if( this.config.pauseOnHover ) { 11882 $(this.container).on( 'mouseleave', this.setTimer.bind( this ) ); 11883 $(this.container).on( 'mouseenter', this.unsetTimer.bind( this ) ); 11884 } 11885 if( this.config.fluidHeight === 'toHighest' ) { 11886 $window.on( 'resize', this.setHeightToHighest.bind( this ) ); 11887 } 11888 }, 11889 11890 11891 setPerViewItems: function() { 11892 if(window.matchMedia( '(max-width: 500px)' ).matches) { this.config.slidesPerView = 1; } 11893 else if(window.matchMedia( '(max-width: 767px)' ).matches && this.initPerView >= 2 ) { this.config.slidesPerView = 2; } 11894 else if(window.matchMedia( '(max-width: 1024px)' ).matches && this.initPerView >= 3 ) { this.config.slidesPerView = 3; } 11895 else { this.config.slidesPerView = this.initPerView; } 11896 11897 if( typeof this.slides === 'undefined' ) return; 11898 this.getSlideSize(); 11899 this.setSize(); 11900 this.setPos(); 11901 this.timeline = this.prepareTimeline( this.config.transitionTime ); 11902 this.timeline.build(); 11903 }, 11904 11905 11906 eventsNav : function() { 11907 this.$nav.on( 'click', 'a', this.handleNav.bind( this ) ); 11908 }, 11909 11910 11911 eventsPag : function() { 11912 this.$pagination.on( 'click', 'a', this.handlePagination.bind( this ) ); 11913 }, 11914 11915 11916 handleNav : function( e ) { 11917 e.preventDefault(); 11918 11919 if( this.state.running ) { return; } 11920 this.state.running = true; 11921 11922 var $this = $( e.currentTarget ), 11923 moveForward = $this.data( 'direction' ) === 'next'; 11924 11925 11926 if( this.config.autoplay ) { 11927 this.unsetTimer(); 11928 setTimeout( this.setTimer.bind( this ), this.config.transitionTime ); 11929 } 11930 11931 this.state.moveForward = moveForward; 11932 this.timeline.build(); 11933 this.timeline.play(); 11934 11935 this.setActive( this.nextId( moveForward ? 1 : -1 ) ); 11936 if( this.config.fluidHeight ) { this.setHeight( this.nextId( moveForward ? 1 : -1 ) ); } 11937 }, 11938 11939 11940 handlePagination : function( e ) { 11941 e.preventDefault(); 11942 11943 var $this = $( e.currentTarget ), 11944 id = $this.index(); 11945 11946 this.goTo( id ); 11947 }, 11948 11949 11950 reset: function() { 11951 this.state.stop = true; 11952 this.state.id = 0; 11953 this.setPos(); 11954 this.unsetTimer(); 11955 this.setTimer(); 11956 }, 11957 11958 11959 goTo : function(id) { 11960 if( this.state.running ) { return; } 11961 this.state.running = true; 11962 11963 var lastId = this.state.id; 11964 11965 if( lastId === id ) { 11966 return; 11967 } else if( lastId < id ) { 11968 this.state.moveForward = true; 11969 } else { 11970 this.state.moveForward = false;
11971 } 11972 11973 if( this.config.autoplay ) { 11974 this.unsetTimer(); 11975 setTimeout( this.setTimer.bind( this ), this.config.transitionTime ); 11976 } 11977 11978 this.timeline.build( Math.abs( lastId - id ) ); 11979 this.timeline.play(); 11980 11981 this.setActive( id ); 11982 if( this.config.fluidHeight ) { this.setHeight( id ); } 11983 }, 11984 11985 11986 windowActive : function() { 11987 this.setTimer(false, true); 11988 $(this.container).removeClass('is-paused'); 11989 }, 11990 11991 11992 windowInactive : function() { 11993 this.unsetTimer(); 11994 $(this.container).addClass('is-paused'); 11995 }, 11996 11997 11998 updateId : function( val ) { 11999 this.state.id = this.nextId(val); 12000 }, 12001 12002 nextId : function( val ) { 12003 var len = this.slides.length, 12004 insertVal = this.state.id + val; 12005 insertVal = ( insertVal >= 0 ) ? insertVal : len + val; 12006 insertVal = ( insertVal >= len ) ? 0 : insertVal; 12007 12008 return insertVal; 12009 }, 12010 12011 12012 setStyle : function( obj, style ) { 12013 var hasT = style.transform, 12014 t = { 12015 x : ( hasT ) ? style.transform.translateX : null, 12016 y : ( hasT ) ? style.transform.translateY : null, 12017 scale : ( hasT ) ? style.transform.scale : null, 12018 rotate : ( hasT ) ? style.transform.rotate : null, 12019 rotateX : ( hasT ) ? style.transform.rotateX : null, 12020 rotateY : ( hasT ) ? style.transform.rotateY : null 12021 }, 12022 z = 'translateZ(0)', 12023 x = (t.x) ? 'translateX(' + t.x + '%)' : 'translateX(0)', 12024 y = (t.y) ? 'translateY(' + t.y + '%)' : 'translateY(0)', 12025 s = (t.scale) ? 'scale(' + t.scale + ')' : 'scale(1)', 12026 r = (t.rotate) ? 'rotate(' + t.rotate + 'deg)' : 'rotate(0)', 12027 rX = (t.rotateX) ? 'rotateX(' + t.rotateX + 'deg)' : '', 12028 rY = (t.rotateY) ? 'rotateY(' + t.rotateY + 'deg)' : '', 12029 12030 o = style.opacity, 12031 h = style.height, 12032 w = style.width; 12033 12034 var c = z + x + y + s + r + rX + rY; 12035 12036 if( c.length ) { 12037 obj.style.webkitTransform = c; 12038 obj.style.msTransform = c; 12039 obj.style.transform = c; 12040 } 12041 12042 if( typeof o === 'number' ) { obj.style.opacity = o; } 12043 if( h ) { obj.style.height = h + '%'; } 12044 if( w ) { obj.style.width = w + '%'; } 12045 }, 12046 12047 12048 setPos : function() { 12049 if( typeof this.slides === 'undefined' ) return; 12050 var id = this.state.id, 12051 i = 0, 12052 len = this.slides.length, 12053 animation = this.animation[ this.config.effect ], 12054 axis = animation.axis, 12055 animNext = animation.next, 12056 animActi = animation.active, 12057 animPrev = animation.prev, 12058 perView = this.config.slidesPerView, 12059 slideId = null, 12060 zIFlow = null, 12061 style = {}; 12062 12063 style.transform = {}; 12064 12065 12066 for( ; i < len; i += 1 ) { 12067 if(i < perView) { 12068 // Position for visible slides. Apply active styles 12069 style = animActi; 12070 style.transform[ 'translate' + axis ] = i * 100; 12071 } else { 12072 // Rest slides move after edge based on axis and moveForward. Apply Next / Prev styles 12073 style = this.state.moveForward ? animNext : animPrev; 12074 style.transform[ 'translate' + axis ] = this.state.moveForward ? perView * 100 : -100; 12075 } 12076 12077 this.slides[ i ].style.zIndex = 0; 12078 12079 slideId = ( i + id ) % len; 12080 this.setStyle( this.slides[ slideId ], style ); 12081 } 12082 }, 12083 12084 12085 // When we're setting animation along Y axis we're going to set up height 12086 // otherwise width. It is shared amongst all slides 12087 setSize : function() { 12088 if( typeof this.slides === 'undefined' ) return; 12089 var i = 0, 12090 len = this.slides.length, 12091 axis = this.animation[ this.config.effect ].axis, 12092 slideSize = this.slideSize, 12093 style = {}; 12094 12095 if( axis === 'Y' ) { 12096 style.height = slideSize[ axis ]; 12097 } else { 12098 style.width = slideSize[ axis ]; 12099 } 12100 12101 for( ; i < len; i += 1 ) { 12102 this.setStyle( this.slides[ i ], style ); 12103 } 12104 }, 12105 12106 12107 setHeight : function( id ) { 12108 var $slides = $( this.slides ), 12109 $activeSlide = $slides.eq( id ); 12110 12111 var currentHeight = $activeSlide.height(); 12112 $( this.container ).height( currentHeight ); 12113 }, 12114 12115 12116 setHeightToHighest : function() { 12117 // this is becouse of alliginig woocommrece carousel. Too much DOM 12118 // Refactor someday 12119 var $slides = $( this.slides ), 12120 height = 0; 12121 12122 $slides.each(function() { 12123 height = Math.max(height, $(this).find('> div').outerHeight()); 12124 }); 12125 12126 $( this.container ).height( height ); 12127 }, 12128 12129 12130 // Little utility inspired by GreenSock. 12131 // We export this to this.timeline on init. 12132 prepareTimeline : function( time ) { 12133 var self = this, 12134 iteration = 0, 12135 totalIter = time / (1000 / 60), 12136 animLoop = [], 12137 aL = 0, // animation length 12138 loops = 1, 12139 ease = this.config.ease, 12140 currentStyle, timeProg, 12141 build, move, add, play, reverse, progress, kill; 12142 12143 12144 // Build constants, run them only once 12145 // take out possibly 12146 var len = this.slides.length, 12147 perView = this.config.slidesPerView, 12148 animation = this.animation[ this.config.effect ], 12149 animAxis = animation.axis, 12150 animNext = animation.next, 12151 animActi = animation.active, 12152 animPrev = animation.prev, 12153 style = {}, 12154 slideId = null, 12155 zIFlow = null; 12156 12157 style.transform = {}; 12158 12159 12160 build = function( repeats ) { 12161 var currentEase = ease; 12162 loops = repeats || loops; 12163 12164 // console.log('build', loops); 12165 12166 if( !loops ) { return; } 12167 if( loops > 1 ) { 12168 currentEase = 'linearEase'; 12169 } 12170 12171 // clean before running new build 12172 kill(); 12173 // set new positions 12174 self.setPos(); 12175 12176 var id = self.state.id, 12177 moveForward = self.state.moveForward, 12178 i = 0, 12179 axisMove = (moveForward) ? -100 : 100; 12180
12181 for( ; i <= perView; i += 1 ) { 12182 slideId = ( (moveForward) ? i + id : i + id - 1 ) % len; 12183 slideId = ( slideId < 0 ) ? len + slideId : slideId; 12184 12185 if( i === 0 ) { 12186 style = moveForward ? animPrev : animActi; 12187 } else if( i === perView ) { 12188 style = moveForward ? animActi : animNext; 12189 } else { 12190 style = animActi; 12191 } 12192 12193 zIFlow = (self.state.moveForward) ? animNext.zIndex : animPrev.zIndex; 12194 if( zIFlow ) { 12195 // console.log( zIFlow ); 12196 self.slides[ slideId ].style.zIndex = (zIFlow === '+') ? i + 1 : len - i; 12197 } 12198 12199 style.transform[ 'translate' + animAxis ] = axisMove; 12200 add( self.slides[ slideId ], style, currentEase ); 12201 } 12202 }; 12203 12204 add = function( slide, toStyles, ease ) { 12205 if( typeof slide === 'undefined' ) { 12206 throw 'Add at least one slide'; 12207 } 12208 12209 var fromStyles = slide.style, 12210 style = self.refStyle( toStyles, fromStyles ); 12211 12212 animLoop.push( [slide, style, ease] ); 12213 aL += 1; 12214 }; 12215 12216 move = function( startProg, mode ) { 12217 if (isTest) return; 12218 var currentTotalIter = totalIter; 12219 12220 if( loops > 1 ) { 12221 currentTotalIter = totalIter / 5; 12222 } 12223 12224 if( !self.state.running ) { self.state.running = true; } 12225 12226 if( startProg ) { 12227 // update iteration val to cached outside var 12228 // ceil to handle properly play after mouse up / touch end 12229 iteration = Math.ceil(startProg * currentTotalIter); 12230 } 12231 12232 timeProg = iteration / currentTotalIter; 12233 progress( timeProg ); 12234 12235 // Break loop 12236 if( iteration >= currentTotalIter && mode === 'play' || 12237 iteration <= 0 && mode === 'reverse' ) { 12238 12239 self.state.running = false; 12240 iteration = 0; 12241 kill(); 12242 self.updateId( self.state.moveForward ? 1 : -1 ); 12243 // If we're creating multiple animation loop we trigger outside only first pass to start all game. 12244 // the rest are triggered as callback 12245 loops -= 1; 12246 if( loops > 0 ) { 12247 build(); 12248 play(); 12249 } 12250 12251 // if we run all loops reset back the default value 12252 if( !loops ) { 12253 loops = 1; 12254 self.timerRemaining = parseInt(self.config.displayTime); 12255 self.config.onAfterSlide( self.state.id ); 12256 } 12257 12258 return; 12259 } 12260 12261 // Run in given mode 12262 if( mode === 'play') { 12263 iteration += 1; 12264 } else { 12265 iteration -= 1; 12266 } 12267 12268 requestAnimationFrame( function() { 12269 if(self.state.stop) return; 12270 move( 0, mode ); 12271 }); 12272 }; 12273 12274 play = function( startProg ) { 12275 12276 var $nextSlide = $(self.slides[ self.nextId(self.state.moveForward ? 1 : -1) ] ); 12277 12278 // If it's Edge Slider and Lazy Load is enabled and It's not a Video Slide 12279 if ( self.config.lazyload && self.config.edgeSlider ) { 12280 12281 // Set the next slide's BG Image 12282 var $slideImg = $nextSlide.find('[data-mk-img-set]'); 12283 if ( $slideImg.length ) { 12284 MK.component.BackgroundImageSetter.init( $slideImg ); 12285 } 12286 12287 } 12288 12289 self.config.onBeforeSlide( self.nextId(self.state.moveForward ? 1 : -1) ); 12290 var start = startProg || 0; 12291 iteration = 0; 12292 self.state.stop = false; 12293 move( start, 'play' ); 12294 12295 }; 12296 12297 reverse = function( startProg ) { 12298 var start = startProg || 1; 12299 move( start, 'reverse' ); 12300 }; 12301 12302 progress = function( progVal ) { 12303 var aI = 0, 12304 currentStyle; 12305 12306 for( aI; aI < aL; aI++ ) { 12307 if( progVal !== 1 && progVal !== 0 ) { 12308 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], animLoop[ aI ][ 2 ] ); 12309 } else if( progVal === 1) { 12310 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' ); 12311 } else if ( progVal === 0 ) { 12312 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' ); 12313 } 12314 self.setStyle( animLoop[ aI ][ 0 ], currentStyle ); 12315 } 12316 }; 12317 12318 // Clear previous loop 12319 kill = function() { 12320 animLoop = []; 12321 aL = 0; 12322 }; 12323 12324 12325 return { 12326 build : build, 12327 add : add, 12328 play : play, 12329 reverse : reverse, 12330 progress : progress 12331 }; 12332 }, 12333 12334 12335 // Build reference styles. 12336 // Return object with array containig initial style and change of its value 12337 // as required for easing functions 12338 refStyle : function( toStyles, fromStyles ) { 12339 var axis = this.animation[ this.config.effect ].axis, 12340 style = {}, 12341 initVal, changeVal, endVal, dynamicEnd, styleProp, transProp, transform; 12342 12343 for( styleProp in toStyles ) { 12344 12345 if( styleProp === 'transform' ) { 12346 transform = this.getTransforms( fromStyles ); 12347 style.transform = {}; 12348 12349 for( transProp in toStyles.transform ) { 12350 // don't care about z 12351 if( transProp === 'translateZ' ) { continue; } 12352 12353 initVal = transform[ transProp ] || 0; // if it is undefined it means it's 0 12354 dynamicEnd = ( transProp === 'translate' + axis ) ? initVal : 0; 12355 endVal = toStyles.transform[ transProp ] + dynamicEnd; // it is dynamic, based on slide position in current set 12356 changeVal = endVal - initVal; 12357 style.transform[ transProp ] = [ initVal, changeVal ]; 12358 } 12359 } else if( styleProp === 'zIndex' ) { 12360 // console.log( 'z' ); 12361 continue; 12362 } else { 12363 initVal = parseFloat( fromStyles[ styleProp ] ) || 0; // if it is undefined it means it's 0 12364 endVal = toStyles[ styleProp ]; 12365 changeVal = endVal - initVal; 12366 style[ styleProp ] = [ initVal, changeVal ]; 12367 } 12368 } 12369 12370 return style; 12371 }, 12372 12373 12374 currentStyle : function( progress, style, ease ) { 12375 var self = this, 12376 currentStyle = {}, 12377 currentVals, styleProp, transProp, prog; 12378 12379 // Redo same loop but construct currentStyle object out of cached values 12380 for( styleProp in style ) { 12381 12382 if( styleProp === 'transform' ) { 12383 currentStyle.transform = {}; 12384 12385 for( transProp in style.transform ) { 12386 // remove this line. double check first if needed by logging 12387 if( transProp === 'translateZ' ) { continue; } 12388 12389 currentVals = style.transform[ transProp ]; 12390 currentStyle.transform[ transProp ] = 12391 // (currentIteration, startValue, changeInValue, totalIterations) 12392 self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 ); 12393 } 12394 } else { 12395 currentVals = style[ styleProp ]; 12396 currentStyle[ styleProp ] = 12397 self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 ); 12398 } 12399 } 12400 12401 return currentStyle; 12402 }, 12403 12404 12405 setActive : function( id ) { 12406 var $slides = $( this.slides ), 12407 className = this.config.activeClass; 12408 12409 $slides.removeClass( className ); 12410 12411 if( this.config.hasPagination ) { 12412 var $pagination = this.$pagination.find( 'a' ); 12413 $pagination.removeClass( className ); 12414 $pagination.eq( id ).addClass( className ); 12415 } 12416 12417 if( this.activeTimer ) { 12418 clearTimeout( this.activeTimer ); 12419 if ( this.imageLoader ) { 12420 this.imageLoader.abort(); 12421 } 12422 } 12423 12424 12425 var self = this; 12426 12427 this.activeTimer = setTimeout( function() { 12428 12429 var $currentSlide = $slides.eq( id ); 12430 12431 if ( self.config.lazyload && self.config.edgeSlider ) { // If it's Edge Slider and Lazy Load is enabled 12432
12433 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 12434 12435 var imgSet = $currentSlide.children('.mk-video-section-touch').data('mk-img-set'); 12436 var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet ); 12437 var $bgImage = $('<img>').attr('src', exactImg ); 12438 12439 self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) { 12440 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12441 setTimeout( function() { 12442 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12443 }, 200); 12444 $currentSlide.addClass( className ); 12445 }); 12446 12447 } 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 12448 12449 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12450 setTimeout( function() { 12451 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12452 }, 200); 12453 $currentSlide.addClass( className ); 12454 12455 } else { // If it's a Image Slide 12456 12457 if ( $currentSlide.children('[data-mk-img-set]').length ) { 12458 // Get the matching Image URL to start lazy loading 12459 var imgSet = $currentSlide.children('[data-mk-img-set]').data('mk-img-set'); 12460 var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet ); 12461 var $bgImage = $('<img>').attr('src', exactImg ); 12462 12463 // Prevent counting time on slide until the image loads 12464 self.unsetTimer(); 12465 self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) { 12466 // Hide spinner, Continue counting time on slide and show the content 12467 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12468 setTimeout( function() { 12469 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12470 }, 200); 12471 self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) ); 12472 $currentSlide.addClass( className ); 12473 }); 12474 } else { 12475 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12476 setTimeout( function() { 12477 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12478 }, 200); 12479 self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) ); 12480 $currentSlide.addClass( className ); 12481 } 12482 12483 } 12484 12485 } else { 12486 12487 $currentSlide.addClass( className ); 12488 12489 } 12490 12491 12492 }, this.config.transitionTime ); 12493 }, 12494 12495 createTimer : function() { 12496 12497 var $slide = $(this), 12498 video = $slide.find('video').get(0); 12499 12500 if(video) { 12501 // A hacky but reliable way to ge the video duration 12502 var interval = setInterval( function() { 12503 // If the metadata is ready 12504 if ( video.readyState > 0 ) { 12505 $slide.data('timer', (video.duration * 1000)); 12506 $slide.attr('data-timer', (video.duration * 1000)); 12507 clearInterval(interval); 12508 } 12509 }, 100); 12510 } 12511 12512 }, 12513 12514 setTimer : function( isFirst, isPaused, fixed_time ) { 12515 // check for custom timer 12516 var customTimer = this.$slides.eq(this.nextId(this.state.moveForward ? 1 : -1)).data('timer'), 12517 trans = parseInt( this.config.transitionTime ), 12518 interval = customTimer ? customTimer : parseInt( this.config.displayTime ), 12519 timer = interval + trans; 12520 12521 var self = this, 12522 first = isFirst || true, 12523 fixed_time = fixed_time || 0, 12524 create, run; 12525 12526 this.timer = true; 12527 this.lastSetTimer = Date.now(); 12528 12529 create = function() { 12530 12531 if( self.autoplay ) { clearTimeout( self.autoplay ); } 12532 if( !self.timer ) { 12533 return; 12534 } 12535 self.state.moveForward = true; 12536 self.timeline.build(); 12537 self.timeline.play(); 12538 self.setActive( self.nextId( 1 ) ); 12539 if( self.config.fluidHeight ) { self.setHeight( self.nextId( 1 ) ); } 12540 first = false; 12541 self.lastSetTimer = Date.now(); 12542 12543 run(); 12544 }; 12545 12546 run = function(newInterval) { 12547 // check for custom timer 12548 customTimer = self.$slides.eq(self.nextId(self.state.moveForward ? 1 : -1)).data('timer'); 12549 interval = customTimer ? customTimer : parseInt( self.config.displayTime ); 12550 timer = interval + trans; // update timer with current val 12551 12552 var time = newInterval || timer; 12553 self.autoplay = setTimeout( create, time ); 12554 }; 12555 12556 if ( fixed_time ) { 12557 run( fixed_time ); 12558 } else if (isPaused) { 12559 run( this.timerRemaining ); 12560 } else { 12561 run(); 12562 } 12563 }, 12564 12565 12566 unsetTimer : function() { 12567 this.timer = false;
12568 this.lastUnsetTimer = Date.now(); 12569 this.timerRemaining -= this.lastUnsetTimer - this.lastSetTimer; 12570 if( this.autoplay ) { clearTimeout( this.autoplay ); } 12571 }, 12572 12573 12574 buildPagination : function() { 12575 var i = 0, 12576 len = this.slides.length, 12577 tpl = ''; 12578 12579 for( ; i < len; i += 1 ) { 12580 tpl += '<a href="javascript:;">' + this.config.paginationTpl + '</a>'; 12581 } 12582 12583 this.$pagination.html( tpl ); 12584 this.setActive( 0 ); 12585 }, 12586 12587 12588 getSlideSize : function() { 12589 this.slideSize = { 12590 X: 100 / this.config.slidesPerView, 12591 Y: 100 / this.config.slidesPerView 12592 }; 12593 }, 12594 12595 12596 getTransforms : function( style ) { 12597 // console.log( style ); 12598 var transform = style.transform || style.webkitTransform || style.mozTransform, 12599 regex = /(\w+)\(([^)]*)\)/g, 12600 match, 12601 T = {}; 12602 12603 if( typeof transform !== 'string' ) { 12604 throw 'Transform prop is not a string.'; 12605 } 12606 12607 if( !transform ) { return; } 12608 12609 // Run regex assignment 12610 while( match = regex.exec( transform ) ) { 12611 T[ match[ 1 ] ] = parseFloat( match[ 2 ] ); 12612 } 12613 12614 return T; 12615 }, 12616 12617 isNode : function( o ) { 12618 return ( 12619 typeof Node === "object" ? o instanceof Node : 12620 o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string" 12621 ); 12622 }, 12623 12624 12625 dragHandler : function() { 12626 var self = this, 12627 $container = $( this.container ), 12628 prevBuild = false, 12629 nextBuild = false, 12630 dragging = false, 12631 buffor = 5, // helpful for decoupling with click events 12632 dragStart, dragMove, dragEnd, progress; 12633 12634 progress = function( moveX ) { 12635 return moveX / self.val.viewportW(); 12636 }; 12637 12638 dragStart = function( moveX, startX ) { 12639 // console.log( 'start', moveX, startX ); 12640 }; 12641 12642 dragMove = function( moveX ) { 12643 // console.log('move'); 12644 if( self.state.running ) return; 12645 12646 // Don't need to check for existance here 12647 12648 if( moveX < -buffor ) { 12649 12650 if( !nextBuild ) { 12651 self.state.moveForward = true; 12652 self.timeline.build(); 12653 nextBuild = true; 12654 prevBuild = false; 12655 self.unsetTimer(); 12656 } else { 12657 // turn progress into positive val 12658 self.timeline.progress( -progress( moveX ) ); 12659 } 12660 dragging = true; 12661 } else if( moveX > buffor ) { 12662 12663 if( !prevBuild ) { 12664 self.state.moveForward = false; 12665 self.timeline.build(); 12666 prevBuild = true; 12667 nextBuild = false; 12668 self.unsetTimer(); 12669 } else { 12670 self.timeline.progress( progress( moveX ) ); 12671 } 12672 dragging = true; 12673 } 12674 }; 12675 12676 dragEnd = function( moveX ) { 12677 if( dragging ) { 12678 var prog = progress( moveX ), 12679 absProg = prog < 0 ? -prog : prog; 12680 12681 if( absProg > 0.1 ) { 12682 self.timeline.play( absProg ); 12683 self.setActive( self.nextId( prog < 0 ? 1 : -1 ) ); 12684 if( self.config.fluidHeight ) { self.setHeight( self.nextId( prog < 0 ? 1 : -1 ) ); } 12685 } else { 12686 self.timeline.reverse( absProg ); 12687 // eventually move this to reverse callbacks 12688 if(prog < 0) { 12689 self.updateId( -1 ); 12690 } else { 12691 self.updateId( 1 ); 12692 } 12693 } 12694 12695 prevBuild = false; 12696 nextBuild = false; 12697 dragging = false; 12698 if( self.config.autoplay ) { self.setTimer( false ); } 12699 } 12700 }; 12701 12702 this.drag( $container, dragStart, dragMove, dragEnd ); 12703 }, 12704 12705 12706 drag : function( $el, startFn, moveFn, stopFn ) { 12707 12708 var touchX, touchY, movX, movY, go, evt, 12709 prevent, start, move, stop; 12710 12711 prevent = function( e ) { 12712 e.preventDefault(); 12713 }; 12714 12715 start = function( e ) { 12716 // $el.on("touchmove", prevent); 12717 $el.on("mousemove", prevent); 12718 $el.on("touchmove", move); 12719 $el.on("mousemove", move); 12720 12721 evt = (e.type === 'touchstart') ? e.originalEvent.touches[0] : e; 12722 touchX = evt.pageX; 12723 12724 if(typeof startFn === 'function') { 12725 startFn(movX, touchX); 12726 } 12727 }; 12728 12729 move = function( e ) { 12730 evt = (e.type === 'touchmove') ? e.originalEvent.touches[0] : e; 12731 movX = evt.pageX - touchX; 12732 12733 if(typeof moveFn === 'function') { 12734 moveFn(movX); 12735 } 12736 }; 12737 12738 stop = function( e ) { 12739 // $el.off("touchmove", prevent); 12740 $el.off("mousemove", prevent); 12741 $el.off("touchmove", move); 12742 $el.off("mousemove", move); 12743 12744 if(typeof stopFn === 'function') { 12745 stopFn(movX); 12746 } 12747 }; 12748 12749 $el.on("touchstart", start); 12750 $el.on("mousedown", start); 12751 $el.on("touchend", stop); 12752 $el.on("touchleave", stop); 12753 $el.on("touchcancel", stop);
12754 $el.on("mouseup", stop); 12755 $el.on("mouseleave", stop); 12756 }, 12757 12758 12759 dynamicVal : function() { 12760 var $window = $( window ), 12761 update, 12762 getViewportW, viewportW; 12763 12764 update = function() { 12765 viewportW = $window.width(); 12766 }; 12767 12768 getViewportW = function() { 12769 return viewportW; 12770 }; 12771 12772 update(); 12773 $window.on( 'load', update ); 12774 $window.on( 'resize', update ); 12775 12776 return { 12777 viewportW : getViewportW 12778 }; 12779 } 12780 }; 12781 12782 12783 12784 // 12785 // Set of default animations 12786 // 12787 // ///////////////////////////////////////////////////////// 12788 12789 MK.ui.Slider.prototype.animation = { 12790 12791 slide : { 12792 axis : 'X', 12793 next : { transform: {} }, 12794 active : { transform: {} }, 12795 prev : { transform: {} } 12796 }, 12797 12798 vertical_slide : { 12799 axis : 'Y', 12800 next : { transform: {} }, 12801 active : { transform: {} }, 12802 prev : { transform: {} } 12803 }, 12804 12805 perspective_flip : { 12806 axis : 'Y', 12807 next : { 12808 transform: { 12809 rotateX : 80 12810 } 12811 }, 12812 active : { 12813 transform: { 12814 rotateX : 0 12815 } 12816 }, 12817 prev : { 12818 transform: { 12819 rotateX : 0 12820 } 12821 } 12822 }, 12823 12824 zoom : { 12825 axis : 'Z', 12826 next: { 12827 opacity : 0, 12828 transform : { 12829 scale : 0.9 12830 } 12831 }, 12832 active: { 12833 opacity : 1, 12834 transform : { 12835 scale : 1 12836 } 12837 }, 12838 prev: { 12839 opacity : 0, 12840 transform : { 12841 scale : 1.1 12842 } 12843 } 12844 }, 12845 12846 fade : { 12847 axis : 'Z', 12848 next: { 12849 opacity : 0, 12850 transform : {} 12851 }, 12852 active: { 12853 opacity : 1, 12854 transform : {} 12855 }, 12856 prev: { 12857 opacity : 0, 12858 transform : {} 12859 } 12860 }, 12861 12862 kenburned : { 12863 axis : 'Z', 12864 next: { 12865 opacity : 0, 12866 transform : {} 12867 }, 12868 active: { 12869 opacity : 1, 12870 transform : {} 12871 }, 12872 prev: { 12873 opacity : 0, 12874 transform : {} 12875 } 12876 }, 12877 12878 zoom_out : { 12879 axis : 'Z', 12880 next: { 12881 zIndex : '+', 12882 opacity : 1, 12883 transform : { 12884 translateY : 100, 12885 scale : 1 12886 } 12887 }, 12888 active: { 12889 opacity : 1, 12890 transform : { 12891 translateY : 0, 12892 scale : 1 12893 } 12894 }, 12895 prev: { 12896 zIndex : '+', 12897 opacity : 0, 12898 transform : { 12899 translateY : 0, 12900 scale : 0.5 12901 } 12902 } 12903 }, 12904 12905 // Problem with Z-Flow 12906 horizontal_curtain : { 12907 axis : 'Z', 12908 next: { 12909 zIndex : '+', 12910 transform : { 12911 translateX : 100, 12912 } 12913 }, 12914 active: { 12915 transform : { 12916 translateX : 0, 12917 } 12918 }, 12919 prev: { 12920 zIndex : '+', 12921 transform : { 12922 translateX : -70, 12923 } 12924 } 12925 }, 12926 12927 roulete : { 12928 axis : 'X', 12929 next: { 12930 opacity : 0.5, 12931 transform : { 12932 scale : 0.5, 12933 rotate : 10, 12934 translateY : 20 12935 } 12936 }, 12937 active: { 12938 opacity : 1, 12939 transform : { 12940 scale : 1, 12941 rotate : 0, 12942 translateY : 0 12943 } 12944 }, 12945 prev: { 12946 opacity : 0.3, 12947 transform : { 12948 scale : 0.5, 12949 rotate : -10, 12950 translateY : 20 12951 } 12952 } 12953 } 12954 }; 12955 12956 12957 12958 // 12959 // Penner's easing library 12960 // 12961 // ///////////////////////////////////////////////////////// 12962 12963 MK.ui.Slider.prototype.ease = { 12964 /* 12965 *
12966 * TERMS OF USE - EASING EQUATIONS 12967 * 12968 * Open source under the BSD License. 12969 * 12970 * Copyright © 2001 Robert Penner 12971 * All rights reserved. 12972 * 12973 * Redistribution and use in source and binary forms, with or without modification, 12974 * are permitted provided that the following conditions are met: 12975 * 12976 * Redistributions of source code must retain the above copyright notice, this list of 12977 * conditions and the following disclaimer. 12978 * Redistributions in binary form must reproduce the above copyright notice, this list 12979 * of conditions and the following disclaimer in the documentation and/or other materials 12980 * provided with the distribution. 12981 * 12982 * Neither the name of the author nor the names of contributors may be used to endorse 12983 * or promote products derived from this software without specific prior written permission. 12984 * 12985 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 12986 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 12987 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 12988 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 12989 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 12990 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 12991 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 12992 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 12993 * OF THE POSSIBILITY OF SUCH DAMAGE. 12994 * 12995 */ 12996 linearEase : function(currentIteration, startValue, changeInValue, totalIterations) { 12997 return changeInValue * currentIteration / totalIterations + startValue; 12998 }, 12999 13000 easeInQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13001 return changeInValue * (currentIteration /= totalIterations) * currentIteration + startValue; 13002 }, 13003 13004 easeOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13005 return -changeInValue * (currentIteration /= totalIterations) * (currentIteration - 2) + startValue; 13006 }, 13007 13008 easeInOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13009 if ((currentIteration /= totalIterations / 2) < 1) { 13010 return changeInValue / 2 * currentIteration * currentIteration + startValue; 13011 } 13012 return -changeInValue / 2 * ((--currentIteration) * (currentIteration - 2) - 1) + startValue; 13013 }, 13014 13015 easeInCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13016 return changeInValue * Math.pow(currentIteration / totalIterations, 3) + startValue; 13017 }, 13018 13019 easeOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13020 return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue; 13021 }, 13022 13023 easeInOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13024 if ((currentIteration /= totalIterations / 2) < 1) { 13025 return changeInValue / 2 * Math.pow(currentIteration, 3) + startValue; 13026 } 13027 return changeInValue / 2 * (Math.pow(currentIteration - 2, 3) + 2) + startValue; 13028 }, 13029 13030 easeInQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13031 return changeInValue * Math.pow (currentIteration / totalIterations, 4) + startValue; 13032 }, 13033 13034 easeOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13035 return -changeInValue * (Math.pow(currentIteration / totalIterations - 1, 4) - 1) + startValue; 13036 }, 13037 13038 easeInOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13039 if ((currentIteration /= totalIterations / 2) < 1) { 13040 return changeInValue / 2 * Math.pow(currentIteration, 4) + startValue; 13041 } 13042 return -changeInValue/2 * (Math.pow(currentIteration - 2, 4) - 2) + startValue; 13043 }, 13044 13045 easeInQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13046 return changeInValue * Math.pow (currentIteration / totalIterations, 5) + startValue; 13047 }, 13048 13049 easeOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13050 return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 5) + 1) + startValue; 13051 }, 13052 13053 easeInOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13054 if ((currentIteration /= totalIterations / 2) < 1) { 13055 return changeInValue / 2 * Math.pow(currentIteration, 5) + startValue; 13056 } 13057 return changeInValue / 2 * (Math.pow(currentIteration - 2, 5) + 2) + startValue; 13058 }, 13059 13060 easeInSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13061 return changeInValue * (1 - Math.cos(currentIteration / totalIterations * (Math.PI / 2))) + startValue; 13062 }, 13063 13064 easeOutSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13065 return changeInValue * Math.sin(currentIteration / totalIterations * (Math.PI / 2)) + startValue; 13066 }, 13067 13068 easeInOutSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13069 return changeInValue / 2 * (1 - Math.cos(Math.PI * currentIteration / totalIterations)) + startValue; 13070 }, 13071 13072 easeInExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13073 return changeInValue * Math.pow(2, 10 * (currentIteration / totalIterations - 1)) + startValue; 13074 }, 13075 13076 easeOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13077 return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue; 13078 }, 13079 13080 easeInOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13081 if ((currentIteration /= totalIterations / 2) < 1) { 13082 return changeInValue / 2 * Math.pow(2, 10 * (currentIteration - 1)) + startValue; 13083 } 13084 return changeInValue / 2 * (-Math.pow(2, -10 * --currentIteration) + 2) + startValue; 13085 }, 13086 13087 easeInCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13088 return changeInValue * (1 - Math.sqrt(1 - (currentIteration /= totalIterations) * currentIteration)) + startValue; 13089 }, 13090 13091 easeOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13092 return changeInValue * Math.sqrt(1 - (currentIteration = currentIteration / totalIterations - 1) * currentIteration) + startValue; 13093 }, 13094 13095 easeInOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13096 if ((currentIteration /= totalIterations / 2) < 1) { 13097 return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue; 13098 } 13099 return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue; 13100 } 13101 }; 13102 13103})(jQuery); 13104/* Social Share */ 13105/* -------------------------------------------------------------------- */ 13106(function($) { 13107 'use strict'; 13108 13109 MK.component.SocialShare = function( el ) { 13110 var networks = { 13111 twitter : 'http://twitter.com/intent/tweet?text={title} {url}', 13112 pinterest : 'http://pinterest.com/pin/create/button/?url={url}&media={image}&description={title}', 13113 facebook : 'https://www.facebook.com/sharer/sharer.php?u={url}', 13114 googleplus : 'https://plus.google.com/share?url={url}', 13115 linkedin : 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&summary={desc}', 13116 digg : 'http://digg.com/submit?url={url}&title={title}', 13117 reddit : 'http://reddit.com/submit?url={url}&title={title}', 13118 }; 13119 13120 this.networks = networks; 13121 this.el = el; 13122 }; 13123 13124
13125 MK.component.SocialShare.prototype = { 13126 13127 init : function() { 13128 this.cacheElements(); 13129 this.bindEvents(); 13130 }, 13131 13132 cacheElements : function() { 13133 this.$this = $( this.el ); 13134 13135 13136 }, 13137 13138 bindEvents : function() { 13139 var thisObject = this; 13140 var tempClass = ""; 13141 $.each(this.networks, function( key, value ) { 13142 thisObject.$tempClass = $('.' + key + '-share'); 13143 thisObject.$tempClass.click(thisObject.openSharingDialog.bind(self, this, key)); 13144 13145 }); 13146 }, 13147 13148 openSharingDialog : function(url, site, args) { 13149 var urlWrapper = url; 13150 var rx = new RegExp('\{[a-z]*\}','g'), res; 13151 var match = rx.exec(url); 13152 while (match != null) { 13153 var pureAttr = match[0].replace("{", "").replace("}" , ""); 13154 var attValue = $(args.currentTarget).attr('data-' + pureAttr); 13155 if (attValue === undefined || attValue === null) { 13156 attValue = ""; 13157 } 13158 attValue = attValue.replace('#', '%23'); // fix for twitter description 13159 urlWrapper = urlWrapper.replace(match, attValue); 13160 match = rx.exec(url); 13161 } 13162 13163 window.open(urlWrapper, site + "Window", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 13164 13165 }, 13166 13167 13168 }; 13169 13170 13171 ////////////////////////////////////////// 13172 // 13173 // Apply to: 13174 // 13175 // /////////////////////////////////////// 13176 13177 var $body = $('body'); 13178 13179 if(!$body.length) return; 13180 13181 $body.each(function() { 13182 var socialShare = new MK.component.SocialShare(this); 13183 socialShare.init(); 13184 }); 13185 13186})(jQuery); 13187 13188 13189 13190//function mk_social_share() { 13191// 13192// "use strict";
13193// 13194// $('.twitter-share').on('click', function () { 13195// var $url = $(this).attr('data-url'), 13196// $title = $(this).attr('data-title'); 13197// 13198// 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"); 13199// return false; 13200// }); 13201// 13202// $('.pinterest-share').on('click', function () { 13203// var $url = $(this).attr('data-url'), 13204// $title = $(this).attr('data-title'), 13205// $image = $(this).attr('data-image'); 13206// 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"); 13207// return false; 13208// }); 13209// 13210// $('.facebook-share').on('click', function () { 13211// var $url = $(this).attr('data-url'); 13212// 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"); 13213// return false; 13214// }); 13215// 13216// $('.googleplus-share').on('click', function () { 13217// var $url = $(this).attr('data-url'); 13218// 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"); 13219// return false; 13220// }); 13221// 13222// $('.linkedin-share').on('click', function () { 13223// var $url = $(this).attr('data-url'), 13224// $title = $(this).attr('data-title'), 13225// $desc = $(this).attr('data-desc'); 13226// 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"); 13227// return false; 13228// }); 13229//} 13230 13231 13232 13233 13234(function($) { 13235 'use strict'; 13236 13237 MK.component.Sortable = function(el) { 13238 this.el = el; 13239 }; 13240 13241 MK.component.Sortable.prototype = { 13242 init: function init() { 13243 this.cacheElements(); 13244 this.bindEvents(); 13245 }, 13246 13247 cacheElements: function cacheElements() { 13248 this.unique = Date.now(); 13249 this.$filter = $(this.el); 13250 this.config = this.$filter.data('sortable-config'); 13251 13252 this.ajaxLoader = new MK.utils.ajaxLoader(this.config.container); 13253 this.ajaxLoader.init(); 13254 13255 this.$container = $( this.config.container ); 13256 this.$navItems = this.$filter.find('a'); 13257 this.$filterItems = this.$container.find(this.config.item); 13258 }, 13259 13260 bindEvents: function bindEvents() { 13261 this.$navItems.on('click', this.handleClick.bind(this)); 13262 MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this)); 13263 }, 13264 13265 handleClick: function handleClick(e) { 13266 e.preventDefault(); 13267 13268 var $item = $(e.currentTarget); 13269 var term = $item.data('filter'); 13270 13271 this.$navItems.removeClass('current'); 13272 $item.addClass('current'); 13273 13274 if(this.config.mode === 'ajax') this.inDB(term, $item); 13275 else this.inPage(term); 13276 }, 13277 13278 inDB: function inDB(term, $item) { 13279 // Add load indicator only for long requests 13280 MK.ui.loader.remove(this.$filter); 13281 MK.ui.loader.add($item); 13282 13283 // If mk-ajax-loaded-posts span exists and one of the filter is clicked, 13284 // clear post ids 13285 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 13286 this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', ''); 13287 } 13288 13289 this.ajaxLoader.setData({ 13290 paged: 1, 13291 term: term 13292 }); 13293 this.ajaxLoader.load(this.unique); 13294 }, 13295 13296 inPage: function inPage(term) { 13297 var $filterItems = this.$container.find(this.config.item); 13298 $filterItems.removeClass('is-hidden'); // show all first 13299 // Replace all ', ' with ', .'. It's used to add '.' as class selector of each category. 13300 var className = term.replace( /, /g, ", ." ); 13301 if(term !== '*') $filterItems.not( '.' + className ).addClass('is-hidden'); // hide filtered 13302 MK.utils.eventManager.publish('staticFilter'); 13303 }, 13304 13305 onLoad: function onLoad(e, response) { 13306 if(this.config.mode === 'static') { 13307 this.$navItems.removeClass('current').first().addClass('current'); 13308 } 13309 if( typeof response !== 'undefined' && response.id === this.config.container) { 13310 MK.ui.loader.remove(this.$filter); 13311 if(response.unique === this.unique) { 13312 this.$container.html(response.content); 13313 this.ajaxLoader.setData({paged: 1}); 13314 } 13315 } 13316 } 13317 }; 13318 13319})(jQuery); 13320(function($) { 13321 'use strict'; 13322 13323 MK.component.Tabs = function( el ) { 13324 var defaults = { 13325 activeClass : 'is-active' 13326 }; 13327 13328 this.config = defaults; 13329 this.el = el; 13330 }; 13331 13332 MK.component.Tabs.prototype = { 13333 13334 init : function() { 13335 this.cacheElements(); 13336 this.bindEvents(); 13337 }, 13338 13339 cacheElements : function() { 13340 this.$this = $( this.el ); 13341 this.$tabs = this.$this.find( '.mk-tabs-tab' ); 13342 this.$panes = this.$this.find( '.mk-tabs-pane' ); 13343 this.currentId = 0; 13344 }, 13345 13346 bindEvents : function() { 13347 var self = this; 13348 13349 this.$tabs.on( 'click', this.switchPane.bind( this ) ); 13350 }, 13351 13352 switchPane : function( evt ) { 13353 evt.preventDefault(); 13354 13355 var clickedId = $( evt.currentTarget ).index(); 13356 13357 this.hide( this.currentId ); 13358 this.show( clickedId ); 13359 13360 // Update current id 13361 this.currentId = clickedId; 13362 13363 // Notify rest of the app 13364 MK.utils.eventManager.publish('item-expanded'); 13365 }, 13366 13367 show : function( id ) { 13368 this.$tabs.eq( id ).addClass( this.config.activeClass ); 13369 this.$panes.eq( id ).addClass( this.config.activeClass ); 13370 }, 13371 13372 hide : function( id ) { 13373 this.$tabs.eq( id ).removeClass( this.config.activeClass ); 13374 this.$panes.eq( id ).removeClass( this.config.activeClass ); 13375 } 13376 }; 13377 13378})(jQuery); 13379 13380 13381/* Tabs */ 13382/* -------------------------------------------------------------------- */ 13383 13384function mk_tabs() { 13385 13386 // "use strict"; 13387 13388 // if ($.exists('.mk-tabs, .mk-news-tab, .mk-woo-tabs')) { 13389 // $(".mk-tabs, .mk-news-tab, .mk-woo-tabs").tabs(); 13390 13391 // $('.mk-tabs').on('click', function () { 13392 // $('.mk-theme-loop').isotope('layout'); 13393 // }); 13394 13395 // $('.mk-tabs.vertical-style').each(function () { 13396 // $(this).find('.mk-tabs-pane').css('minHeight', $(this).find('.mk-tabs-tabs').height() - 1); 13397 // }); 13398 13399 // } 13400} 13401 13402function mk_tabs_responsive(){ 13403 // $('.mk-tabs, .mk-news-tab').each(function () { 13404 // $this = $(this); 13405 // if ($this.hasClass('mobile-true')) { 13406 // if (window.matchMedia('(max-width: 767px)').matches) 13407 // { 13408 // $this.tabs("destroy"); 13409 // } else { 13410 // $this.tabs(); 13411 // } 13412 // } 13413 // }); 13414 13415} 13416 13417 13418(function($) { 13419 'use strict'; 13420 13421 $(document).on('click', function(e) { 13422 $('.mk-toggle-trigger').removeClass('mk-toggle-active'); 13423 }); 13424 13425 function toggle(e) { 13426 e.preventDefault(); 13427 e.stopPropagation(); 13428 var $this = $(e.currentTarget); 13429 13430 if (!$this.hasClass('mk-toggle-active')) { 13431 13432 $('.mk-box-to-trigger').fadeOut(200); 13433 $this.parent().find('.mk-box-to-trigger').fadeIn(250); 13434 $('.mk-toggle-trigger').removeClass('mk-toggle-active'); 13435 $this.addClass('mk-toggle-active'); 13436 13437 } else { 13438 13439 $('.mk-box-to-trigger').fadeOut(200); 13440 $this.removeClass('mk-toggle-active'); 13441 13442 } 13443 } 13444 13445 function assignToggle() { 13446 // wait for ajax response propagation and insertion 13447 setTimeout(function() { 13448 $('.mk-toggle-trigger').off('click', toggle); 13449 $('.mk-toggle-trigger').on('click', toggle); 13450 }, 100); 13451 } 13452 13453 assignToggle(); 13454 MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle); 13455 MK.utils.eventManager.subscribe('ajax-preview', assignToggle); 13456 13457 $(window).on('vc_reload', function(){ 13458 assignToggle(); 13459 MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle); 13460 MK.utils.eventManager.subscribe('ajax-preview', assignToggle); 13461 }); 13462 13463}(jQuery)); 13464(function($) { 13465 'use strict'; 13466 13467 var $iframes = $('iframe'); 13468 13469 $iframes.each(function() { 13470 var $iframe = $(this); 13471 var parent = $iframe.parent().get(0); 13472 var tagName = parent.tagName; 13473 13474 if(tagName === 'P') $iframe.wrap('<div class="mk-video-container"></div>'); 13475 }); 13476 13477}(jQuery)); 13478(function( $ ) { 13479 'use strict'; 13480 13481 if( MK.utils.isMobile() ) { 13482 $('.mk-animate-element').removeClass('mk-animate-element'); 13483 return; 13484 } 13485
13486 var init = function init() { 13487 var $rootLevelEls = $('.js-master-row, .widget'); 13488 $rootLevelEls.each( spyViewport ); 13489 $rootLevelEls.each( function rootLevelEl() { 13490 var $animateEl = $(this).find( '.mk-animate-element' ); 13491 $animateEl.each( spyViewport ); 13492 }); 13493 }; 13494 13495 var spyViewport = function spyViewport(i) { 13496 var self = this; 13497 13498 MK.utils.scrollSpy( this, { 13499 position : 'bottom', 13500 threshold : 200, 13501 after : function() { 13502 animate.call(self, i); 13503 } 13504 }); 13505 }; 13506 13507 var animate = function animate(i) { 13508 var $this = $(this); 13509 13510 setTimeout(function() { 13511 $this.addClass( 'mk-in-viewport' ); 13512 }, 100 * i); 13513 }; 13514 13515 13516 $(window).on('load vc_reload', init); 13517 13518}(jQuery)); 13519function product_loop_add_cart() { 13520 var $body = $('body'); 13521 $body.on('click', '.add_to_cart_button', function() { 13522 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>'; 13523 var $holder = $(this).parents('.product:eq(0)'); 13524 var $i = $holder.find('.product-loading-icon'); 13525 $holder.addClass('adding-to-cart').removeClass('added-to-cart'); 13526 $i.html(icon); 13527 }); 13528 $body.bind('added_to_cart', function() { 13529 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>'; 13530 var $holder = $('.adding-to-cart'); 13531 var $i = $holder.find('.product-loading-icon'); 13532 $holder.removeClass('adding-to-cart').addClass('added-to-cart'); 13533 $i.html(icon); 13534 }); 13535} 13536(function($) { 13537 'use strict'; 13538 13539 /** 13540 * Entry point of application. Runs all components 13541 */ 13542 $( window ).on( 'load', function() { 13543 MK.core.initAll( document ); 13544 MK.utils.scrollToURLHash(); 13545 // TODO move preloader to components and manage it state from within 13546 setTimeout( function() { 13547 MK.ui.preloader.hide(); // site wide 13548 $('.mk-preloader').hide(); // components 13549 $('body').removeClass('loading'); 13550 }, 150 ); 13551 }); 13552 13553 /** 13554 * VC frontend editor. Init all components. 13555 */ 13556 $( window ).on( 'vc_reload', function() { 13557 setTimeout(function(){ 13558 MK.core.initAll( document ); 13559 }, 100); 13560 }); 13561 13562 /** 13563 * Assign global click handlers 13564 */ 13565 $( document ).on( 'click', '.js-smooth-scroll, .js-main-nav a', smoothScrollToAnchor); 13566 $( '.side_dashboard_menu a' ).on( 'click', smoothScrollToAnchor); 13567 13568 function smoothScrollToAnchor( evt ) { 13569 var anchor = MK.utils.detectAnchor( this ); 13570 var $this = $(evt.currentTarget); 13571 var loc = window.location; 13572 var currentPage = loc.origin + loc.pathname; 13573 var href = $this.attr( 'href' ); 13574 var linkSplit = (href) ? href.split( '#' ) : ''; 13575 var hrefPage = linkSplit[0] ? linkSplit[0] : ''; 13576 var hrefHash = linkSplit[1] ? linkSplit[1] : ''; 13577 13578 if( anchor.length ) { 13579 if(hrefPage === currentPage || hrefPage === '') evt.preventDefault(); 13580 MK.utils.scrollToAnchor( anchor ); 13581 13582 } else if( $this.attr( 'href' ) === '#' ) { 13583 evt.preventDefault(); 13584 } 13585 } 13586 13587}(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.