Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Essentials - Deferred
- *
- * A handy tool for organizing waiting for something.
- *
- * @version 0.0.4
- *
- *
- * @author a.porohnya@gmail.com (Aleksey Porokhnya)
- */
- ;(function() {
- var Deferred, PENDING, REJECTED, RESOLVED, after, execute, flatten, has, isArguments, isPromise, wrap, _when, _reduce,
- __slice = [].slice, _forEach;
- PENDING = "pending";
- RESOLVED = "resolved";
- REJECTED = "rejected";
- _forEach = function(callback) {
- for (var i = 0; this.length > i; i++) {
- callback.call(this, this[i], i, this);
- }
- }
- _reduce = function(callback /*, initialValue*/) {
- if (null === this || 'undefined' === typeof this) {
- throw new TypeError('_reduce called on null or undefined');
- }
- if ('function' !== typeof callback) {
- throw new TypeError(callback + ' is not a function');
- }
- var t = Object(this), len = t.length >>> 0, k = 0, value;
- if (arguments.length >= 2) {
- value = arguments[1];
- } else {
- while (k < len && ! k in t) k++;
- if (k >= len)
- throw new TypeError('Reduce of empty array with no initial value');
- value = t[k++];
- }
- for (; k < len; k++) {
- if (k in t) {
- value = callback(value, t[k], k, t);
- }
- }
- return value;
- };
- if (!Array.isArray) {
- Array.isArray = function(arg) {
- return Object.prototype.toString.call(arg) === '[object Array]';
- };
- }
- has = function(obj, prop) {
- return obj != null ? obj.hasOwnProperty(prop) : void 0;
- };
- isArguments = function(obj) {
- return has(obj, 'length') && has(obj, 'callee');
- };
- isPromise = function(obj) {
- return has(obj, 'promise') && typeof (obj != null ? obj.promise : void 0) === 'function';
- };
- flatten = function(array) {
- if (isArguments(array)) {
- return flatten(Array.prototype.slice.call(array));
- }
- if (!Array.isArray(array)) {
- return [array];
- }
- return _reduce.call(array, function(memo, value) {
- if (Array.isArray(value)) {
- return memo.concat(flatten(value));
- }
- memo.push(value);
- return memo;
- }, []);
- };
- after = function(times, func) {
- if (times <= 0) {
- return func();
- }
- return function() {
- if (--times < 1) {
- return func.apply(this, arguments);
- }
- };
- };
- wrap = function(func, wrapper) {
- return function() {
- var args;
- args = [func].concat(Array.prototype.slice.call(arguments, 0));
- return wrapper.apply(this, args);
- };
- };
- execute = function(callbacks, args, context) {
- var callback, _i, _len, _ref, _results;
- _ref = flatten(callbacks);
- _results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- callback = _ref[_i];
- if (Object.prototype.toString.call(args) !== '[object Arguments]' && args.length === undefined) {
- args.length = 0;
- }
- _results.push(callback.call.apply(callback, [context].concat(__slice.call(args))));
- }
- return _results;
- };
- /**
- * @name Deferred
- * @namespace
- * @returns {Deferred}
- * @constructor
- */
- Deferred = function() {
- var candidate, close, closingArguments, doneCallbacks, failCallbacks, progressCallbacks, state;
- state = PENDING;
- doneCallbacks = [];
- failCallbacks = [];
- progressCallbacks = [];
- closingArguments = {
- 'resolved': {},
- 'rejected': {},
- 'pending': {}
- };
- /**
- * Promise Object
- *
- * @type {Promise}
- * @param candidate
- * @returns {{}}
- */
- this.promise = function(candidate) {
- var pipe, storeCallbacks;
- candidate = candidate || {};
- candidate.state = function() {
- return state;
- };
- storeCallbacks = function(shouldExecuteImmediately, holder, holderState) {
- return function() {
- if (state === PENDING) {
- holder.push.apply(holder, flatten(arguments));
- }
- if (shouldExecuteImmediately()) {
- execute(arguments, closingArguments[holderState]);
- }
- return candidate;
- };
- };
- candidate.done = storeCallbacks((function() {
- return state === RESOLVED;
- }), doneCallbacks, RESOLVED);
- candidate.fail = storeCallbacks((function() {
- return state === REJECTED;
- }), failCallbacks, REJECTED);
- candidate.progress = storeCallbacks((function() {
- return state !== PENDING;
- }), progressCallbacks, PENDING);
- candidate.always = function() {
- var _ref;
- return (_ref = candidate.done.apply(candidate, arguments)).fail.apply(_ref, arguments);
- };
- pipe = function(doneFilter, failFilter, progressFilter) {
- var filter, master;
- master = new Deferred();
- filter = function(source, funnel, callback) {
- if (!callback) {
- return candidate[source](master[funnel]);
- }
- return candidate[source](function() {
- var args, value;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- value = callback.apply(null, args);
- if (isPromise(value)) {
- return value.done(master.resolve).fail(master.reject).progress(master.notify);
- } else {
- return master[funnel](value);
- }
- });
- };
- filter('done', 'resolve', doneFilter);
- filter('fail', 'reject', failFilter);
- filter('progress', 'notify', progressFilter);
- return master;
- };
- candidate.pipe = pipe;
- candidate.then = pipe;
- if (candidate.promise == null) {
- candidate.promise = function() {
- return candidate;
- };
- }
- return candidate;
- };
- this.promise(this);
- candidate = this;
- close = function(finalState, callbacks, context) {
- return function() {
- if (state === PENDING) {
- state = finalState;
- closingArguments[finalState] = arguments;
- execute(callbacks, closingArguments[finalState], context);
- return candidate;
- }
- return this;
- };
- };
- this.resolve = close(RESOLVED, doneCallbacks);
- this.reject = close(REJECTED, failCallbacks);
- this.notify = close(PENDING, progressCallbacks);
- this.resolveWith = function(context, args) {
- return close(RESOLVED, doneCallbacks, context).apply(null, args);
- };
- this.rejectWith = function(context, args) {
- return close(REJECTED, failCallbacks, context).apply(null, args);
- };
- this.notifyWith = function(context, args) {
- return close(PENDING, progressCallbacks, context).apply(null, args);
- };
- return this;
- };
- /**
- * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events.
- *
- * @returns {Promise}
- * @private
- */
- _when = function() {
- var def, defs, finish, resolutionArgs, trigger, _i, _len;
- defs = flatten(arguments);
- if (defs.length === 1) {
- if (isPromise(defs[0])) {
- return defs[0];
- } else {
- return (new Deferred()).resolve(defs[0]).promise();
- }
- }
- trigger = new Deferred();
- if (!defs.length) {
- return trigger.resolve().promise();
- }
- resolutionArgs = [];
- finish = after(defs.length, function() {
- return trigger.resolve.apply(trigger, resolutionArgs);
- });
- _forEach.call(defs, function(def, index) {
- if (isPromise(def)) {
- return def.done(function() {
- var args;
- args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
- resolutionArgs[index] = args.length > 1 ? args : args[0];
- return finish();
- });
- } else {
- resolutionArgs[index] = def;
- return finish();
- }
- });
- for (_i = 0, _len = defs.length; _i < _len; _i++) {
- def = defs[_i];
- isPromise(def) && def.fail(trigger.reject);
- }
- return trigger.promise();
- };
- /**
- * Returns new Deferred object
- *
- * @returns {Deferred}
- * @constructor
- */
- mmcore.Deferred = function () {
- return new Deferred();
- };
- mmcore.when = _when;
- }).call(this);
- /**
- * Essentials - Wait for
- *
- * A handy tool for organizing waiting for something.
- *
- * @version 0.1.0
- *
- * @requires mmcore.Deffered
- *
- * @author evgeniy@pavlyuk.me (Evgeniy Pavlyuk), a.porohnya@gmail.com (Aleksey Porokhnya)
- */
- (function() {
- 'use strict';
- /**
- * A handy tool for organizing waiting for something.
- *
- * @param {function(this:!mmcore.Deferred):boolean} checker A function that controls the state of the waiting.
- * @param {!Object=} options Optional settings:
- * initializer {function(this:mmcore.Deferred)} A function that is called before the first check.
- * interval {number} Delay (in milliseconds) between the checks.
- * isNotPeriodicallyChecked {boolean} Is the check not called periodically, but only once?
- * isNotStoppedOnDocumentReadiness {boolean} Is the waiting not stopped when the document gets ready and the
- * waiting is incomplete?
- * timeout {number} A period of time (in milliseconds) after which the waiting fails.
- *
- * @return {!mmcore.Deferred#Promise} The promise of the waiting.
- *
- * @example
- * // Periodically check for the client jQuery arrival.
- * mmcore.waitFor(function() {
- * // Successfully complete the waiting when the client jQuery arrives.
- * // The waiting stops if the client jQuery does not arrive when the document gets ready.
- * return (typeof jQuery === 'function');
- * }).done(function() {
- * // The client jQuery has arrived.
- * }).fail(function() {
- * // The client jQuery has not been arrived when the document got ready.
- * });
- *
- * @example
- * // Periodically check for the client jQuery arrival.
- * mmcore.waitFor(function() {
- * // The checker has direct access to the deferred object, so the waiting can be completed by hand.
- * // It gives more control over the waiting, and allows to complete the waiting with custom arguments.
- * if (typeof jQuery === 'function') {
- * this.resolve(jQuery);
- * }
- * }).done(function(jQuery) {
- * // The client jQuery has arrived.
- * });
- */
- mmcore.waitFor = function(checker, options) {
- var check;
- var waiting;
- // Manages the state of the event that is expected to happen.
- // Learn more at http://api.jquery.com/category/deferred-object/
- waiting = mmcore.Deferred();
- // The handy method is used instead of copying and pasting the check below.
- waiting.isComplete = function() {
- return (waiting.state() !== 'pending');
- };
- // Extend the default options with the given ones (if any).
- options = options || {};
- options.interval = options.interval || 50;
- options.isNotStoppedOnDocumentReadiness = options.isNotStoppedOnDocumentReadiness|| false;
- options.isNotPeriodicallyChecked = options.isNotPeriodicallyChecked || false;
- // Calls the checker.
- // If not prevented by isNotPeriodicallyChecked option, provides periodical calling of itself.
- // If not prevented by isNotStoppedOnDocumentReadiness option, stops the waiting if it is not complete when the
- // document is ready.
- check = function() {
- if (waiting.isComplete()) {
- return;
- }
- // Successfully completes waiting if the checker returns true.
- // Note, that the checker has direct access to the deferred object, so the waiting can be completed in the checker
- // by calling resolve or reject method of the deferred object.
- // Checking for the return value is done to provide an easy and comfortable way to complete the waiting from the
- // checker.
- if (checker.call(waiting)) {
- waiting.resolve();
- }
- if (waiting.isComplete()) {
- return;
- }
- if (!options.isNotStoppedOnDocumentReadiness
- && ((mmcore.$ && mmcore.$.isReady) || (!mmcore.$ && document.readyState === "complete"))) {
- // Stop the waiting if it is incomplete when the document is ready.
- waiting.reject();
- } else if (!options.isNotPeriodicallyChecked) {
- // Provide periodical calling of the checking function.
- setTimeout(check, options.interval);
- }
- };
- // If there is the initializer function, call it before the first check.
- if (options.hasOwnProperty('initializer')) {
- options.initializer.call(waiting);
- }
- check();
- if (!waiting.isComplete()) {
- if (options.hasOwnProperty('timeout')) {
- // Stop checking after the specified period of time.
- (function() {
- var timeoutId = setTimeout(waiting.reject, options.timeout);
- waiting.always(function() {
- clearTimeout(timeoutId);
- });
- }());
- }
- if (!options.isNotStoppedOnDocumentReadiness) {
- if (!options.isNotPeriodicallyChecked) {
- // If the checker is periodically called, and the waiting stops if it is incomplete when the document is
- // ready, call the checker for the last time exactly at the moment when the document gets ready.
- mmcore.AddDocLoadHandler(check);
- //$(document).ready(check);
- } else {
- // If the checker is not called periodically, but only once, stop the waiting when the document gets ready.
- mmcore.AddDocLoadHandler(waiting.reject);
- //$(document).ready(waiting.reject);
- }
- }
- }
- return waiting.promise();
- };
- }());
- /**
- * Maxymiser Core - Campaign
- *
- * Campaign constructor that provides basic functionality for campaign development.
- *
- * @version 0.3.4
- *
- * @requires mmcore.Deferred
- * @requires mmcore.tryCatch
- * @requires mmcore.AttachStyle
- *
- * @author evgeniy.pavlyuk@maxymiser.com (Evgeniy Pavlyuk)
- * @author andrey.ponamarev@maxymiser.com (Andrey Ponamarev)
- * @author aleksey.porokhnya@maxymiser.com (Aleksey Porokhnya)
- */
- (function() {
- 'use strict';
- /**
- * @type {Campaign}
- */
- mmcore.Campaign = Campaign;
- /**
- * @param {*} itemToCheck
- * @param {Array} arr
- * @returns {boolean}
- */
- function inArray(itemToCheck, arr) {
- var inArray = false;
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] === itemToCheck) {
- inArray = true;
- }
- }
- return inArray;
- }
- /**
- *
- * @param elems
- * @param callback
- * @param inv
- * @returns {Array}
- */
- var grep = function( elems, callback, inv) {
- var retVal,
- ret = [],
- i = 0,
- length = elems.length;
- inv = !!inv;
- // Go through the array, only saving the items
- // that pass the validator function
- for ( ; i < length; i++ ) {
- retVal = !!callback( elems[ i ], i );
- if ( inv !== retVal ) {
- ret.push( elems[ i ] );
- }
- }
- return ret;
- }
- /**
- * Campaign constructor that provides basic functionality for campaign development. *
- * Documentation https://bitbucket.org/gamingteam/essentials-campaign
- *
- *
- * @name Campaign
- * @namespace
- * @constructor
- *
- * @param {string} name Campaign name from the UI.
- * @param {!Array.<string>} maxyboxNames Names of campaign elements from the UI.
- * @param {string} prefix Prefix with campaign type and number, for example, mt1.
- */
- function Campaign(name, maxyboxNames, prefix) {
- /**
- * Campaign name.
- * @type {string}
- */
- this.name = name;
- /**
- * Names of campaign elements.
- * @type {!Array.<string>}
- */
- this.maxyboxNames = maxyboxNames;
- /**
- * Campaign type and number prefix.
- * @type {string}
- */
- this.prefix = prefix;
- this.preventDefaultRendering();
- this.preventDefaultHiding();
- }
- /**
- * Marks the campaign elements as rendered.
- */
- Campaign.prototype.preventDefaultRendering = function() {
- /* jshint -W106 */
- var states = mmcore._r_mbs;
- /* jshint +W106 */
- var maxyBoxes = this.maxyboxNames;
- var l = maxyBoxes.length;
- while(l--){
- states[maxyBoxes[l]] = 1;
- }
- };
- /**
- * Excludes the campaign elements from arguments of `mmcore.HideMaxyboxes` when it's called.
- */
- Campaign.prototype.preventDefaultHiding = function() {
- var campaign = this;
- mmcore.HideMaxyboxes = (function(hideMaxyboxes) {
- return function() {
- var maxyboxNames = arguments;
- mmcore.tryCatch(function() {
- maxyboxNames = grep(maxyboxNames, function(maxyboxName) {
- return (inArray(maxyboxName, campaign.maxyboxNames));
- });
- })();
- if (maxyboxNames.length) {
- return hideMaxyboxes.apply(this, maxyboxNames);
- }
- };
- }(mmcore.HideMaxyboxes));
- mmcore._MbStyle = function () {};
- };
- /**
- * Hides content by selector.
- *
- * @param {string|Array.<string>} selector CSS selector(s).
- * @param {string=} hidingStyle Optional CSS to be applied to the selector.
- * If ommited, the content is hidden through absolute positioning.
- */
- Campaign.prototype.hideContent = function(selector, hidingStyle) {
- var hidingClass;
- var hidingSelectorStyle;
- var countSelectors;
- var hidingSelectors;
- var htmlTag = document.getElementsByTagName('html')[0];
- var htmlClass = htmlTag.getAttribute('class');
- var styleStr = '';
- var isEmpty = function(obj) {
- if (obj == null) return true;
- if (obj.length > 0) return false;
- if (obj.length === 0) return true;
- for (var key in obj) {
- if (hasOwnProperty.call(obj, key)) return false;
- }
- return true;
- };
- this.hidingClass = this.prefix + '-hidden-content';
- // Add Class to html
- htmlClass = (htmlClass !== null && htmlClass === '') ? this.hidingClass : htmlClass + ' ' + this.hidingClass;
- htmlTag.setAttribute('class', htmlClass);
- if (arguments.length < 2) {
- hidingStyle = 'left: -33554430px; position: absolute; top: -33554430px;';
- }
- hidingClass = this.hidingClass;
- if ({}.toString.call(selector) === '[object Object]' && !isEmpty(selector)) {
- for (var key in selector) {
- styleStr += ' .' + hidingClass + ' ' + key + '{' + selector[key] + '}';
- }
- mmcore.AttachStyle(styleStr);
- return;
- }
- hidingSelectors = selector.split(',');
- countSelectors = hidingSelectors.length;
- hidingSelectorStyle = '';
- while(countSelectors--){
- hidingSelectorStyle += '.' + hidingClass + ' ' + hidingSelectors[countSelectors] + '{' +
- hidingStyle +
- '}'
- }
- mmcore.AttachStyle(hidingSelectorStyle);
- };
- /**
- * Shows the content previously hidden by `Campaign.prototype.hideContent`.
- */
- Campaign.prototype.showContent = function() {
- if (this.hasOwnProperty('hidingClass')) {
- var htmlTag = document.getElementsByTagName('html')[0];
- var htmlClass = htmlTag.getAttribute('class');
- if(htmlClass !== null && htmlClass !== ''){
- htmlClass = htmlClass.replace(this.hidingClass, '');
- htmlTag.setAttribute('class', htmlClass);
- }
- }
- };
- /**
- * Returns generated experience of this campaign from GenInfo
- *
- * @returns {Object}
- */
- Campaign.prototype.getExperience = function() {
- // Assume that an own property of mmcore.GenInfo reference to a unique object.
- return mmcore.GenInfo.hasOwnProperty(this.name) ?
- mmcore.GenInfo[this.name] : null;
- };
- /**
- * Returns true if campaign has non default experience
- *
- * @return {boolean}
- */
- Campaign.prototype.hasNonDefaultExperience = function() {
- var experience, hasNonDefaultExperience;
- experience = this.getExperience();
- if (!experience) {
- return false;
- }
- hasNonDefaultExperience = false;
- for(var key in experience){
- if (experience.hasOwnProperty(key) &&
- (experience[key] !== 'Default')) {
- hasNonDefaultExperience = true;
- break;
- }
- }
- return hasNonDefaultExperience;
- };
- /**
- * @return {boolean}
- * @deprecated Use hasNonDefaultExperience() instead.
- */
- Campaign.prototype.hasMaxybox = function() {
- return this.hasNonDefaultExperience();
- };
- /**
- * Extending method for campaign
- *
- * @param {Object} obj
- */
- Campaign.prototype.extend = function extend(obj) {
- for(var prop in obj)
- this[prop] = obj[prop];
- return this;
- },
- /**
- * Render all or specific campaign maxyboxes.
- * this in a variant script references to the campaign.
- */
- Campaign.prototype.renderMaxyboxes = function() {
- var campaign;
- var maxyboxNames;
- var key;
- maxyboxNames = this.maxyboxNames;
- if (arguments.length) {
- maxyboxNames = grep(arguments, function(maxyboxName) {
- return !inArray(maxyboxName, maxyboxNames);
- });
- }
- campaign = this;
- for(key in mmcore._renderers){
- if(inArray(key, maxyboxNames) && typeof mmcore._renderers[key] === 'function'){
- mmcore._renderers[key].call(campaign);
- }
- }
- };
- }());
- /**
- * Maxymiser Core - Request
- *
- * A handy wrap around `mmcore.CGRequest`.
- *
- * @version 0.1.0
- *
- * @requires mmcore.jQuery
- * @requires mmcore.tryCatch
- *
- * @author evgeniy.pavlyuk@maxymiser.com (Evgeniy Pavlyuk)
- */
- (function() {
- 'use strict';
- var $ = mmcore.jQuery;
- var ACTION_TRACKING_PAGE_ID = 'event';
- var REQUEST_TIMEOUT = 2250; // In milliseconds.
- var followingRequest;
- var prepareFollowingRequest = function() {
- followingRequest = $.Deferred();
- mmcore.request.promise = followingRequest.promise();
- };
- /**
- * @param {string=} pageId If not sepcified, `event` is asssumed.
- * @param {boolean=} isSynchronous If not specified, the request will be asynchronous.
- * @return {!Object} Promise.
- */
- mmcore.request = function(pageId, isSynchronous) {
- var request = followingRequest;
- prepareFollowingRequest();
- if (!arguments.length) {
- pageId = ACTION_TRACKING_PAGE_ID;
- }
- mmcore.SetPageID(pageId);
- mmcore._async = !isSynchronous;
- mmcore.CGRequest(request.resolve); // Callback is called in a try block in a response.
- setTimeout(mmcore.tryCatch(request.reject), REQUEST_TIMEOUT);
- return request.promise();
- };
- prepareFollowingRequest();
- }());
- /**
- * Maxymiser Essentials - Mediator
- *
- *
- * Makes `mmcore` act as a mediator.
- * Provides `mmcore.mediator`
- *
- * @version 0.1.3
- *
- *
- * @author porokhnya.aleksey@maxymiser.com (Porokhnya Aleksey)
- */
- ;(function () {
- 'use strict';
- // We'll generate guids for class instances for easy referencing later on.
- // Subscriber instances will have an id that can be refernced for quick
- // lookups.
- function guidGenerator() {
- var S4 = function() {
- return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
- };
- return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
- }
- /**
- * Subscribers are instances of Mediator Channel registrations. We generate
- * an object instance so that it can be updated later on without having to
- * unregister and re-register. Subscribers are constructed with a function
- * to be called, options object, and context.
- *
- * @name Subscriber
- * @namespace
- *
- * @param {Function} fn
- * @param {Object} options
- * @param {Object} context
- * @returns {Subscriber}
- * @constructor
- */
- function Subscriber(fn, options, context){
- if(!(this instanceof Subscriber)) {
- return new Subscriber(fn, options, context);
- }
- this.id = guidGenerator();
- this.fn = fn;
- this.options = options;
- this.context = context;
- this.channel = null;
- }
- Subscriber.prototype = {
- /**
- * Mediator.update on a subscriber instance can update its function,context,
- * or options object. It takes in an object and looks for fn, context, or options keys.
- *
- * @param {Object} options
- */
- update: function(options){
- if(options){
- this.fn = options.fn || this.fn;
- this.context = options.context || this.context;
- this.options = options.options || this.options;
- if(this.channel && this.options && this.options.priority !== undefined) {
- this.channel.setPriority(this.id, this.options.priority);
- }
- }
- }
- };
- /**
- * @name Channel
- * @namespace
- * @param {String} namespace
- * @param {Channel} parent
- * @returns {Channel}
- * @constructor
- */
- function Channel(namespace, parent){
- if(!(this instanceof Channel)) {
- return new Channel(namespace);
- }
- this.namespace = namespace || "";
- this._subscribers = [];
- this._channels = [];
- this._parent = parent;
- this.stopped = false;
- }
- // A Mediator channel holds a list of sub-channels and subscribers to be fired
- // when Mediator.publish is called on the Mediator instance. It also contains
- // some methods to manipulate its lists of data; only setPriority and
- // StopPropagation are meant to be used. The other methods should be accessed
- // through the Mediator instance.
- Channel.prototype = {
- addSubscriber: function(fn, options, context){
- var subscriber = new Subscriber(fn, options, context);
- if(options && options.priority !== undefined){
- // Cheap hack to either parse as an int or turn it into 0. Runs faster
- // in many browsers than parseInt with the benefit that it won't
- // return a NaN.
- options.priority = options.priority >> 0;
- if(options.priority < 0){ options.priority = 0; }
- if(options.priority >= this._subscribers.length){ options.priority = this._subscribers.length-1; }
- this._subscribers.splice(options.priority, 0, subscriber);
- }else{
- this._subscribers.push(subscriber);
- }
- subscriber.channel = this;
- return subscriber;
- },
- // The channel instance is passed as an argument to the mediator subscriber,
- // and further subscriber propagation can be called with
- // channel.StopPropagation().
- stopPropagation: function(){
- this.stopped = true;
- },
- getSubscriber: function(identifier){
- var x = 0,
- y = this._subscribers.length;
- for(x, y; x < y; x++){
- if(this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
- return this._subscribers[x];
- }
- }
- },
- // Channel.setPriority is useful in updating the order in which Subscribers
- // are called, and takes an identifier (subscriber id or named function) and
- // an array index. It will not search recursively through subchannels.
- setPriority: function(identifier, priority){
- var oldIndex = 0,
- x = 0,
- sub, firstHalf, lastHalf, y;
- for(x = 0, y = this._subscribers.length; x < y; x++){
- if(this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
- break;
- }
- oldIndex ++;
- }
- sub = this._subscribers[oldIndex];
- firstHalf = this._subscribers.slice(0, oldIndex);
- lastHalf = this._subscribers.slice(oldIndex+1);
- this._subscribers = firstHalf.concat(lastHalf);
- this._subscribers.splice(priority, 0, sub);
- },
- addChannel: function(channel){
- this._channels[channel] = new Channel((this.namespace ? this.namespace + ':' : '') + channel, this);
- },
- hasChannel: function(channel){
- return this._channels.hasOwnProperty(channel);
- },
- returnChannel: function(channel){
- return this._channels[channel];
- },
- removeSubscriber: function(identifier){
- var x = this._subscribers.length - 1;
- // If we don't pass in an id, we're clearing all
- if(!identifier){
- this._subscribers = [];
- return;
- }
- // Going backwards makes splicing a whole lot easier.
- for(x; x >= 0; x--) {
- if(this._subscribers[x].fn === identifier || this._subscribers[x].id === identifier){
- this._subscribers[x].channel = null;
- this._subscribers.splice(x,1);
- }
- }
- },
- // This will publish arbitrary arguments to a subscriber and then to parent
- // channels.
- publish: function(data){
- var x = 0,
- y = this._subscribers.length,
- called = false,
- subscriber, l,
- subsBefore,subsAfter;
- // Priority is preserved in the _subscribers index.
- for(x, y; x < y; x++) {
- called = false;
- if(!this.stopped){
- subscriber = this._subscribers[x];
- if(subscriber.options !== undefined && typeof subscriber.options.predicate === "function"){
- if(subscriber.options.predicate.apply(subscriber.context, data)){
- subscriber.fn.apply(subscriber.context, data);
- called = true;
- }
- }else{
- subsBefore = this._subscribers.length;
- subscriber.fn.apply(subscriber.context, data);
- subsAfter = this._subscribers.length;
- y = subsAfter;
- if (subsAfter === subsBefore - 1){
- x--;
- }
- called = true;
- }
- }
- if(called && subscriber.options && subscriber.options !== undefined){
- subscriber.options.calls--;
- if(subscriber.options.calls < 1){
- this.removeSubscriber(subscriber.id);
- y--;
- x--;
- }
- }
- }
- if(this._parent){
- this._parent.publish(data);
- }
- this.stopped = false;
- }
- };
- /**
- * Mediator object
- *
- * @returns {Mediator}
- * @constructor
- */
- function Mediator() {
- if(!(this instanceof Mediator)) {
- return new Mediator();
- }
- this._channels = new Channel('');
- }
- // A Mediator instance is the interface through which events are registered
- // and removed from publish channels.
- Mediator.prototype = {
- /**
- * Returns a channel instance based on namespace
- * for example application:chat:message:received
- *
- * @param {string} namespace
- * @returns {Array|_channels|*}
- */
- getChannel: function(namespace){
- var channel = this._channels,
- namespaceHierarchy = namespace.split(':'),
- x = 0,
- y = namespaceHierarchy.length;
- if(namespace === ''){
- return channel;
- }
- if(namespaceHierarchy.length > 0){
- for(x, y; x < y; x++){
- if(!channel.hasChannel(namespaceHierarchy[x])){
- channel.addChannel(namespaceHierarchy[x]);
- }
- channel = channel.returnChannel(namespaceHierarchy[x]);
- }
- }
- return channel;
- },
- /**
- * Pass in a channel namespace, function to be called, options, and context
- * to call the function in to Subscribe. It will create a channel if one
- * does not exist. Options can include a predicate to determine if it
- * should be called (based on the data published to it) and a priority index.
- *
- * @param {String} channelName
- * @param {Function} fn
- * @param {Object} options
- * @param {Object} context
- * @returns {Subscriber}
- */
- subscribe: function(channelName, fn, options, context){
- var channel = this.getChannel(channelName);
- options = options || {};
- context = context || {};
- return channel.addSubscriber(fn, options, context);
- },
- /**
- * Pass in a channel namespace, function to be called, options, and context
- * to call the function in to Subscribe. It will create a channel if one
- * does not exist. Options can include a predicate to determine if it
- * should be called (based on the data published to it) and a priority index
- *
- * @param {String} channelName
- * @param {Function} fn
- * @param {Object} options
- * @param {Object} context
- * @returns {Subscriber}
- */
- once: function(channelName, fn, options, context){
- options = options || {};
- options.calls = 1;
- return this.subscribe(channelName, fn, options, context);
- },
- /**
- * Returns a subscriber for a given subscriber id / named function and channel namespace
- *
- * @param {String} identifier
- * @param {String} channel name
- * @returns {Subscriber}
- */
- getSubscriber: function(identifier, channel){
- return this.getChannel(channel || "").getSubscriber(identifier);
- },
- /**
- * Remove a subscriber from a given channel namespace recursively based on
- * a passed-in subscriber id or named function.
- *
- * @param {String} channelName
- * @param {String} identifier
- */
- remove: function(channelName, identifier){
- this.getChannel(channelName).removeSubscriber(identifier);
- },
- /**
- * Publishes arbitrary data to a given channel namespace. Channels are
- * called recursively downwards; a post to application:chat will post to
- * application:chat:receive and application:chat:derp:test:beta:bananas.
- * Called using Mediator.publish("application:chat", [ args ]);
- *
- * @param {String} channelName
- */
- publish: function(channelName){
- var args = Array.prototype.slice.call(arguments, 1),
- channel = this.getChannel(channelName);
- args.push(channel);
- this.getChannel(channelName).publish(args);
- }
- };
- /**
- * Alias for Mediator.subscribe (See "subscribe" method)
- * @type {Function}
- */
- Mediator.prototype.on = Mediator.prototype.subscribe;
- /**
- * Alias for Mediator.subscribe (See "subscribe" method)
- * @type {Function}
- */
- Mediator.prototype.bind = Mediator.prototype.subscribe;
- /**
- * Alias for Mediator.subscribe (See "publish" method)
- * @type {Function}
- */
- Mediator.prototype.emit = Mediator.prototype.publish;
- /**
- * Alias for Mediator.subscribe (See "publish" method)
- * @type {Function}
- */
- Mediator.prototype.trigger = Mediator.prototype.publish;
- /**
- * Alias for Mediator.subscribe (See "publish" method)
- * @type {Function}
- */
- Mediator.prototype.fire = Mediator.prototype.publish;
- /**
- * Alias for Mediator.subscribe (See "remove" method)
- * @type {Function}
- */
- Mediator.prototype.off = Mediator.prototype.remove;
- // Finally, expose it all.
- Mediator.Channel = Channel;
- Mediator.Subscriber = Subscriber;
- /**
- * Mediator instance
- * more information at: https://bitbucket.org/gamingteam/essentials-mediator
- *
- * @type {Mediator}
- */
- mmcore.mediator = new Mediator();
- } ());
- ;(function() {
- /**
- * Maxymiser Core - OnNotRefresh
- *
- * Method which is used to add halders for non refresh load of page
- *
- * @version 0.1.0
- *
- * @param {function} func Function which will be called if page hasnt been refreshed (there is no cookie which is seted on unload event)
- * @param {string} [suffix] Cookie suffix which used to identify which page where unloaded recently (default value is 'default')
- * @param {number} [sec] Cookie lifetime in seconds (default value is 3)
- *
- * @author titus.kovalenko@maxymiser.com (Titus Kovalenko)
- */
- var onNotRefresh = function(func, suffix, sec) {
- suffix = suffix || 'default';
- sec = sec || 3;
- if (!mmcore.GetCookie('mm_refresh_' + suffix, 1)) {
- func();
- }
- window.onunload = (function (original) {
- return function() {
- var result;
- mmcore.SetCookie('mm_refresh_' + suffix, 1, sec / (24 * 60 * 60), 1);
- if (original) {
- result = original.apply(this, arguments)
- };
- return result;
- }
- })(window.onunload);
- }
- mmcore.onNotRefresh = onNotRefresh;
- })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement