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