702 lines
33 KiB
JavaScript
702 lines
33 KiB
JavaScript
|
/*globals jQuery,Window,HTMLElement,HTMLDocument,HTMLCollection,NodeList,MutationObserver */
|
||
|
/*exported Arrive*/
|
||
|
/*jshint latedef:false */
|
||
|
|
||
|
/*
|
||
|
* arrive.js
|
||
|
* v2.4.1
|
||
|
* https://github.com/uzairfarooq/arrive
|
||
|
* MIT licensed
|
||
|
*
|
||
|
* Copyright (c) 2014-2017 Uzair Farooq
|
||
|
*/
|
||
|
var Arrive = (function(window, $, undefined) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
if(!window.MutationObserver || typeof HTMLElement === 'undefined'){
|
||
|
return; //for unsupported browsers
|
||
|
}
|
||
|
|
||
|
var arriveUniqueId = 0;
|
||
|
|
||
|
var utils = (function() {
|
||
|
var matches = HTMLElement.prototype.matches || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector
|
||
|
|| HTMLElement.prototype.msMatchesSelector;
|
||
|
|
||
|
return {
|
||
|
matchesSelector: function(elem, selector) {
|
||
|
return elem instanceof HTMLElement && matches.call(elem, selector);
|
||
|
},
|
||
|
// to enable function overloading - By John Resig (MIT Licensed)
|
||
|
addMethod: function (object, name, fn) {
|
||
|
var old = object[ name ];
|
||
|
object[ name ] = function(){
|
||
|
if ( fn.length == arguments.length ) {
|
||
|
return fn.apply( this, arguments );
|
||
|
}
|
||
|
else if ( typeof old == 'function' ) {
|
||
|
return old.apply( this, arguments );
|
||
|
}
|
||
|
};
|
||
|
},
|
||
|
callCallbacks: function(callbacksToBeCalled, registrationData) {
|
||
|
if (registrationData && registrationData.options.onceOnly && registrationData.firedElems.length == 1) {
|
||
|
// as onlyOnce param is true, make sure we fire the event for only one item
|
||
|
callbacksToBeCalled = [callbacksToBeCalled[0]];
|
||
|
}
|
||
|
|
||
|
for (var i = 0, cb; (cb = callbacksToBeCalled[i]); i++) {
|
||
|
if (cb && cb.callback) {
|
||
|
cb.callback.call(cb.elem, cb.elem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (registrationData && registrationData.options.onceOnly && registrationData.firedElems.length == 1) {
|
||
|
// unbind event after first callback as onceOnly is true.
|
||
|
registrationData.me.unbindEventWithSelectorAndCallback.call(
|
||
|
registrationData.target, registrationData.selector, registrationData.callback
|
||
|
);
|
||
|
}
|
||
|
},
|
||
|
// traverse through all descendants of a node to check if event should be fired for any descendant
|
||
|
checkChildNodesRecursively: function(nodes, registrationData, matchFunc, callbacksToBeCalled) {
|
||
|
// check each new node if it matches the selector
|
||
|
for (var i=0, node; (node = nodes[i]); i++) {
|
||
|
if (matchFunc(node, registrationData, callbacksToBeCalled)) {
|
||
|
callbacksToBeCalled.push({ callback: registrationData.callback, elem: node });
|
||
|
}
|
||
|
|
||
|
if (node.childNodes.length > 0) {
|
||
|
utils.checkChildNodesRecursively(node.childNodes, registrationData, matchFunc, callbacksToBeCalled);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
mergeArrays: function(firstArr, secondArr){
|
||
|
// Overwrites default options with user-defined options.
|
||
|
var options = {},
|
||
|
attrName;
|
||
|
for (attrName in firstArr) {
|
||
|
if (firstArr.hasOwnProperty(attrName)) {
|
||
|
options[attrName] = firstArr[attrName];
|
||
|
}
|
||
|
}
|
||
|
for (attrName in secondArr) {
|
||
|
if (secondArr.hasOwnProperty(attrName)) {
|
||
|
options[attrName] = secondArr[attrName];
|
||
|
}
|
||
|
}
|
||
|
return options;
|
||
|
},
|
||
|
toElementsArray: function (elements) {
|
||
|
// check if object is an array (or array like object)
|
||
|
// Note: window object has .length property but it's not array of elements so don't consider it an array
|
||
|
if (typeof elements !== 'undefined' && (typeof elements.length !== 'number' || elements === window)) {
|
||
|
elements = [elements];
|
||
|
}
|
||
|
return elements;
|
||
|
}
|
||
|
};
|
||
|
})();
|
||
|
|
||
|
|
||
|
// Class to maintain state of all registered events of a single type
|
||
|
var EventsBucket = (function() {
|
||
|
var EventsBucket = function() {
|
||
|
// holds all the events
|
||
|
|
||
|
this._eventsBucket = [];
|
||
|
// function to be called while adding an event, the function should do the event initialization/registration
|
||
|
this._beforeAdding = null;
|
||
|
// function to be called while removing an event, the function should do the event destruction
|
||
|
this._beforeRemoving = null;
|
||
|
};
|
||
|
|
||
|
EventsBucket.prototype.addEvent = function(target, selector, options, callback) {
|
||
|
var newEvent = {
|
||
|
target: target,
|
||
|
selector: selector,
|
||
|
options: options,
|
||
|
callback: callback,
|
||
|
firedElems: []
|
||
|
};
|
||
|
|
||
|
if (this._beforeAdding) {
|
||
|
this._beforeAdding(newEvent);
|
||
|
}
|
||
|
|
||
|
this._eventsBucket.push(newEvent);
|
||
|
return newEvent;
|
||
|
};
|
||
|
|
||
|
EventsBucket.prototype.removeEvent = function(compareFunction) {
|
||
|
for (var i=this._eventsBucket.length - 1, registeredEvent; (registeredEvent = this._eventsBucket[i]); i--) {
|
||
|
if (compareFunction(registeredEvent)) {
|
||
|
if (this._beforeRemoving) {
|
||
|
this._beforeRemoving(registeredEvent);
|
||
|
}
|
||
|
|
||
|
// mark callback as null so that even if an event mutation was already triggered it does not call callback
|
||
|
var removedEvents = this._eventsBucket.splice(i, 1);
|
||
|
if (removedEvents && removedEvents.length) {
|
||
|
removedEvents[0].callback = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
EventsBucket.prototype.beforeAdding = function(beforeAdding) {
|
||
|
this._beforeAdding = beforeAdding;
|
||
|
};
|
||
|
|
||
|
EventsBucket.prototype.beforeRemoving = function(beforeRemoving) {
|
||
|
this._beforeRemoving = beforeRemoving;
|
||
|
};
|
||
|
|
||
|
return EventsBucket;
|
||
|
})();
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @constructor
|
||
|
* General class for binding/unbinding arrive and leave events
|
||
|
*/
|
||
|
var MutationEvents = function(getObserverConfig, onMutation) {
|
||
|
var eventsBucket = new EventsBucket(),
|
||
|
me = this;
|
||
|
|
||
|
var defaultOptions = {
|
||
|
fireOnAttributesModification: false
|
||
|
};
|
||
|
|
||
|
// actual event registration before adding it to bucket
|
||
|
eventsBucket.beforeAdding(function(registrationData) {
|
||
|
var
|
||
|
target = registrationData.target,
|
||
|
observer;
|
||
|
|
||
|
// mutation observer does not work on window or document
|
||
|
if (target === window.document || target === window) {
|
||
|
target = document.getElementsByTagName("html")[0];
|
||
|
}
|
||
|
|
||
|
// Create an observer instance
|
||
|
observer = new MutationObserver(function(e) {
|
||
|
onMutation.call(this, e, registrationData);
|
||
|
});
|
||
|
|
||
|
var config = getObserverConfig(registrationData.options);
|
||
|
|
||
|
observer.observe(target, config);
|
||
|
|
||
|
registrationData.observer = observer;
|
||
|
registrationData.me = me;
|
||
|
});
|
||
|
|
||
|
// cleanup/unregister before removing an event
|
||
|
eventsBucket.beforeRemoving(function (eventData) {
|
||
|
eventData.observer.disconnect();
|
||
|
});
|
||
|
|
||
|
this.bindEvent = function(selector, options, callback) {
|
||
|
options = utils.mergeArrays(defaultOptions, options);
|
||
|
|
||
|
var elements = utils.toElementsArray(this);
|
||
|
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
eventsBucket.addEvent(elements[i], selector, options, callback);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
this.unbindEvent = function() {
|
||
|
var elements = utils.toElementsArray(this);
|
||
|
eventsBucket.removeEvent(function(eventObj) {
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
if (this === undefined || eventObj.target === elements[i]) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
this.unbindEventWithSelectorOrCallback = function(selector) {
|
||
|
var elements = utils.toElementsArray(this),
|
||
|
callback = selector,
|
||
|
compareFunction;
|
||
|
|
||
|
if (typeof selector === "function") {
|
||
|
compareFunction = function(eventObj) {
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
if ((this === undefined || eventObj.target === elements[i]) && eventObj.callback === callback) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
}
|
||
|
else {
|
||
|
compareFunction = function(eventObj) {
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
if ((this === undefined || eventObj.target === elements[i]) && eventObj.selector === selector) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
}
|
||
|
eventsBucket.removeEvent(compareFunction);
|
||
|
};
|
||
|
|
||
|
this.unbindEventWithSelectorAndCallback = function(selector, callback) {
|
||
|
var elements = utils.toElementsArray(this);
|
||
|
eventsBucket.removeEvent(function(eventObj) {
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
if ((this === undefined || eventObj.target === elements[i]) && eventObj.selector === selector && eventObj.callback === callback) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @constructor
|
||
|
* Processes 'arrive' events
|
||
|
*/
|
||
|
var ArriveEvents = function() {
|
||
|
// Default options for 'arrive' event
|
||
|
var arriveDefaultOptions = {
|
||
|
fireOnAttributesModification: false,
|
||
|
onceOnly: false,
|
||
|
existing: false
|
||
|
};
|
||
|
|
||
|
function getArriveObserverConfig(options) {
|
||
|
var config = {
|
||
|
attributes: false,
|
||
|
childList: true,
|
||
|
subtree: true
|
||
|
};
|
||
|
|
||
|
if (options.fireOnAttributesModification) {
|
||
|
config.attributes = true;
|
||
|
}
|
||
|
|
||
|
return config;
|
||
|
}
|
||
|
|
||
|
function onArriveMutation(mutations, registrationData) {
|
||
|
mutations.forEach(function( mutation ) {
|
||
|
var newNodes = mutation.addedNodes,
|
||
|
targetNode = mutation.target,
|
||
|
callbacksToBeCalled = [],
|
||
|
node;
|
||
|
|
||
|
// If new nodes are added
|
||
|
if( newNodes !== null && newNodes.length > 0 ) {
|
||
|
utils.checkChildNodesRecursively(newNodes, registrationData, nodeMatchFunc, callbacksToBeCalled);
|
||
|
}
|
||
|
else if (mutation.type === "attributes") {
|
||
|
if (nodeMatchFunc(targetNode, registrationData, callbacksToBeCalled)) {
|
||
|
callbacksToBeCalled.push({ callback: registrationData.callback, elem: targetNode });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
utils.callCallbacks(callbacksToBeCalled, registrationData);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function nodeMatchFunc(node, registrationData, callbacksToBeCalled) {
|
||
|
// check a single node to see if it matches the selector
|
||
|
if (utils.matchesSelector(node, registrationData.selector)) {
|
||
|
if(node._id === undefined) {
|
||
|
node._id = arriveUniqueId++;
|
||
|
}
|
||
|
// make sure the arrive event is not already fired for the element
|
||
|
if (registrationData.firedElems.indexOf(node._id) == -1) {
|
||
|
registrationData.firedElems.push(node._id);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
arriveEvents = new MutationEvents(getArriveObserverConfig, onArriveMutation);
|
||
|
|
||
|
var mutationBindEvent = arriveEvents.bindEvent;
|
||
|
|
||
|
// override bindEvent function
|
||
|
arriveEvents.bindEvent = function(selector, options, callback) {
|
||
|
|
||
|
if (typeof callback === "undefined") {
|
||
|
callback = options;
|
||
|
options = arriveDefaultOptions;
|
||
|
} else {
|
||
|
options = utils.mergeArrays(arriveDefaultOptions, options);
|
||
|
}
|
||
|
|
||
|
var elements = utils.toElementsArray(this);
|
||
|
|
||
|
if (options.existing) {
|
||
|
var existing = [];
|
||
|
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
var nodes = elements[i].querySelectorAll(selector);
|
||
|
for (var j = 0; j < nodes.length; j++) {
|
||
|
existing.push({ callback: callback, elem: nodes[j] });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// no need to bind event if the callback has to be fired only once and we have already found the element
|
||
|
if (options.onceOnly && existing.length) {
|
||
|
return callback.call(existing[0].elem, existing[0].elem);
|
||
|
}
|
||
|
|
||
|
setTimeout(utils.callCallbacks, 1, existing);
|
||
|
}
|
||
|
|
||
|
mutationBindEvent.call(this, selector, options, callback);
|
||
|
};
|
||
|
|
||
|
return arriveEvents;
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @constructor
|
||
|
* Processes 'leave' events
|
||
|
*/
|
||
|
var LeaveEvents = function() {
|
||
|
// Default options for 'leave' event
|
||
|
var leaveDefaultOptions = {};
|
||
|
|
||
|
function getLeaveObserverConfig() {
|
||
|
var config = {
|
||
|
childList: true,
|
||
|
subtree: true
|
||
|
};
|
||
|
|
||
|
return config;
|
||
|
}
|
||
|
|
||
|
function onLeaveMutation(mutations, registrationData) {
|
||
|
mutations.forEach(function( mutation ) {
|
||
|
var removedNodes = mutation.removedNodes,
|
||
|
callbacksToBeCalled = [];
|
||
|
|
||
|
if( removedNodes !== null && removedNodes.length > 0 ) {
|
||
|
utils.checkChildNodesRecursively(removedNodes, registrationData, nodeMatchFunc, callbacksToBeCalled);
|
||
|
}
|
||
|
|
||
|
utils.callCallbacks(callbacksToBeCalled, registrationData);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function nodeMatchFunc(node, registrationData) {
|
||
|
return utils.matchesSelector(node, registrationData.selector);
|
||
|
}
|
||
|
|
||
|
leaveEvents = new MutationEvents(getLeaveObserverConfig, onLeaveMutation);
|
||
|
|
||
|
var mutationBindEvent = leaveEvents.bindEvent;
|
||
|
|
||
|
// override bindEvent function
|
||
|
leaveEvents.bindEvent = function(selector, options, callback) {
|
||
|
|
||
|
if (typeof callback === "undefined") {
|
||
|
callback = options;
|
||
|
options = leaveDefaultOptions;
|
||
|
} else {
|
||
|
options = utils.mergeArrays(leaveDefaultOptions, options);
|
||
|
}
|
||
|
|
||
|
mutationBindEvent.call(this, selector, options, callback);
|
||
|
};
|
||
|
|
||
|
return leaveEvents;
|
||
|
};
|
||
|
|
||
|
|
||
|
var arriveEvents = new ArriveEvents(),
|
||
|
leaveEvents = new LeaveEvents();
|
||
|
|
||
|
function exposeUnbindApi(eventObj, exposeTo, funcName) {
|
||
|
// expose unbind function with function overriding
|
||
|
utils.addMethod(exposeTo, funcName, eventObj.unbindEvent);
|
||
|
utils.addMethod(exposeTo, funcName, eventObj.unbindEventWithSelectorOrCallback);
|
||
|
utils.addMethod(exposeTo, funcName, eventObj.unbindEventWithSelectorAndCallback);
|
||
|
}
|
||
|
|
||
|
/*** expose APIs ***/
|
||
|
function exposeApi(exposeTo) {
|
||
|
exposeTo.arrive = arriveEvents.bindEvent;
|
||
|
exposeUnbindApi(arriveEvents, exposeTo, "unbindArrive");
|
||
|
|
||
|
exposeTo.leave = leaveEvents.bindEvent;
|
||
|
exposeUnbindApi(leaveEvents, exposeTo, "unbindLeave");
|
||
|
}
|
||
|
|
||
|
exposeApi(HTMLElement.prototype);
|
||
|
exposeApi(NodeList.prototype);
|
||
|
exposeApi(HTMLCollection.prototype);
|
||
|
exposeApi(HTMLDocument.prototype);
|
||
|
exposeApi(Window.prototype);
|
||
|
|
||
|
var Arrive = {};
|
||
|
// expose functions to unbind all arrive/leave events
|
||
|
exposeUnbindApi(arriveEvents, Arrive, "unbindAllArrive");
|
||
|
exposeUnbindApi(leaveEvents, Arrive, "unbindAllLeave");
|
||
|
|
||
|
return Arrive;
|
||
|
|
||
|
})(window, null, undefined);
|
||
|
|
||
|
var ewww_webp_supported = false;
|
||
|
// webp detection adapted from https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_using_javascript
|
||
|
function check_webp_feature(feature, callback) {
|
||
|
if (ewww_webp_supported) {
|
||
|
callback(ewww_webp_supported);
|
||
|
return;
|
||
|
}
|
||
|
var kTestImages = {
|
||
|
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
||
|
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
|
||
|
};
|
||
|
var img = new Image();
|
||
|
img.onload = function () {
|
||
|
ewww_webp_supported = (img.width > 0) && (img.height > 0);
|
||
|
callback(ewww_webp_supported);
|
||
|
};
|
||
|
img.onerror = function () {
|
||
|
callback(false);
|
||
|
};
|
||
|
img.src = "data:image/webp;base64," + kTestImages[feature];
|
||
|
}
|
||
|
function ewwwLoadImages(ewww_webp_supported) {
|
||
|
if (ewww_webp_supported) {
|
||
|
var nggImages = document.querySelectorAll('.batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a');
|
||
|
for (var i = 0, len = nggImages.length; i < len; i++){
|
||
|
ewwwAttr(nggImages[i], 'data-src', nggImages[i].getAttribute('data-webp'));
|
||
|
ewwwAttr(nggImages[i], 'data-thumbnail', nggImages[i].getAttribute('data-webp-thumbnail'));
|
||
|
}
|
||
|
var revImages = document.querySelectorAll('.rev_slider ul li');
|
||
|
for (var i = 0, len = revImages.length; i < len; i++){
|
||
|
ewwwAttr(revImages[i], 'data-thumb', revImages[i].getAttribute('data-webp-thumb'));
|
||
|
var param_num = 1;
|
||
|
while ( param_num < 11 ) {
|
||
|
ewwwAttr(revImages[i], 'data-param' + param_num, revImages[i].getAttribute('data-webp-param' + param_num));
|
||
|
param_num++;
|
||
|
}
|
||
|
}
|
||
|
var revImages = document.querySelectorAll('.rev_slider img');
|
||
|
for (var i = 0, len = revImages.length; i < len; i++){
|
||
|
ewwwAttr(revImages[i], 'data-lazyload', revImages[i].getAttribute('data-webp-lazyload'));
|
||
|
}
|
||
|
var wooImages = document.querySelectorAll('div.woocommerce-product-gallery__image');
|
||
|
for (var i = 0, len = wooImages.length; i < len; i++){
|
||
|
ewwwAttr(wooImages[i], 'data-thumb', wooImages[i].getAttribute('data-webp-thumb'));
|
||
|
}
|
||
|
}
|
||
|
var videos = document.querySelectorAll('video');
|
||
|
for (var i = 0, len = videos.length; i < len; i++){
|
||
|
if (ewww_webp_supported) {
|
||
|
ewwwAttr(videos[i], 'poster', videos[i].getAttribute('data-poster-webp'));
|
||
|
} else {
|
||
|
ewwwAttr(videos[i], 'poster', videos[i].getAttribute('data-poster-image'));
|
||
|
}
|
||
|
}
|
||
|
var lazies = document.querySelectorAll('img.ewww_webp_lazy_load');
|
||
|
for (var i = 0, len = lazies.length; i < len; i++){
|
||
|
console.log('parsing an image: ' + lazies[i].getAttribute('data-src'));
|
||
|
if (ewww_webp_supported) {
|
||
|
console.log('webp good');
|
||
|
ewwwAttr(lazies[i], 'data-lazy-srcset', lazies[i].getAttribute('data-lazy-srcset-webp'));
|
||
|
ewwwAttr(lazies[i], 'data-srcset', lazies[i].getAttribute('data-srcset-webp'));
|
||
|
ewwwAttr(lazies[i], 'data-lazy-src', lazies[i].getAttribute('data-lazy-src-webp'));
|
||
|
ewwwAttr(lazies[i], 'data-src', lazies[i].getAttribute('data-src-webp'));
|
||
|
ewwwAttr(lazies[i], 'data-orig-file', lazies[i].getAttribute('data-webp-orig-file'));
|
||
|
ewwwAttr(lazies[i], 'data-medium-file', lazies[i].getAttribute('data-webp-medium-file'));
|
||
|
ewwwAttr(lazies[i], 'data-large-file', lazies[i].getAttribute('data-webp-large-file'));
|
||
|
var jpsrcset = lazies[i].getAttribute('srcset');
|
||
|
if (jpsrcset != null && jpsrcset !== false && jpsrcset.includes('R0lGOD')) {
|
||
|
ewwwAttr(lazies[i], 'src', lazies[i].getAttribute('data-lazy-src-webp'));
|
||
|
}
|
||
|
}
|
||
|
lazies[i].className = lazies[i].className.replace(/\bewww_webp_lazy_load\b/, '');
|
||
|
}
|
||
|
var elems = document.querySelectorAll('.ewww_webp');
|
||
|
for (var i = 0, len = elems.length; i < len; i++){
|
||
|
console.log('parsing an image: ' + elems[i].getAttribute('data-src'));
|
||
|
if (ewww_webp_supported) {
|
||
|
ewwwAttr(elems[i], 'srcset', elems[i].getAttribute('data-srcset-webp'));
|
||
|
ewwwAttr(elems[i], 'src', elems[i].getAttribute('data-src-webp'));
|
||
|
ewwwAttr(elems[i], 'data-orig-file', elems[i].getAttribute('data-webp-orig-file'));
|
||
|
ewwwAttr(elems[i], 'data-medium-file', elems[i].getAttribute('data-webp-medium-file'));
|
||
|
ewwwAttr(elems[i], 'data-large-file', elems[i].getAttribute('data-webp-large-file'));
|
||
|
ewwwAttr(elems[i], 'data-large_image', elems[i].getAttribute('data-webp-large_image'));
|
||
|
ewwwAttr(elems[i], 'data-src', elems[i].getAttribute('data-webp-src'));
|
||
|
} else {
|
||
|
ewwwAttr(elems[i], 'srcset', elems[i].getAttribute('data-srcset-img'));
|
||
|
ewwwAttr(elems[i], 'src', elems[i].getAttribute('data-src-img'));
|
||
|
}
|
||
|
elems[i].className = elems[i].className.replace(/\bewww_webp\b/, 'ewww_webp_loaded');
|
||
|
}
|
||
|
if (window.jQuery && jQuery.fn.isotope && jQuery.fn.imagesLoaded) {
|
||
|
jQuery('.fusion-posts-container-infinite').imagesLoaded( function() {
|
||
|
if ( jQuery( '.fusion-posts-container-infinite' ).hasClass( 'isotope' ) ) {
|
||
|
jQuery( '.fusion-posts-container-infinite' ).isotope();
|
||
|
}
|
||
|
});
|
||
|
jQuery('.fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper').imagesLoaded( function() {
|
||
|
jQuery( '.fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper' ).isotope();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
check_webp_feature('alpha', ewwwWebPInit);
|
||
|
function ewwwWebPInit(ewww_webp_supported) {
|
||
|
ewwwLoadImages(ewww_webp_supported);
|
||
|
ewwwNggLoadGalleries(ewww_webp_supported);
|
||
|
document.arrive('.ewww_webp', function() {
|
||
|
ewwwLoadImages(ewww_webp_supported);
|
||
|
});
|
||
|
document.arrive('.ewww_webp_lazy_load', function() {
|
||
|
ewwwLoadImages(ewww_webp_supported);
|
||
|
});
|
||
|
document.arrive('videos', function() {
|
||
|
ewwwLoadImages(ewww_webp_supported);
|
||
|
});
|
||
|
if (document.readyState == 'loading') {
|
||
|
console.log('deferring ewwwJSONParserInit until DOMContentLoaded')
|
||
|
document.addEventListener('DOMContentLoaded', ewwwJSONParserInit);
|
||
|
} else {
|
||
|
console.log(document.readyState);
|
||
|
console.log('running JSON parsers post haste')
|
||
|
if ( typeof galleries !== 'undefined' ) {
|
||
|
console.log('galleries found, parsing')
|
||
|
ewwwNggParseGalleries(ewww_webp_supported);
|
||
|
}
|
||
|
ewwwWooParseVariations(ewww_webp_supported);
|
||
|
}
|
||
|
}
|
||
|
function ewwwAttr(elem, attr, value) {
|
||
|
if (value != null && value !== false) {
|
||
|
elem.setAttribute(attr, value);
|
||
|
}
|
||
|
}
|
||
|
function ewwwJSONParserInit() {
|
||
|
if ( typeof galleries !== 'undefined' ) {
|
||
|
check_webp_feature('alpha', ewwwNggParseGalleries);
|
||
|
}
|
||
|
check_webp_feature('alpha', ewwwWooParseVariations);
|
||
|
}
|
||
|
function ewwwWooParseVariations(ewww_webp_supported) {
|
||
|
if (!ewww_webp_supported) {
|
||
|
return;
|
||
|
}
|
||
|
var elems = document.querySelectorAll('form.variations_form');
|
||
|
for (var i = 0, len = elems.length; i < len; i++){
|
||
|
var variations = elems[i].getAttribute('data-product_variations');
|
||
|
var variations_changed = false;
|
||
|
try {
|
||
|
variations = JSON.parse(variations);
|
||
|
//console.log(variations);
|
||
|
console.log('parsing WC variations');
|
||
|
for ( var num in variations ) {
|
||
|
if (variations[ num ] !== undefined && variations[ num ].image !== undefined) {
|
||
|
console.log(variations[num].image);
|
||
|
if (variations[num].image.src_webp !== undefined) {
|
||
|
variations[num].image.src = variations[num].image.src_webp;
|
||
|
variations_changed = true;
|
||
|
}
|
||
|
if (variations[num].image.srcset_webp !== undefined) {
|
||
|
variations[num].image.srcset = variations[num].image.srcset_webp;
|
||
|
variations_changed = true;
|
||
|
}
|
||
|
if (variations[num].image.full_src_webp !== undefined) {
|
||
|
variations[num].image.full_src = variations[num].image.full_src_webp;
|
||
|
variations_changed = true;
|
||
|
}
|
||
|
if (variations[num].image.gallery_thumbnail_src_webp !== undefined) {
|
||
|
variations[num].image.gallery_thumbnail_src = variations[num].image.gallery_thumbnail_src_webp;
|
||
|
variations_changed = true;
|
||
|
}
|
||
|
if (variations[num].image.thumb_src_webp !== undefined) {
|
||
|
variations[num].image.thumb_src = variations[num].image.thumb_src_webp;
|
||
|
variations_changed = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (variations_changed) {
|
||
|
ewwwAttr(elems[i], 'data-product_variations', JSON.stringify(variations));
|
||
|
}
|
||
|
} catch (err) {
|
||
|
console.log(err);
|
||
|
console.log(response);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function ewwwNggParseGalleries(ewww_webp_supported) {
|
||
|
if (ewww_webp_supported) {
|
||
|
for(var galleryIndex in galleries) {
|
||
|
var gallery = galleries[galleryIndex];
|
||
|
galleries[galleryIndex].images_list = ewwwNggParseImageList(gallery.images_list);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function ewwwNggLoadGalleries(ewww_webp_supported) {
|
||
|
if (ewww_webp_supported) {
|
||
|
document.addEventListener('ngg.galleria.themeadded', function(event, themename){
|
||
|
window.ngg_galleria._create_backup = window.ngg_galleria.create;
|
||
|
window.ngg_galleria.create = function(gallery_parent, themename) {
|
||
|
var gallery_id = $(gallery_parent).data('id');
|
||
|
galleries['gallery_' + gallery_id].images_list = ewwwNggParseImageList(galleries['gallery_' + gallery_id].images_list);
|
||
|
return window.ngg_galleria._create_backup(gallery_parent, themename);
|
||
|
};
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
function ewwwNggParseImageList(images_list) {
|
||
|
console.log('parsing gallery images');
|
||
|
for(var nggIndex in images_list) {
|
||
|
var nggImage = images_list[nggIndex];
|
||
|
if (typeof nggImage['image-webp'] !== typeof undefined) {
|
||
|
images_list[nggIndex]['image'] = nggImage['image-webp'];
|
||
|
delete images_list[nggIndex]['image-webp'];
|
||
|
}
|
||
|
if (typeof nggImage['thumb-webp'] !== typeof undefined) {
|
||
|
images_list[nggIndex]['thumb'] = nggImage['thumb-webp'];
|
||
|
delete images_list[nggIndex]['thumb-webp'];
|
||
|
}
|
||
|
if (typeof nggImage['full_image_webp'] !== typeof undefined) {
|
||
|
images_list[nggIndex]['full_image'] = nggImage['full_image_webp'];
|
||
|
delete images_list[nggIndex]['full_image_webp'];
|
||
|
}
|
||
|
if (typeof nggImage['srcsets'] !== typeof undefined) {
|
||
|
for(var nggSrcsetIndex in nggImage['srcsets']) {
|
||
|
nggSrcset = nggImage['srcsets'][nggSrcsetIndex];
|
||
|
if (typeof nggImage['srcsets'][nggSrcsetIndex + '-webp'] !== typeof undefined) {
|
||
|
images_list[nggIndex]['srcsets'][nggSrcsetIndex] = nggImage['srcsets'][nggSrcsetIndex + '-webp'];
|
||
|
delete images_list[nggIndex]['srcsets'][nggSrcsetIndex + '-webp'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (typeof nggImage['full_srcsets'] !== typeof undefined) {
|
||
|
for(var nggFSrcsetIndex in nggImage['full_srcsets']) {
|
||
|
nggFSrcset = nggImage['full_srcsets'][nggFSrcsetIndex];
|
||
|
if (typeof nggImage['full_srcsets'][nggFSrcsetIndex + '-webp'] !== typeof undefined) {
|
||
|
images_list[nggIndex]['full_srcsets'][nggFSrcsetIndex] = nggImage['full_srcsets'][nggFSrcsetIndex + '-webp'];
|
||
|
delete images_list[nggIndex]['full_srcsets'][nggFSrcsetIndex + '-webp'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return images_list;
|
||
|
}
|