loader.js

/*
 Centralised loader script that is responsible for loading/handling all your product/environment specific scripts
 in one place. Allows a better control over your vast product range, centralising all your business related configurations
 in one place:
 - load all your scripts/styles/configurations/presets from one script
 - control when and how the scripts get initialised
 - restrict loading per product
*/

import sizeof from './utils/sizeof';
import mapObject from './utils/mapObject';

(function () {
  'use strict';

  // var classSelector = /^\.([\w-]+)$/; // class string expression check
  // var idSelector = /^#[\w\d\-\_\&\!\@\*]+$/; // ID string expression check
  // var tagSelector = /^[\w-]+$/; // TAG string expression check

  /**
   * Ajax method
   *
   * @class Ajax
   * @constructor
   */
  var Ajax = function () { this.xhr = new XMLHttpRequest(); };

  /* eslint no-undef: "off" */
  Ajax.prototype.createCORSRequest = function (method, url) { var obj = this; if ('withCredentials' in obj.xhr) { /* Most browsers. */obj.xhr.open(method, url, true); } else if (typeof XDomainRequest !== 'undefined') { /* IE8 & IE9 */obj.xhr = new XDomainRequest(); url = (url.indexOf('https') > -1 && location.protocol !== 'https:') ? url.replace('https', 'http') : url; obj.xhr.open(method, url); } else { /* CORS not supported. */obj.xhr = null; } return obj.xhr; };
  Ajax.prototype.abort = function () { if (this.xhr && this.xhr.readyState !== undefined && this.xhr.readyState !== 4) { this.xhr.abort(); } return this; };

  /**
   * Retrieves data from a URL without page refresh
   *
   * @method getData
   * @param {Object} configuration object
   *  - object contains: HTTP method "type: POST, GET", url: to send the request to, data: {object}
   * @return {String} in success object
   */
  Ajax.prototype.getData = function (data) { var obj = this; try { data.type = (data.type !== undefined && typeof data.type === 'string' && data.type.length > 0) ? data.type : 'POST'; data.data = (data.data !== undefined && typeof data.data === 'object') ? data.data : {}; data.url = (data.url !== undefined && typeof data.url === 'string' && data.url.length > 0) ? data.url : ''; data.success = (data.success !== undefined) ? data.success : function () {}; data.error = (data.error !== undefined) ? data.error : function () {}; data.headers = (data.headers !== undefined) ? data.headers : {}; data.extraCallback = (data.extraCallback !== undefined) ? data.extraCallback : function () {}; /* cross browser CORS support */obj.xhr = this.createCORSRequest(data.type, data.url); obj.xhr.onload = function () { data.extraCallback(data, obj.xhr); data.success(obj.xhr.responseText, data, obj.xhr); }; obj.xhr.onerror = function () { data.error(obj.xhr.status); }; if (typeof XDomainRequest === 'undefined') { if (sizeof(data.headers) > 0) { var item; for (item in data.headers) { obj.xhr.setRequestHeader(item, data.headers[item]); } } else if ((data.type === 'POST' || data.type === 'PUT' || data.type === 'DELETE') && sizeof(data.headers) === 0) { obj.xhr.setRequestHeader('Content-Type', 'application/json'); } else { obj.xhr.setRequestHeader('Content-Type', 'text/plain'); } }obj.xhr.send(JSON.stringify(data.data)); return obj.xhr; } catch (err) { console.log(err); } };
  // var stringContains = function (str, partial) { try { return (str.indexOf(partial) > -1); } catch (e) { return false; } };

  var loadScript = function () {
    // generic/default settings
    if (typeof window._CLLBV3Opt === 'undefined') {
      window._CLLBV3Opt = {
        bindContainer: document.body,
        spaceName: 'my_space_name',
        autoStart: false,
        memberId: '',
        gameId: 'my_product_id',
        enforceGameLookup: true,
        apiKey: '',
        resources: [],
        uri: {
          gatewayDomain: 'https://gateway.ziqni.com'
        },
        language: 'en',
        currency: ''
      };
    }

    this.settings = {
      apiKey: '', // default API key
      spaceName: 'my_space_name', // default space name
      enforceGameLookup: true, // default enforce game lookup
      language: 'en', // default language setting
      currency: '', // default currency setting

      // default script that will be loaded
      defaultScript: 'https://ziqni.cdn.ziqni.com/ziqni-tech/gamification-ux-package/_widgets/gamification-ux-package/build/javascript/gamification-ux-package.v3-selfinit.js',

      // default stylesheet resources that will be loaded
      defaultResources: [
        'https://ziqni.cdn.ziqni.com/ziqni-tech/gamification-ux-package/_widgets/gamification-ux-package/build/css/theme/cl-style-1-default-theme.css'
      ],

      // forces widget to load if no specific product defined
      loadWidgetIfNoProductsFound: true,

      // product specific configuration that will be loaded overwriting the default scripts and resources
      products: {
        my_product_id: {
          // script: "",
          // resources: [],
          onBeforeLoad: function (instance, options, callback) { // your custom logic before the widget gets initialised/rendered
            if (typeof callback === 'function') callback();
          }
        }
      }
    };

    /**
     * Load in external scripts
     * @param options
     * @param callback
     * @param errorCallback
     */
    this.loadScript = function (options, callback, errorCallback) {
      var _this = this;
      var script = document.createElement('script');
      script.setAttribute('type', 'text/javascript');
      script.setAttribute('src', ((typeof options.script === 'string' && options.script.length > 0) ? options.script : _this.settings.defaultScript));

      script.onload = function () {
        callback();
      };

      script.onerror = function (e) {
        console.log('widget not loaded');

        if (typeof errorCallback !== 'undefined') {
          errorCallback();
        }
      };

      document.body.appendChild(script);
    };

    /**
     * Initialises widget with global and custom parameters
     * @param product
     */
    this.initialiseWidget = function (product) {
      var _this = this;

      _this.loadScript(product, function () {
        if (typeof window._clLeaderBoardV3SelfInit !== 'undefined') {
          var settings = window._CLLBV3Opt;
          settings.resources = (typeof product.resources !== 'undefined' ? product.resources : _this.settings.defaultResources);

          if (typeof settings.apiKey === 'undefined') { settings.apiKey = _this.settings.apiKey; }
          if (typeof settings.spaceName === 'undefined') { settings.spaceName = _this.settings.spaceName; }
          if (typeof settings.enforceGameLookup === 'undefined') { settings.enforceGameLookup = _this.settings.enforceGameLookup; }
          if (typeof settings.language === 'undefined') { settings.language = _this.settings.language; }
          if (typeof settings.currency === 'undefined') { settings.currency = _this.settings.currency; }

          window._clLeaderBoardV3 = new window._clLeaderBoardV3SelfInit(settings);

          if (typeof product.onBeforeLoad === 'function') {
            product.onBeforeLoad(_this, product, function () {
              window._clLeaderBoardV3.init();
            });
          } else {
            window._clLeaderBoardV3.init();
          }
        } else {
          console.log('widget does not exist');
        }
      });
    };

    this.init = function () {
      var _this = this;

      if (typeof window._CLLBV3Opt !== 'undefined' && typeof window._CLLBV3Opt.gameId === 'string') {
        var found = false;
        mapObject(_this.settings.products, function (product, key) {
          if (key === window._CLLBV3Opt.gameId && !found) {
            found = true;
            _this.initialiseWidget(product);
          }
        });

        // if not found and loadWidgetIfNoProductsFound is true initialise widget
        if (!found && _this.settings.loadWidgetIfNoProductsFound) {
          _this.initialiseWidget({
            script: _this.settings.defaultScript,
            resources: _this.settings.defaultResources
          });
        }
      }
    };
  };

  /* eslint new-cap: "off" */
  new loadScript().init();
})();