Advertisement
Guest User

Untitled

a guest
Jul 29th, 2015
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Essentials - Deferred
  3.  *
  4.  * A handy tool for organizing waiting for something.
  5.  *
  6.  * @version 0.0.4
  7.  *
  8.  *
  9.  * @author a.porohnya@gmail.com (Aleksey Porokhnya)
  10.  */
  11. ;(function() {
  12.     var Deferred, PENDING, REJECTED, RESOLVED, after, execute, flatten, has, isArguments, isPromise, wrap, _when, _reduce,
  13.         __slice = [].slice, _forEach;
  14.  
  15.     PENDING = "pending";
  16.  
  17.     RESOLVED = "resolved";
  18.  
  19.     REJECTED = "rejected";
  20.  
  21.     _forEach = function(callback) {
  22.         for (var i = 0; this.length > i; i++) {
  23.             callback.call(this, this[i], i, this);
  24.         }
  25.     }
  26.  
  27.     _reduce = function(callback /*, initialValue*/) {
  28.         if (null === this || 'undefined' === typeof this) {
  29.             throw new TypeError('_reduce called on null or undefined');
  30.         }
  31.         if ('function' !== typeof callback) {
  32.             throw new TypeError(callback + ' is not a function');
  33.         }
  34.         var t = Object(this), len = t.length >>> 0, k = 0, value;
  35.         if (arguments.length >= 2) {
  36.             value = arguments[1];
  37.         } else {
  38.             while (k < len && ! k in t) k++;
  39.             if (k >= len)
  40.                 throw new TypeError('Reduce of empty array with no initial value');
  41.             value = t[k++];
  42.         }
  43.         for (; k < len; k++) {
  44.             if (k in t) {
  45.                 value = callback(value, t[k], k, t);
  46.             }
  47.         }
  48.         return value;
  49.     };
  50.  
  51.     if (!Array.isArray) {
  52.         Array.isArray = function(arg) {
  53.             return Object.prototype.toString.call(arg) === '[object Array]';
  54.         };
  55.     }
  56.  
  57.     has = function(obj, prop) {
  58.         return obj != null ? obj.hasOwnProperty(prop) : void 0;
  59.     };
  60.  
  61.     isArguments = function(obj) {
  62.         return has(obj, 'length') && has(obj, 'callee');
  63.     };
  64.  
  65.     isPromise = function(obj) {
  66.         return has(obj, 'promise') && typeof (obj != null ? obj.promise : void 0) === 'function';
  67.     };
  68.  
  69.     flatten = function(array) {
  70.         if (isArguments(array)) {
  71.             return flatten(Array.prototype.slice.call(array));
  72.         }
  73.         if (!Array.isArray(array)) {
  74.             return [array];
  75.         }
  76.         return _reduce.call(array, function(memo, value) {
  77.             if (Array.isArray(value)) {
  78.                 return memo.concat(flatten(value));
  79.             }
  80.             memo.push(value);
  81.             return memo;
  82.         }, []);
  83.     };
  84.  
  85.     after = function(times, func) {
  86.         if (times <= 0) {
  87.             return func();
  88.         }
  89.         return function() {
  90.             if (--times < 1) {
  91.                 return func.apply(this, arguments);
  92.             }
  93.         };
  94.     };
  95.  
  96.     wrap = function(func, wrapper) {
  97.         return function() {
  98.             var args;
  99.             args = [func].concat(Array.prototype.slice.call(arguments, 0));
  100.             return wrapper.apply(this, args);
  101.         };
  102.     };
  103.  
  104.     execute = function(callbacks, args, context) {
  105.         var callback, _i, _len, _ref, _results;
  106.         _ref = flatten(callbacks);
  107.         _results = [];
  108.         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  109.             callback = _ref[_i];
  110.             if (Object.prototype.toString.call(args) !== '[object Arguments]' && args.length === undefined) {
  111.                 args.length = 0;
  112.             }
  113.             _results.push(callback.call.apply(callback, [context].concat(__slice.call(args))));
  114.         }
  115.         return _results;
  116.     };
  117.  
  118.     /**
  119.      * @name Deferred
  120.      * @namespace
  121.      * @returns {Deferred}
  122.      * @constructor
  123.      */
  124.     Deferred = function() {
  125.         var candidate, close, closingArguments, doneCallbacks, failCallbacks, progressCallbacks, state;
  126.         state = PENDING;
  127.         doneCallbacks = [];
  128.         failCallbacks = [];
  129.         progressCallbacks = [];
  130.         closingArguments = {
  131.             'resolved': {},
  132.             'rejected': {},
  133.             'pending': {}
  134.         };
  135.         /**
  136.          * Promise Object
  137.          *
  138.          * @type {Promise}
  139.          * @param candidate
  140.          * @returns {{}}
  141.          */
  142.         this.promise = function(candidate) {
  143.             var pipe, storeCallbacks;
  144.             candidate = candidate || {};
  145.             candidate.state = function() {
  146.                 return state;
  147.             };
  148.             storeCallbacks = function(shouldExecuteImmediately, holder, holderState) {
  149.                 return function() {
  150.                     if (state === PENDING) {
  151.                         holder.push.apply(holder, flatten(arguments));
  152.                     }
  153.                     if (shouldExecuteImmediately()) {
  154.                         execute(arguments, closingArguments[holderState]);
  155.                     }
  156.                     return candidate;
  157.                 };
  158.             };
  159.             candidate.done = storeCallbacks((function() {
  160.                 return state === RESOLVED;
  161.             }), doneCallbacks, RESOLVED);
  162.             candidate.fail = storeCallbacks((function() {
  163.                 return state === REJECTED;
  164.             }), failCallbacks, REJECTED);
  165.             candidate.progress = storeCallbacks((function() {
  166.                 return state !== PENDING;
  167.             }), progressCallbacks, PENDING);
  168.             candidate.always = function() {
  169.                 var _ref;
  170.                 return (_ref = candidate.done.apply(candidate, arguments)).fail.apply(_ref, arguments);
  171.             };
  172.             pipe = function(doneFilter, failFilter, progressFilter) {
  173.                 var filter, master;
  174.                 master = new Deferred();
  175.                 filter = function(source, funnel, callback) {
  176.                     if (!callback) {
  177.                         return candidate[source](master[funnel]);
  178.                     }
  179.                     return candidate[source](function() {
  180.                         var args, value;
  181.                         args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  182.                         value = callback.apply(null, args);
  183.                         if (isPromise(value)) {
  184.                             return value.done(master.resolve).fail(master.reject).progress(master.notify);
  185.                         } else {
  186.                             return master[funnel](value);
  187.                         }
  188.                     });
  189.                 };
  190.                 filter('done', 'resolve', doneFilter);
  191.                 filter('fail', 'reject', failFilter);
  192.                 filter('progress', 'notify', progressFilter);
  193.                 return master;
  194.             };
  195.             candidate.pipe = pipe;
  196.             candidate.then = pipe;
  197.             if (candidate.promise == null) {
  198.                 candidate.promise = function() {
  199.                     return candidate;
  200.                 };
  201.             }
  202.             return candidate;
  203.         };
  204.         this.promise(this);
  205.         candidate = this;
  206.         close = function(finalState, callbacks, context) {
  207.             return function() {
  208.                 if (state === PENDING) {
  209.                     state = finalState;
  210.                     closingArguments[finalState] = arguments;
  211.                     execute(callbacks, closingArguments[finalState], context);
  212.                     return candidate;
  213.                 }
  214.                 return this;
  215.             };
  216.         };
  217.         this.resolve = close(RESOLVED, doneCallbacks);
  218.         this.reject = close(REJECTED, failCallbacks);
  219.         this.notify = close(PENDING, progressCallbacks);
  220.         this.resolveWith = function(context, args) {
  221.             return close(RESOLVED, doneCallbacks, context).apply(null, args);
  222.         };
  223.         this.rejectWith = function(context, args) {
  224.             return close(REJECTED, failCallbacks, context).apply(null, args);
  225.         };
  226.         this.notifyWith = function(context, args) {
  227.             return close(PENDING, progressCallbacks, context).apply(null, args);
  228.         };
  229.         return this;
  230.     };
  231.  
  232.     /**
  233.      * Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events.
  234.      *
  235.      * @returns {Promise}
  236.      * @private
  237.      */
  238.     _when = function() {
  239.         var def, defs, finish, resolutionArgs, trigger, _i, _len;
  240.         defs = flatten(arguments);
  241.         if (defs.length === 1) {
  242.             if (isPromise(defs[0])) {
  243.                 return defs[0];
  244.             } else {
  245.                 return (new Deferred()).resolve(defs[0]).promise();
  246.             }
  247.         }
  248.         trigger = new Deferred();
  249.         if (!defs.length) {
  250.             return trigger.resolve().promise();
  251.         }
  252.         resolutionArgs = [];
  253.         finish = after(defs.length, function() {
  254.             return trigger.resolve.apply(trigger, resolutionArgs);
  255.         });
  256.  
  257.         _forEach.call(defs, function(def, index) {
  258.             if (isPromise(def)) {
  259.                 return def.done(function() {
  260.                     var args;
  261.                     args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
  262.                     resolutionArgs[index] = args.length > 1 ? args : args[0];
  263.                     return finish();
  264.                 });
  265.             } else {
  266.                 resolutionArgs[index] = def;
  267.                 return finish();
  268.             }
  269.         });
  270.  
  271.         for (_i = 0, _len = defs.length; _i < _len; _i++) {
  272.             def = defs[_i];
  273.             isPromise(def) && def.fail(trigger.reject);
  274.         }
  275.         return trigger.promise();
  276.     };
  277.  
  278.  
  279.     /**
  280.      * Returns new Deferred object
  281.      *
  282.      * @returns {Deferred}
  283.      * @constructor
  284.      */
  285.     mmcore.Deferred = function () {
  286.         return new Deferred();
  287.     };
  288.     mmcore.when = _when;
  289.  
  290. }).call(this);
  291.  
  292. /**
  293.  * Essentials - Wait for
  294.  *
  295.  * A handy tool for organizing waiting for something.
  296.  *
  297.  * @version 0.1.0
  298.  *
  299.  * @requires mmcore.Deffered
  300.  *
  301.  * @author evgeniy@pavlyuk.me (Evgeniy Pavlyuk), a.porohnya@gmail.com (Aleksey Porokhnya)
  302.  */
  303. (function() {
  304.     'use strict';
  305.  
  306.     /**
  307.      * A handy tool for organizing waiting for something.
  308.      *
  309.      * @param {function(this:!mmcore.Deferred):boolean} checker A function that controls the state of the waiting.
  310.      * @param {!Object=} options Optional settings:
  311.      *     initializer {function(this:mmcore.Deferred)} A function that is called before the first check.
  312.      *     interval {number} Delay (in milliseconds) between the checks.
  313.      *     isNotPeriodicallyChecked {boolean} Is the check not called periodically, but only once?
  314.      *     isNotStoppedOnDocumentReadiness {boolean} Is the waiting not stopped when the document gets ready and the
  315.      *         waiting is incomplete?
  316.      *     timeout {number} A period of time (in milliseconds) after which the waiting fails.
  317.      *
  318.      * @return {!mmcore.Deferred#Promise} The promise of the waiting.
  319.      *
  320.      * @example
  321.      * // Periodically check for the client jQuery arrival.
  322.      * mmcore.waitFor(function() {
  323.    *    // Successfully complete the waiting when the client jQuery arrives.
  324.    *    // The waiting stops if the client jQuery does not arrive when the document gets ready.
  325.    *   return (typeof jQuery === 'function');
  326.    * }).done(function() {
  327.    *   // The client jQuery has arrived.
  328.    * }).fail(function() {
  329.    *   // The client jQuery has not been arrived when the document got ready.
  330.    * });
  331.      *
  332.      * @example
  333.      *  // Periodically check for the client jQuery arrival.
  334.      * mmcore.waitFor(function() {
  335.    *   // The checker has direct access to the deferred object, so the waiting can be completed by hand.
  336.    *   // It gives more control over the waiting, and allows to complete the waiting with custom arguments.
  337.    *   if (typeof jQuery === 'function') {
  338.    *     this.resolve(jQuery);
  339.    *   }
  340.    * }).done(function(jQuery) {
  341.    *   // The client jQuery has arrived.
  342.    * });
  343.      */
  344.     mmcore.waitFor = function(checker, options) {
  345.         var check;
  346.         var waiting;
  347.  
  348.         // Manages the state of the event that is expected to happen.
  349.         // Learn more at http://api.jquery.com/category/deferred-object/
  350.         waiting = mmcore.Deferred();
  351.  
  352.         // The handy method is used instead of copying and pasting the check below.
  353.         waiting.isComplete = function() {
  354.             return (waiting.state() !== 'pending');
  355.         };
  356.  
  357.         // Extend the default options with the given ones (if any).
  358.         options = options || {};
  359.         options.interval = options.interval || 50;
  360.         options.isNotStoppedOnDocumentReadiness = options.isNotStoppedOnDocumentReadiness|| false;
  361.         options.isNotPeriodicallyChecked = options.isNotPeriodicallyChecked || false;
  362.  
  363.  
  364.         // Calls the checker.
  365.         // If not prevented by isNotPeriodicallyChecked option, provides periodical calling of itself.
  366.         // If not prevented by isNotStoppedOnDocumentReadiness option, stops the waiting if it is not complete when the
  367.         // document is ready.
  368.         check = function() {
  369.             if (waiting.isComplete()) {
  370.                 return;
  371.             }
  372.  
  373.             // Successfully completes waiting if the checker returns true.
  374.             // Note, that the checker has direct access to the deferred object, so the waiting can be completed in the checker
  375.             // by calling resolve or reject method of the deferred object.
  376.             // Checking for the return value is done to provide an easy and comfortable way to complete the waiting from the
  377.             // checker.
  378.             if (checker.call(waiting)) {
  379.                 waiting.resolve();
  380.             }
  381.  
  382.             if (waiting.isComplete()) {
  383.                 return;
  384.             }
  385.  
  386.             if (!options.isNotStoppedOnDocumentReadiness
  387.                 && ((mmcore.$ && mmcore.$.isReady) || (!mmcore.$ && document.readyState === "complete"))) {
  388.                 // Stop the waiting if it is incomplete when the document is ready.
  389.                 waiting.reject();
  390.             } else if (!options.isNotPeriodicallyChecked) {
  391.                 // Provide periodical calling of the checking function.
  392.                 setTimeout(check, options.interval);
  393.             }
  394.         };
  395.  
  396.         // If there is the initializer function, call it before the first check.
  397.         if (options.hasOwnProperty('initializer')) {
  398.             options.initializer.call(waiting);
  399.         }
  400.  
  401.         check();
  402.  
  403.         if (!waiting.isComplete()) {
  404.             if (options.hasOwnProperty('timeout')) {
  405.                 // Stop checking after the specified period of time.
  406.                 (function() {
  407.                     var timeoutId = setTimeout(waiting.reject, options.timeout);
  408.                     waiting.always(function() {
  409.                         clearTimeout(timeoutId);
  410.                     });
  411.                 }());
  412.             }
  413.  
  414.             if (!options.isNotStoppedOnDocumentReadiness) {
  415.                 if (!options.isNotPeriodicallyChecked) {
  416.                     // If the checker is periodically called, and the waiting stops if it is incomplete when the document is
  417.                     // ready, call the checker for the last time exactly at the moment when the document gets ready.
  418.                     mmcore.AddDocLoadHandler(check);
  419.                     //$(document).ready(check);
  420.                 } else {
  421.                     // If the checker is not called periodically, but only once, stop the waiting when the document gets ready.
  422.                     mmcore.AddDocLoadHandler(waiting.reject);
  423.                     //$(document).ready(waiting.reject);
  424.                 }
  425.             }
  426.         }
  427.  
  428.         return waiting.promise();
  429.     };
  430. }());
  431.  
  432. /**
  433.  * Maxymiser Core - Campaign
  434.  *
  435.  * Campaign constructor that provides basic functionality for campaign development.
  436.  *
  437.  * @version 0.3.4
  438.  *
  439.  * @requires mmcore.Deferred
  440.  * @requires mmcore.tryCatch
  441.  * @requires mmcore.AttachStyle
  442.  *
  443.  * @author evgeniy.pavlyuk@maxymiser.com (Evgeniy Pavlyuk)
  444.  * @author andrey.ponamarev@maxymiser.com (Andrey Ponamarev)
  445.  * @author aleksey.porokhnya@maxymiser.com (Aleksey Porokhnya)
  446.  */
  447. (function() {
  448.     'use strict';
  449.     /**
  450.      * @type {Campaign}
  451.      */
  452.     mmcore.Campaign = Campaign;
  453.  
  454.     /**
  455.      * @param {*} itemToCheck
  456.      * @param {Array} arr
  457.      * @returns {boolean}
  458.      */
  459.     function inArray(itemToCheck, arr) {
  460.         var inArray = false;
  461.         for (var i = 0; i < arr.length; i++) {
  462.             if (arr[i] === itemToCheck) {
  463.                 inArray = true;
  464.             }
  465.         }
  466.         return inArray;
  467.     }
  468.  
  469.     /**
  470.      *
  471.      * @param elems
  472.      * @param callback
  473.      * @param inv
  474.      * @returns {Array}
  475.      */
  476.     var grep = function( elems, callback, inv) {
  477.         var retVal,
  478.             ret = [],
  479.             i = 0,
  480.             length = elems.length;
  481.         inv = !!inv;
  482.  
  483.         // Go through the array, only saving the items
  484.         // that pass the validator function
  485.         for ( ; i < length; i++ ) {
  486.             retVal = !!callback( elems[ i ], i );
  487.             if ( inv !== retVal ) {
  488.                 ret.push( elems[ i ] );
  489.             }
  490.         }
  491.  
  492.         return ret;
  493.     }
  494.  
  495.     /**
  496.      * Campaign constructor that provides basic functionality for campaign development.   *
  497.      * Documentation https://bitbucket.org/gamingteam/essentials-campaign
  498.      *
  499.      *
  500.      * @name Campaign
  501.      * @namespace
  502.      * @constructor
  503.      *
  504.      * @param {string} name Campaign name from the UI.
  505.      * @param {!Array.<string>} maxyboxNames Names of campaign elements from the UI.
  506.      * @param {string} prefix Prefix with campaign type and number, for example, mt1.
  507.      */
  508.     function Campaign(name, maxyboxNames, prefix) {
  509.         /**
  510.          * Campaign name.
  511.          * @type {string}
  512.          */
  513.         this.name = name;
  514.         /**
  515.          * Names of campaign elements.
  516.          * @type {!Array.<string>}
  517.          */
  518.         this.maxyboxNames = maxyboxNames;
  519.         /**
  520.          * Campaign type and number prefix.
  521.          * @type {string}
  522.          */
  523.         this.prefix = prefix;
  524.  
  525.         this.preventDefaultRendering();
  526.         this.preventDefaultHiding();
  527.     }
  528.  
  529.     /**
  530.      * Marks the campaign elements as rendered.
  531.      */
  532.     Campaign.prototype.preventDefaultRendering = function() {
  533.         /* jshint -W106 */
  534.         var states = mmcore._r_mbs;
  535.         /* jshint +W106 */
  536.         var maxyBoxes = this.maxyboxNames;
  537.         var l = maxyBoxes.length;
  538.  
  539.         while(l--){
  540.             states[maxyBoxes[l]] = 1;
  541.         }
  542.     };
  543.  
  544.     /**
  545.      * Excludes the campaign elements from arguments of `mmcore.HideMaxyboxes` when it's called.
  546.      */
  547.     Campaign.prototype.preventDefaultHiding = function() {
  548.         var campaign = this;
  549.         mmcore.HideMaxyboxes = (function(hideMaxyboxes) {
  550.             return function() {
  551.                 var maxyboxNames = arguments;
  552.  
  553.                 mmcore.tryCatch(function() {
  554.                     maxyboxNames = grep(maxyboxNames, function(maxyboxName) {
  555.                         return (inArray(maxyboxName, campaign.maxyboxNames));
  556.                     });
  557.                 })();
  558.  
  559.                 if (maxyboxNames.length) {
  560.                     return hideMaxyboxes.apply(this, maxyboxNames);
  561.                 }
  562.             };
  563.         }(mmcore.HideMaxyboxes));
  564.         mmcore._MbStyle = function () {};
  565.     };
  566.  
  567.     /**
  568.      * Hides content by selector.
  569.      *
  570.      * @param {string|Array.<string>} selector CSS selector(s).
  571.      * @param {string=} hidingStyle Optional CSS to be applied to the selector.
  572.      *     If ommited, the content is hidden through absolute positioning.
  573.      */
  574.     Campaign.prototype.hideContent = function(selector, hidingStyle) {
  575.         var hidingClass;
  576.         var hidingSelectorStyle;
  577.         var countSelectors;
  578.         var hidingSelectors;
  579.         var htmlTag = document.getElementsByTagName('html')[0];
  580.         var htmlClass = htmlTag.getAttribute('class');
  581.         var styleStr = '';
  582.         var isEmpty = function(obj) {
  583.  
  584.             if (obj == null) return true;
  585.  
  586.             if (obj.length > 0)    return false;
  587.             if (obj.length === 0)  return true;
  588.  
  589.             for (var key in obj) {
  590.                 if (hasOwnProperty.call(obj, key)) return false;
  591.             }
  592.  
  593.             return true;
  594.         };
  595.  
  596.         this.hidingClass = this.prefix + '-hidden-content';
  597.  
  598.         // Add Class to html
  599.         htmlClass = (htmlClass !== null && htmlClass === '') ? this.hidingClass : htmlClass + ' ' + this.hidingClass;
  600.  
  601.         htmlTag.setAttribute('class', htmlClass);
  602.  
  603.         if (arguments.length < 2) {
  604.             hidingStyle = 'left: -33554430px; position: absolute; top: -33554430px;';
  605.         }
  606.  
  607.         hidingClass = this.hidingClass;
  608.  
  609.         if ({}.toString.call(selector) === '[object Object]' && !isEmpty(selector)) {
  610.             for (var key in selector) {
  611.                 styleStr += ' .' + hidingClass + ' ' + key + '{' + selector[key] + '}';
  612.             }
  613.             mmcore.AttachStyle(styleStr);
  614.             return;
  615.         }
  616.  
  617.         hidingSelectors = selector.split(',');
  618.         countSelectors = hidingSelectors.length;
  619.         hidingSelectorStyle = '';
  620.  
  621.         while(countSelectors--){
  622.             hidingSelectorStyle += '.' + hidingClass + ' ' + hidingSelectors[countSelectors] + '{' +
  623.                 hidingStyle +
  624.                 '}'
  625.         }
  626.         mmcore.AttachStyle(hidingSelectorStyle);
  627.     };
  628.  
  629.     /**
  630.      * Shows the content previously hidden by `Campaign.prototype.hideContent`.
  631.      */
  632.     Campaign.prototype.showContent = function() {
  633.         if (this.hasOwnProperty('hidingClass')) {
  634.             var htmlTag = document.getElementsByTagName('html')[0];
  635.             var htmlClass = htmlTag.getAttribute('class');
  636.             if(htmlClass !== null && htmlClass !== ''){
  637.                 htmlClass = htmlClass.replace(this.hidingClass, '');
  638.                 htmlTag.setAttribute('class', htmlClass);
  639.             }
  640.         }
  641.     };
  642.  
  643.     /**
  644.      * Returns generated experience of this campaign from GenInfo
  645.      *
  646.      * @returns {Object}
  647.      */
  648.     Campaign.prototype.getExperience = function() {
  649.         // Assume that an own property of mmcore.GenInfo reference to a unique object.
  650.         return mmcore.GenInfo.hasOwnProperty(this.name) ?
  651.                mmcore.GenInfo[this.name] : null;
  652.     };
  653.  
  654.     /**
  655.      * Returns true if campaign has non default experience
  656.      *
  657.      * @return {boolean}
  658.      */
  659.     Campaign.prototype.hasNonDefaultExperience = function() {
  660.         var experience, hasNonDefaultExperience;
  661.         experience = this.getExperience();
  662.         if (!experience) {
  663.             return false;
  664.         }
  665.  
  666.         hasNonDefaultExperience = false;
  667.  
  668.         for(var key in experience){
  669.             if (experience.hasOwnProperty(key) &&
  670.                 (experience[key] !== 'Default')) {
  671.                 hasNonDefaultExperience = true;
  672.                 break;
  673.             }
  674.         }
  675.  
  676.         return hasNonDefaultExperience;
  677.     };
  678.  
  679.     /**
  680.      * @return {boolean}
  681.      * @deprecated Use hasNonDefaultExperience() instead.
  682.      */
  683.     Campaign.prototype.hasMaxybox = function() {
  684.         return this.hasNonDefaultExperience();
  685.     };
  686.  
  687.  
  688.     /**
  689.      * Extending method for campaign
  690.      *
  691.      * @param {Object} obj
  692.      */
  693.     Campaign.prototype.extend = function extend(obj) {
  694.         for(var prop in obj)
  695.             this[prop] = obj[prop];
  696.  
  697.         return this;
  698.     },
  699.  
  700.     /**
  701.      * Render all or specific campaign maxyboxes.
  702.      * this in a variant script references to the campaign.
  703.      */
  704.         Campaign.prototype.renderMaxyboxes = function() {
  705.             var campaign;
  706.             var maxyboxNames;
  707.             var key;
  708.  
  709.             maxyboxNames = this.maxyboxNames;
  710.  
  711.             if (arguments.length) {
  712.                 maxyboxNames = grep(arguments, function(maxyboxName) {
  713.                     return !inArray(maxyboxName, maxyboxNames);
  714.                 });
  715.             }
  716.  
  717.             campaign = this;
  718.  
  719.             for(key in mmcore._renderers){
  720.                 if(inArray(key, maxyboxNames) && typeof mmcore._renderers[key] === 'function'){
  721.                     mmcore._renderers[key].call(campaign);
  722.                 }
  723.             }
  724.         };
  725. }());
  726.  
  727. /**
  728.  * Maxymiser Core - Request
  729.  *
  730.  * A handy wrap around `mmcore.CGRequest`.
  731.  *
  732.  * @version 0.1.0
  733.  *
  734.  * @requires mmcore.jQuery
  735.  * @requires mmcore.tryCatch
  736.  *
  737.  * @author evgeniy.pavlyuk@maxymiser.com (Evgeniy Pavlyuk)
  738.  */
  739. (function() {
  740.     'use strict';
  741.     var $ = mmcore.jQuery;
  742.     var ACTION_TRACKING_PAGE_ID = 'event';
  743.     var REQUEST_TIMEOUT = 2250;  // In milliseconds.
  744.     var followingRequest;
  745.     var prepareFollowingRequest = function() {
  746.         followingRequest = $.Deferred();
  747.         mmcore.request.promise = followingRequest.promise();
  748.     };
  749.     /**
  750.      * @param {string=} pageId If not sepcified, `event` is asssumed.
  751.      * @param {boolean=} isSynchronous If not specified, the request will be asynchronous.
  752.      * @return {!Object} Promise.
  753.      */
  754.     mmcore.request = function(pageId, isSynchronous) {
  755.         var request = followingRequest;
  756.         prepareFollowingRequest();
  757.         if (!arguments.length) {
  758.             pageId = ACTION_TRACKING_PAGE_ID;
  759.         }
  760.         mmcore.SetPageID(pageId);
  761.         mmcore._async = !isSynchronous;
  762.         mmcore.CGRequest(request.resolve);  // Callback is called in a try block in a response.
  763.         setTimeout(mmcore.tryCatch(request.reject), REQUEST_TIMEOUT);
  764.         return request.promise();
  765.     };
  766.     prepareFollowingRequest();
  767. }());
  768.  
  769. /**
  770.  * Maxymiser Essentials - Mediator
  771.  *
  772.  *
  773.  * Makes `mmcore` act as a mediator.
  774.  * Provides `mmcore.mediator`
  775.  *
  776.  * @version 0.1.3
  777.  *
  778.  *
  779.  * @author porokhnya.aleksey@maxymiser.com (Porokhnya Aleksey)
  780.  */
  781.  
  782.  
  783. ;(function () {
  784.     'use strict';
  785.  
  786.     // We'll generate guids for class instances for easy referencing later on.
  787.     // Subscriber instances will have an id that can be refernced for quick
  788.     // lookups.
  789.  
  790.     function guidGenerator() {
  791.         var S4 = function() {
  792.             return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
  793.         };
  794.  
  795.         return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
  796.     }
  797.  
  798.     /**
  799.      * Subscribers are instances of Mediator Channel registrations. We generate
  800.      * an object instance so that it can be updated later on without having to
  801.      * unregister and re-register. Subscribers are constructed with a function
  802.      *  to be called, options object, and context.
  803.      *
  804.      * @name Subscriber
  805.      * @namespace
  806.      *
  807.      * @param {Function} fn
  808.      * @param {Object} options
  809.      * @param {Object} context
  810.      * @returns {Subscriber}
  811.      * @constructor
  812.      */
  813.     function Subscriber(fn, options, context){
  814.         if(!(this instanceof Subscriber)) {
  815.             return new Subscriber(fn, options, context);
  816.         }
  817.  
  818.         this.id = guidGenerator();
  819.         this.fn = fn;
  820.         this.options = options;
  821.         this.context = context;
  822.         this.channel = null;
  823.     }
  824.  
  825.     Subscriber.prototype = {
  826.  
  827.         /**
  828.          * Mediator.update on a subscriber instance can update its function,context,
  829.          * or options object. It takes in an object and looks for fn, context, or options keys.
  830.          *
  831.          * @param {Object} options
  832.          */
  833.         update: function(options){
  834.             if(options){
  835.                 this.fn = options.fn || this.fn;
  836.                 this.context = options.context || this.context;
  837.                 this.options = options.options || this.options;
  838.                 if(this.channel && this.options && this.options.priority !== undefined) {
  839.                     this.channel.setPriority(this.id, this.options.priority);
  840.                 }
  841.             }
  842.         }
  843.     };
  844.  
  845.  
  846.     /**
  847.      * @name Channel
  848.      * @namespace
  849.      * @param {String} namespace
  850.      * @param {Channel} parent
  851.      * @returns {Channel}
  852.      * @constructor
  853.      */
  854.     function Channel(namespace, parent){
  855.         if(!(this instanceof Channel)) {
  856.             return new Channel(namespace);
  857.         }
  858.  
  859.         this.namespace = namespace || "";
  860.         this._subscribers = [];
  861.         this._channels = [];
  862.         this._parent = parent;
  863.         this.stopped = false;
  864.     }
  865.  
  866.     // A Mediator channel holds a list of sub-channels and subscribers to be fired
  867.     // when Mediator.publish is called on the Mediator instance. It also contains
  868.     // some methods to manipulate its lists of data; only setPriority and
  869.     // StopPropagation are meant to be used. The other methods should be accessed
  870.     // through the Mediator instance.
  871.  
  872.     Channel.prototype = {
  873.         addSubscriber: function(fn, options, context){
  874.             var subscriber = new Subscriber(fn, options, context);
  875.  
  876.             if(options && options.priority !== undefined){
  877.                 // Cheap hack to either parse as an int or turn it into 0. Runs faster
  878.                 // in many browsers than parseInt with the benefit that it won't
  879.                 // return a NaN.
  880.                 options.priority = options.priority >> 0;
  881.  
  882.                 if(options.priority < 0){ options.priority = 0; }
  883.                 if(options.priority >= this._subscribers.length){ options.priority = this._subscribers.length-1; }
  884.  
  885.                 this._subscribers.splice(options.priority, 0, subscriber);
  886.             }else{
  887.                 this._subscribers.push(subscriber);
  888.             }
  889.  
  890.             subscriber.channel = this;
  891.  
  892.             return subscriber;
  893.         },
  894.  
  895.         // The channel instance is passed as an argument to the mediator subscriber,
  896.         // and further subscriber propagation can be called with
  897.         // channel.StopPropagation().
  898.         stopPropagation: function(){
  899.             this.stopped = true;
  900.         },
  901.  
  902.         getSubscriber: function(identifier){
  903.             var x = 0,
  904.                 y = this._subscribers.length;
  905.  
  906.             for(x, y; x < y; x++){
  907.                 if(this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
  908.                     return this._subscribers[x];
  909.                 }
  910.             }
  911.         },
  912.  
  913.         // Channel.setPriority is useful in updating the order in which Subscribers
  914.         // are called, and takes an identifier (subscriber id or named function) and
  915.         // an array index. It will not search recursively through subchannels.
  916.  
  917.         setPriority: function(identifier, priority){
  918.             var oldIndex = 0,
  919.                 x = 0,
  920.                 sub, firstHalf, lastHalf, y;
  921.  
  922.             for(x = 0, y = this._subscribers.length; x < y; x++){
  923.                 if(this._subscribers[x].id === identifier || this._subscribers[x].fn === identifier){
  924.                     break;
  925.                 }
  926.                 oldIndex ++;
  927.             }
  928.  
  929.             sub = this._subscribers[oldIndex];
  930.             firstHalf = this._subscribers.slice(0, oldIndex);
  931.             lastHalf = this._subscribers.slice(oldIndex+1);
  932.  
  933.             this._subscribers = firstHalf.concat(lastHalf);
  934.             this._subscribers.splice(priority, 0, sub);
  935.         },
  936.  
  937.         addChannel: function(channel){
  938.             this._channels[channel] = new Channel((this.namespace ? this.namespace + ':' : '') + channel, this);
  939.         },
  940.  
  941.         hasChannel: function(channel){
  942.             return this._channels.hasOwnProperty(channel);
  943.         },
  944.  
  945.         returnChannel: function(channel){
  946.             return this._channels[channel];
  947.         },
  948.  
  949.         removeSubscriber: function(identifier){
  950.             var x = this._subscribers.length - 1;
  951.  
  952.             // If we don't pass in an id, we're clearing all
  953.             if(!identifier){
  954.                 this._subscribers = [];
  955.                 return;
  956.             }
  957.  
  958.             // Going backwards makes splicing a whole lot easier.
  959.             for(x; x >= 0; x--) {
  960.                 if(this._subscribers[x].fn === identifier || this._subscribers[x].id === identifier){
  961.                     this._subscribers[x].channel = null;
  962.                     this._subscribers.splice(x,1);
  963.                 }
  964.             }
  965.         },
  966.  
  967.         // This will publish arbitrary arguments to a subscriber and then to parent
  968.         // channels.
  969.  
  970.         publish: function(data){
  971.             var x = 0,
  972.                 y = this._subscribers.length,
  973.                 called = false,
  974.                 subscriber, l,
  975.                 subsBefore,subsAfter;
  976.  
  977.             // Priority is preserved in the _subscribers index.
  978.             for(x, y; x < y; x++) {
  979.                 called = false;
  980.  
  981.                 if(!this.stopped){
  982.                     subscriber = this._subscribers[x];
  983.                     if(subscriber.options !== undefined && typeof subscriber.options.predicate === "function"){
  984.                         if(subscriber.options.predicate.apply(subscriber.context, data)){
  985.                             subscriber.fn.apply(subscriber.context, data);
  986.                             called = true;
  987.                         }
  988.                     }else{
  989.                         subsBefore = this._subscribers.length;
  990.                         subscriber.fn.apply(subscriber.context, data);
  991.                         subsAfter = this._subscribers.length;
  992.                         y = subsAfter;
  993.                         if (subsAfter === subsBefore - 1){
  994.                             x--;
  995.                         }
  996.                         called = true;
  997.                     }
  998.                 }
  999.  
  1000.                 if(called && subscriber.options && subscriber.options !== undefined){
  1001.                     subscriber.options.calls--;
  1002.  
  1003.                     if(subscriber.options.calls < 1){
  1004.                         this.removeSubscriber(subscriber.id);
  1005.                         y--;
  1006.                         x--;
  1007.                     }
  1008.                 }
  1009.             }
  1010.  
  1011.             if(this._parent){
  1012.                 this._parent.publish(data);
  1013.             }
  1014.  
  1015.             this.stopped = false;
  1016.         }
  1017.     };
  1018.  
  1019.     /**
  1020.      * Mediator object
  1021.      *
  1022.      * @returns {Mediator}
  1023.      * @constructor
  1024.      */
  1025.     function Mediator() {
  1026.         if(!(this instanceof Mediator)) {
  1027.             return new Mediator();
  1028.         }
  1029.  
  1030.         this._channels = new Channel('');
  1031.     }
  1032.  
  1033.     // A Mediator instance is the interface through which events are registered
  1034.     // and removed from publish channels.
  1035.  
  1036.     Mediator.prototype = {
  1037.  
  1038.         /**
  1039.          * Returns a channel instance based on namespace
  1040.          *  for example application:chat:message:received
  1041.          *
  1042.          * @param {string} namespace
  1043.          * @returns {Array|_channels|*}
  1044.          */
  1045.         getChannel: function(namespace){
  1046.             var channel = this._channels,
  1047.                 namespaceHierarchy = namespace.split(':'),
  1048.                 x = 0,
  1049.                 y = namespaceHierarchy.length;
  1050.  
  1051.             if(namespace === ''){
  1052.                 return channel;
  1053.             }
  1054.  
  1055.             if(namespaceHierarchy.length > 0){
  1056.                 for(x, y; x < y; x++){
  1057.  
  1058.                     if(!channel.hasChannel(namespaceHierarchy[x])){
  1059.                         channel.addChannel(namespaceHierarchy[x]);
  1060.                     }
  1061.  
  1062.                     channel = channel.returnChannel(namespaceHierarchy[x]);
  1063.                 }
  1064.             }
  1065.  
  1066.             return channel;
  1067.         },
  1068.  
  1069.  
  1070.         /**
  1071.          * Pass in a channel namespace, function to be called, options, and context
  1072.          * to call the function in to Subscribe. It will create a channel if one
  1073.          * does not exist. Options can include a predicate to determine if it
  1074.          * should be called (based on the data published to it) and a priority index.
  1075.          *
  1076.          * @param {String} channelName
  1077.          * @param {Function} fn
  1078.          * @param {Object} options
  1079.          * @param {Object} context
  1080.          * @returns {Subscriber}
  1081.          */
  1082.         subscribe: function(channelName, fn, options, context){
  1083.             var channel = this.getChannel(channelName);
  1084.  
  1085.             options = options || {};
  1086.             context = context || {};
  1087.  
  1088.             return channel.addSubscriber(fn, options, context);
  1089.         },
  1090.  
  1091.  
  1092.         /**
  1093.          * Pass in a channel namespace, function to be called, options, and context
  1094.          * to call the function in to Subscribe. It will create a channel if one
  1095.          * does not exist. Options can include a predicate to determine if it
  1096.          * should be called (based on the data published to it) and a priority index
  1097.          *
  1098.          * @param {String} channelName
  1099.          * @param {Function} fn
  1100.          * @param {Object} options
  1101.          * @param {Object} context
  1102.          * @returns {Subscriber}
  1103.          */
  1104.         once: function(channelName, fn, options, context){
  1105.             options = options || {};
  1106.             options.calls = 1;
  1107.  
  1108.             return this.subscribe(channelName, fn, options, context);
  1109.         },
  1110.  
  1111.  
  1112.         /**
  1113.          * Returns a subscriber for a given subscriber id / named function and channel namespace
  1114.          *
  1115.          * @param {String} identifier
  1116.          * @param {String} channel name
  1117.          * @returns {Subscriber}
  1118.          */
  1119.         getSubscriber: function(identifier, channel){
  1120.             return this.getChannel(channel || "").getSubscriber(identifier);
  1121.         },
  1122.  
  1123.  
  1124.         /**
  1125.          * Remove a subscriber from a given channel namespace recursively based on
  1126.          * a passed-in subscriber id or named function.
  1127.          *
  1128.          * @param {String} channelName
  1129.          * @param {String} identifier
  1130.          */
  1131.         remove: function(channelName, identifier){
  1132.             this.getChannel(channelName).removeSubscriber(identifier);
  1133.         },
  1134.  
  1135.         /**
  1136.          * Publishes arbitrary data to a given channel namespace. Channels are
  1137.          * called recursively downwards; a post to application:chat will post to
  1138.          * application:chat:receive and application:chat:derp:test:beta:bananas.
  1139.          * Called using Mediator.publish("application:chat", [ args ]);
  1140.          *
  1141.          * @param {String} channelName
  1142.          */
  1143.         publish: function(channelName){
  1144.             var args = Array.prototype.slice.call(arguments, 1),
  1145.                 channel = this.getChannel(channelName);
  1146.  
  1147.             args.push(channel);
  1148.  
  1149.             this.getChannel(channelName).publish(args);
  1150.         }
  1151.     };
  1152.  
  1153.     /**
  1154.      * Alias for Mediator.subscribe (See "subscribe" method)
  1155.      * @type {Function}
  1156.      */
  1157.     Mediator.prototype.on = Mediator.prototype.subscribe;
  1158.     /**
  1159.      * Alias for Mediator.subscribe (See "subscribe" method)
  1160.      * @type {Function}
  1161.      */
  1162.     Mediator.prototype.bind = Mediator.prototype.subscribe;
  1163.     /**
  1164.      * Alias for Mediator.subscribe (See "publish" method)
  1165.      * @type {Function}
  1166.      */
  1167.     Mediator.prototype.emit = Mediator.prototype.publish;
  1168.     /**
  1169.      * Alias for Mediator.subscribe (See "publish" method)
  1170.      * @type {Function}
  1171.      */
  1172.     Mediator.prototype.trigger = Mediator.prototype.publish;
  1173.     /**
  1174.      * Alias for Mediator.subscribe (See "publish" method)
  1175.      * @type {Function}
  1176.      */
  1177.     Mediator.prototype.fire = Mediator.prototype.publish;
  1178.     /**
  1179.      * Alias for Mediator.subscribe (See "remove" method)
  1180.      * @type {Function}
  1181.      */
  1182.     Mediator.prototype.off = Mediator.prototype.remove;
  1183.  
  1184.     // Finally, expose it all.
  1185.  
  1186.     Mediator.Channel = Channel;
  1187.     Mediator.Subscriber = Subscriber;
  1188.  
  1189.     /**
  1190.      * Mediator instance
  1191.      * more information at: https://bitbucket.org/gamingteam/essentials-mediator
  1192.      *
  1193.      * @type {Mediator}
  1194.      */
  1195.     mmcore.mediator = new Mediator();
  1196. } ());
  1197.  
  1198. ;(function() {
  1199.     /**
  1200.      * Maxymiser Core - OnNotRefresh
  1201.      *
  1202.      * Method which is used to add halders for non refresh load of page
  1203.      *
  1204.      * @version 0.1.0
  1205.      *
  1206.      * @param {function} func Function which will be called if page hasnt been refreshed (there is no cookie which is seted on unload event)
  1207.      * @param {string} [suffix] Cookie suffix which used to identify which page where unloaded recently (default value is 'default')
  1208.      * @param {number} [sec] Cookie lifetime in seconds (default value is 3)
  1209.      *
  1210.      * @author titus.kovalenko@maxymiser.com (Titus Kovalenko)
  1211.      */
  1212.     var onNotRefresh = function(func, suffix, sec) {
  1213.         suffix = suffix || 'default';
  1214.         sec = sec || 3;
  1215.  
  1216.         if (!mmcore.GetCookie('mm_refresh_' + suffix, 1)) {
  1217.             func();
  1218.         }
  1219.  
  1220.         window.onunload = (function (original) {
  1221.             return function() {
  1222.                 var result;
  1223.                 mmcore.SetCookie('mm_refresh_' + suffix, 1, sec / (24 * 60 * 60), 1);
  1224.  
  1225.                 if (original) {
  1226.                     result = original.apply(this, arguments)
  1227.                 };
  1228.  
  1229.                 return result;
  1230.             }
  1231.         })(window.onunload);
  1232.     }
  1233.  
  1234.     mmcore.onNotRefresh = onNotRefresh;
  1235. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement