File "ai-insert.js"
Full Path: /home/refref/public_html/plugins-20250409180348/ad-inserter/includes/js/ai-insert.js
File size: 30.3 KB
MIME-type: text/plain
Charset: utf-8
if (typeof ai_insertion_js != 'undefined') {
ai_insert = function (insertion, selector, insertion_code) {
var ai_debug = typeof ai_debugging !== 'undefined'; // 1
// var ai_debug = false;
// if (selector.indexOf (':eq') != - 1) {
// ***
if (selector.indexOf (':eq(') != - 1) {
var jq = window.jQuery && window.jQuery.fn;
if (ai_debug) console.log ('AI INSERT USING jQuery QUERIES:', selector);
if (!jq) {
console.error ('AI INSERT USING jQuery QUERIES:', selector, '- jQuery not found');
return;
} else var elements = jQuery (selector);
} else var elements = document.querySelectorAll (selector);
// Array.prototype.forEach.call (elements, function (element, index) {
for (var index = 0, len = elements.length; index < len; index++) {
var element = elements [index];
if (element.hasAttribute ('id')) {
selector_string = '#' + element.getAttribute ('id');
} else
if (element.hasAttribute ('class')) {
selector_string = '.' + element.getAttribute ('class').replace (new RegExp (' ', 'g'), '.');
} else
selector_string = '';
if (ai_debug) console.log ('');
if (ai_debug) console.log ('AI INSERT', insertion, selector, '(' + element.tagName.toLowerCase() + selector_string + ')');
var template = document.createElement ('div');
template.innerHTML = insertion_code;
var ai_selector_counter = template.getElementsByClassName ("ai-selector-counter")[0];
if (ai_selector_counter != null) {
ai_selector_counter.innerText = index + 1;
}
var ai_debug_name_ai_main = template.getElementsByClassName ("ai-debug-name ai-main")[0];
if (ai_debug_name_ai_main != null) {
var insertion_name = insertion.toUpperCase ();
if (typeof ai_front != 'undefined') {
if (insertion == 'before') {
insertion_name = ai_front.insertion_before;
} else
if (insertion == 'after') {
insertion_name = ai_front.insertion_after;
} else
if (insertion == 'prepend') {
insertion_name = ai_front.insertion_prepend;
} else
if (insertion == 'append') {
insertion_name = ai_front.insertion_append;
} else
if (insertion == 'replace-content') {
insertion_name = ai_front.insertion_replace_content;
} else
if (insertion == 'replace-element') {
insertion_name = ai_front.insertion_replace_element;
}
}
if (selector_string.indexOf ('.ai-viewports') == - 1) {
ai_debug_name_ai_main.innerText = insertion_name + ' ' + selector + ' (' + element.tagName.toLowerCase() + selector_string + ')';
}
}
var range = document.createRange ();
var fragment_ok = true;
try {
var fragment = range.createContextualFragment (template.innerHTML);
}
catch (err) {
var fragment_ok = false;
if (ai_debug) console.log ('AI INSERT', 'range.createContextualFragment ERROR:', err.message);
}
if (insertion == 'before') {
// ***
// if (!fragment_ok) {
// jQuery (template.innerHTML).insertBefore (jQuery (element));
// } else
element.parentNode.insertBefore (fragment, element);
} else
if (insertion == 'after') {
// ***
// if (!fragment_ok) {
// jQuery (template.innerHTML).insertBefore (jQuery (element.nextSibling));
// } else
element.parentNode.insertBefore (fragment, element.nextSibling);
} else
if (insertion == 'prepend') {
// ***
// if (!fragment_ok) {
// jQuery (template.innerHTML).insertBefore (jQuery (element.firstChild));
// } else
element.insertBefore (fragment, element.firstChild);
} else
if (insertion == 'append') {
// ***
// if (!fragment_ok) {
// jQuery (template.innerHTML).appendTo (jQuery (element));
// } else
element.insertBefore (fragment, null);
} else
if (insertion == 'replace-content') {
element.innerHTML = '';
// ***
// if (!fragment_ok) {
// jQuery (template.innerHTML).appendTo (jQuery (element));
// } else
element.insertBefore (fragment, null);
} else
if (insertion == 'replace-element') {
// ***
// if (!fragment_ok) {
// jQuery (template.innerHTML).insertBefore (jQuery (element));
// } else
element.parentNode.insertBefore (fragment, element);
element.parentNode.removeChild (element);
}
// });
ai_process_elements ();
};
}
ai_insert_code = function (element) {
function hasClass (element, cls) {
if (element == null) return false;
if (element.classList) return element.classList.contains (cls); else
return (' ' + element.className + ' ').indexOf (' ' + cls + ' ') > - 1;
}
function addClass (element, cls) {
if (element == null) return;
if (element.classList) element.classList.add (cls); else
element.className += ' ' + cls;
}
function removeClass (element, cls) {
if (element == null) return;
if (element.classList) element.classList.remove (cls); else
element.className = element.className.replace (new RegExp ('(^|\\b)' + cls.split (' ').join ('|') + '(\\b|$)', 'gi'), ' ');
}
if (typeof element == 'undefined') return;
var insertion = false;
var ai_debug = typeof ai_debugging !== 'undefined'; // 2
// var ai_debug = false;
if (ai_debug) console.log ('AI INSERT ELEMENT class:', element.getAttribute ('class'));
if (hasClass (element, 'no-visibility-check')) {
var visible = true;
} else var visible = !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
if (ai_debug) {
var block = element.getAttribute ('data-block');
}
if (visible) {
if (ai_debug) console.log ('AI ELEMENT VISIBLE: block', block, 'offsetWidth:', element.offsetWidth, 'offsetHeight:', element.offsetHeight, 'getClientRects().length:', element.getClientRects().length);
var insertion_code = element.getAttribute ('data-code');
var insertion_type = element.getAttribute ('data-insertion-position');
var selector = element.getAttribute ('data-selector');
if (insertion_code != null) {
if (insertion_type != null && selector != null) {
// ***
if (selector.indexOf (':eq(') != - 1) {
var jq = window.jQuery && window.jQuery.fn;
if (jq) {
var selector_exists = jQuery (selector).length;
} else var selector_exists = false;
} else var selector_exists = document.querySelectorAll (selector).length;
if (ai_debug) console.log ('AI ELEMENT VISIBLE: block', block, insertion_type, selector, selector_exists ? '' : 'NOT FOUND');
if (selector_exists) {
ai_insert (insertion_type, selector, b64d (insertion_code));
removeClass (element, 'ai-viewports');
}
} else {
if (ai_debug) console.log ('AI ELEMENT VISIBLE: block', block);
var range = document.createRange ();
var fragment_ok = true;
try {
var fragment = range.createContextualFragment (b64d (insertion_code));
}
catch (err) {
var fragment_ok = false;
if (ai_debug) console.log ('AI INSERT NEXT', 'range.createContextualFragment ERROR:', err.message);
}
// ***
// if (!fragment_ok) {
// jQuery (b64d (insertion_code)).insertBefore (jQuery (element.nextSibling));
// } else
element.parentNode.insertBefore (fragment, element.nextSibling);
removeClass (element, 'ai-viewports');
}
}
insertion = true;
// Should not be removed here as it is needed for tracking - removed there
// var ai_check_block_data = element.getElementsByClassName ('ai-check-block');
// if (typeof ai_check_block_data [0] != 'undefined') {
// // Remove span
// ai_check_block_data [0].parentNode.removeChild (ai_check_block_data [0]);
// }
} else {
if (ai_debug) console.log ('AI ELEMENT NOT VISIBLE: block', block, 'offsetWidth:', element.offsetWidth, 'offsetHeight:', element.offsetHeight, 'getClientRects().length:', element.getClientRects().length);
var debug_bar = element.previousElementSibling;
if (hasClass (debug_bar, 'ai-debug-bar') && hasClass (debug_bar, 'ai-debug-script')) {
removeClass (debug_bar, 'ai-debug-script');
addClass (debug_bar, 'ai-debug-viewport-invisible');
}
removeClass (element, 'ai-viewports');
}
return insertion;
}
ai_insert_list_code = function (id) {
var ai_block_div = document.getElementsByClassName (id) [0];
if (typeof ai_block_div != 'undefined') {
var inserted = ai_insert_code (ai_block_div);
var wrapping_div = ai_block_div.closest ('div.' + ai_block_class_def);
if (wrapping_div) {
if (!inserted) {
wrapping_div.removeAttribute ('data-ai');
}
var debug_block = wrapping_div.querySelectorAll ('.ai-debug-block');
if (wrapping_div && debug_block.length) {
wrapping_div.classList.remove ('ai-list-block');
wrapping_div.classList.remove ('ai-list-block-ip');
wrapping_div.classList.remove ('ai-list-block-filter');
wrapping_div.style.visibility = '';
if (wrapping_div.classList.contains ('ai-remove-position')) {
wrapping_div.style.position = '';
}
}
}
ai_block_div.classList.remove (id);
if (inserted) ai_process_elements ();
}
}
ai_insert_viewport_code = function (id) {
var ai_block_div = document.getElementsByClassName (id) [0];
if (typeof ai_block_div != 'undefined') {
var inserted = ai_insert_code (ai_block_div);
ai_block_div.classList.remove (id);
if (inserted) {
var wrapping_div = ai_block_div.closest ('div.' + ai_block_class_def);
if (wrapping_div != null) {
var viewport_style = ai_block_div.getAttribute ('style');
if (viewport_style != null) {
wrapping_div.setAttribute ('style', wrapping_div.getAttribute ('style') + ' ' + viewport_style);
}
}
}
setTimeout (function () {
ai_block_div.removeAttribute ('style');
}, 2);
ai_process_elements ();
}
}
ai_insert_adsense_fallback_codes = function (adsense_unfilled_ins) {
var ai_debug = typeof ai_debugging !== 'undefined'; // 3
// var ai_debug = false;
adsense_unfilled_ins.style.display = "none";
var fallback_wrapper = adsense_unfilled_ins.closest ('.ai-fallback-adsense');
var fallback_div = fallback_wrapper.nextElementSibling;
if (!!fallback_div.getAttribute ('data-code')) {
var inserted = ai_insert_code (fallback_div);
if (inserted) {
ai_process_elements ();
}
} else {
fallback_div.style.display = "block";
}
if (fallback_wrapper.classList.contains ('ai-empty-code') && adsense_unfilled_ins.closest ('.' + ai_block_class_def) != null) {
var label_div = adsense_unfilled_ins.closest ('.' + ai_block_class_def).getElementsByClassName ('code-block-label');
if (label_div.length != 0) {
label_div [0].style.display = "none";
}
}
if (ai_debug) {
console.log ('AI FALLBACK ADSENSE UNFILLED:', adsense_unfilled_ins.closest ('.' + ai_block_class_def) != null ? adsense_unfilled_ins.closest ('.' + ai_block_class_def).classList.value : '', !!fallback_div.getAttribute ('data-code') ? 'INSERT' : 'SHOW');
}
}
//ai_insert_fallback_codes = function () {
// var ai_debug = typeof ai_debugging !== 'undefined'; // 3
//// var ai_debug = false;
// var ai_fallback_divs = document.getElementsByClassName ('ai-fallback-adsense');
// var fallback_check = ai_fallback_divs.length;
// if (ai_debug && fallback_check) {
// console.log ('');
// console.log ('AI FALLBACK CHECK ADSENSE:', ai_fallback_divs.length, 'block' + (ai_fallback_divs.length == 1 ? '' : 's')) ;
// }
// for (var adsense = 0; adsense < ai_fallback_divs.length; adsense ++) {
// var adsense_div = ai_fallback_divs [adsense];
// var adsense_unfilled_ins = adsense_div.querySelector ('ins.adsbygoogle[data-ad-status="filled"]');
// if (!!adsense_unfilled_ins) {
// adsense_unfilled_ins.style.display = "none";
// var fallback_div = adsense_div.nextElementSibling;
// var insert = !!fallback_div.getAttribute ('data-code');
// if (insert) {
// if (ai_debug) {
// var block = fallback_div.getAttribute ('data-block');
// console.log ('AI INSERT FALLBACK CODE FOR BLOCK', block);
// }
// var inserted = ai_insert_code (fallback_div);
// if (inserted) {
// ai_process_elements ();
// }
// } else {
// if (ai_debug) {
// var block = fallback_div.getAttribute ('data-block');
// console.log ('AI SHOW FALLBACK CODE FOR BLOCK', block);
// }
// fallback_div.style.display = "block";
// }
// }
// }
// if (ai_debug && fallback_check) {
// console.log ('');
// }
//}
ai_insert_code_by_class = function (id) {
var ai_block_div = document.getElementsByClassName (id) [0];
if (typeof ai_block_div != 'undefined') {
ai_insert_code (ai_block_div);
ai_block_div.classList.remove (id);
}
}
ai_insert_client_code = function (id, len) {
var ai_debug = typeof ai_debugging !== 'undefined'; // 4
// var ai_debug = false;
var ai_block_div = document.getElementsByClassName (id) [0];
if (ai_debug) {
var block = ai_block_div.getAttribute ('data-block');
console.log ('AI INSERT PROTECTED BLOCK', block, '.' + id);
}
if (typeof ai_block_div != 'undefined') {
var insertion_code = ai_block_div.getAttribute ('data-code');
// if (insertion_code != null && ai_check_block () && ai_check_and_insert_block ()) {
if (insertion_code != null && ai_check_block () /*&& ai_check_and_insert_block ()*/) {
ai_block_div.setAttribute ('data-code', insertion_code.substring (Math.floor (len / 19)));
ai_insert_code_by_class (id);
ai_block_div.remove();
}
}
}
ai_process_elements_active = false;
function ai_process_elements () {
if (!ai_process_elements_active)
setTimeout (function() {
ai_process_elements_active = false;
if (typeof ai_process_rotations == 'function') {
ai_process_rotations ();
}
if (typeof ai_process_lists == 'function') {
// ***
// ai_process_lists (jQuery (".ai-list-data"));
ai_process_lists ();
}
if (typeof ai_process_ip_addresses == 'function') {
// ***
// ai_process_ip_addresses (jQuery (".ai-ip-data"));
ai_process_ip_addresses ();
}
if (typeof ai_process_filter_hooks == 'function') {
// ***
// ai_process_filter_hooks (jQuery (".ai-filter-check"));
ai_process_filter_hooks ();
}
if (typeof ai_adb_process_blocks == 'function') {
ai_adb_process_blocks ();
}
if (typeof ai_process_impressions == 'function' && ai_tracking_finished == true) {
ai_process_impressions ();
}
if (typeof ai_install_click_trackers == 'function' && ai_tracking_finished == true) {
ai_install_click_trackers ();
}
if (typeof ai_install_close_buttons == 'function') {
ai_install_close_buttons (document);
}
if (typeof ai_process_wait_for_interaction == 'function') {
ai_process_wait_for_interaction ();
}
if (typeof ai_process_delayed_blocks == 'function') {
ai_process_delayed_blocks ();
}
}, 5);
ai_process_elements_active = true;
}
const targetNode = document.querySelector ('body');
const config = {attributes: true, childList: false, subtree: true};
const ai_adsense_callback = function (mutationsList, observer) {
// Use traditional 'for loops' for IE 11
for (const mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName == 'data-ad-status' && mutation.target.dataset.adStatus == 'unfilled' && !!mutation.target.closest ('.ai-fallback-adsense')) {
ai_insert_adsense_fallback_codes (mutation.target);
}
}
};
const observer = new MutationObserver (ai_adsense_callback);
observer.observe (targetNode, config);
// Later, we can stop observing
//observer.disconnect();
/*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");
}
if ($) {
exposeApi($.fn);
}
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, typeof jQuery === 'undefined' ? null : jQuery, undefined);
}