File: source/skylink-debug.js

                      /**
                       * The list of the SDK <code>console</code> API log levels.
                       * @attribute LOG_LEVEL
                       * @param {Number} DEBUG <small>Value <code>4</code></small>
                       *   The value of the log level that displays <code>console</code> <code>debug</code>,
                       *   <code>log</code>, <code>info</code>, <code>warn</code> and <code>error</code> logs.
                       * @param {Number} LOG   <small>Value <code>3</code></small>
                       *   The value of the log level that displays only <code>console</code> <code>log</code>,
                       *   <code>info</code>, <code>warn</code> and <code>error</code> logs.
                       * @param {Number} INFO  <small>Value <code>2</code></small>
                       *   The value of the log level that displays only <code>console</code> <code>info</code>,
                       *   <code>warn</code> and <code>error</code> logs.
                       * @param {Number} WARN  <small>Value <code>1</code></small>
                       *   The value of the log level that displays only <code>console</code> <code>warn</code>
                       *   and <code>error</code> logs.
                       * @param {Number} ERROR <small>Value <code>0</code></small>
                       *   The value of the log level that displays only <code>console</code> <code>error</code> logs.
                       * @param {Number} NONE <small>Value <code>-1</code></small>
                       *   The value of the log level that displays no logs.
                       * @type JSON
                       * @readOnly
                       * @for Skylink
                       * @since 0.5.4
                       */
                      Skylink.prototype.LOG_LEVEL = {
                        DEBUG: 4,
                        LOG: 3,
                        INFO: 2,
                        WARN: 1,
                        ERROR: 0,
                        NONE: -1
                      };
                      
                      /**
                       * Stores the log message starting header string.
                       * E.g. "<header> - <the log message>".
                       * @attribute _LOG_KEY
                       * @type String
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.4
                       */
                      var _LOG_KEY = 'SkylinkJS';
                      
                      /**
                       * Stores the list of available SDK log levels.
                       * @attribute _LOG_LEVELS
                       * @type Array
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _LOG_LEVELS = ['error', 'warn', 'info', 'log', 'debug'];
                      
                      /**
                       * Stores the current SDK log level.
                       * Default is ERROR (<code>0</code>).
                       * @attribute _logLevel
                       * @type String
                       * @default 0
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.4
                       */
                      var _logLevel = 0;
                      
                      /**
                       * Stores the flag if debugging mode is enabled.
                       * This manipulates the SkylinkLogs interface.
                       * @attribute _enableDebugMode
                       * @type Boolean
                       * @default false
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.4
                       */
                      var _enableDebugMode = false;
                      
                      /**
                       * Stores the flag if logs should be stored in SkylinkLogs interface.
                       * @attribute _enableDebugStack
                       * @type Boolean
                       * @default false
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _enableDebugStack = false;
                      
                      /**
                       * Stores the flag if logs should trace if available.
                       * This uses the <code>console.trace</code> API.
                       * @attribute _enableDebugTrace
                       * @type Boolean
                       * @default false
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _enableDebugTrace = false;
                      
                      /**
                       * Stores the logs used for SkylinkLogs object.
                       * @attribute _storedLogs
                       * @type Array
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _storedLogs = [];
                      
                      /**
                       * Function that gets the stored logs.
                       * @method _getStoredLogsFn
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _getStoredLogsFn = function (logLevel) {
                        if (typeof logLevel === 'undefined') {
                          return _storedLogs;
                        }
                        var returnLogs = [];
                        for (var i = 0; i < _storedLogs.length; i++) {
                          if (_storedLogs[i][1] === _LOG_LEVELS[logLevel]) {
                            returnLogs.push(_storedLogs[i]);
                          }
                        }
                        return returnLogs;
                      };
                      
                      /**
                       * Function that clears the stored logs.
                       * @method _clearAllStoredLogsFn
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _clearAllStoredLogsFn = function () {
                        _storedLogs = [];
                      };
                      
                      /**
                       * Function that prints in the Web Console interface the stored logs.
                       * @method _printAllStoredLogsFn
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _printAllStoredLogsFn = function () {
                        for (var i = 0; i < _storedLogs.length; i++) {
                          var timestamp = _storedLogs[i][0];
                          var log = (console[_storedLogs[i][1]] !== 'undefined') ?
                            _storedLogs[i][1] : 'log';
                          var message = _storedLogs[i][2];
                          var debugObject = _storedLogs[i][3];
                      
                          if (typeof debugObject !== 'undefined') {
                            console[log](message, debugObject, timestamp);
                          } else {
                            console[log](message, timestamp);
                          }
                        }
                      };
                      
                      /**
                       * <blockquote class="info">
                       *   To utilise and enable the <code>SkylinkLogs</code> API functionalities, the
                       *   <a href="#method_setDebugMode"><code>setDebugMode()</code> method</a>
                       *   <code>options.storeLogs</code> parameter has to be enabled.
                       * </blockquote>
                       * The object interface to manage the SDK <a href="https://developer.mozilla.org/en/docs/Web/API/console">
                       * Javascript Web Console</a> logs.
                       * @property SkylinkLogs
                       * @type JSON
                       * @global true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var SkylinkLogs = {
                        /**
                         * Function that gets the current stored SDK <code>console</code> logs.
                         * @property SkylinkLogs.getLogs
                         * @param {Number} [logLevel] The specific log level of logs to return.
                         * - When not provided or that the level does not exists, it will return all logs of all levels.
                         *  [Rel: Skylink.LOG_LEVEL]
                         * @return {Array} The array of stored logs.<ul>
                         *   <li><code><#index></code><var><b>{</b>Array<b>}</b></var><p>The stored log item.</p><ul>
                         *   <li><code>0</code><var><b>{</b>Date<b>}</b></var><p>The DateTime of when the log was stored.</p></li>
                         *   <li><code>1</code><var><b>{</b>String<b>}</b></var><p>The log level. [Rel: Skylink.LOG_LEVEL]</p></li>
                         *   <li><code>2</code><var><b>{</b>String<b>}</b></var><p>The log message.</p></li>
                         *   <li><code>3</code><var><b>{</b>Any<b>}</b></var><span class="label">Optional</span><p>The log message object.
                         *   </p></li></ul></li></ul>
                         * @example
                         *  // Example 1: Get logs of specific level
                         *  var debugLogs = SkylinkLogs.getLogs(skylinkDemo.LOG_LEVEL.DEBUG);
                         *
                         *  // Example 2: Get all the logs
                         *  var allLogs = SkylinkLogs.getLogs();
                         * @type Function
                         * @global true
                         * @triggerForPropHackNone true
                         * @for Skylink
                         * @since 0.5.5
                         */
                        getLogs: _getStoredLogsFn,
                      
                        /**
                         * Function that clears all the current stored SDK <code>console</code> logs.
                         * @property SkylinkLogs.clearAllLogs
                         * @type Function
                         * @example
                         *   // Example 1: Clear all the logs
                         *   SkylinkLogs.clearAllLogs();
                         * @global true
                         * @triggerForPropHackNone true
                         * @for Skylink
                         * @since 0.5.5
                         */
                        clearAllLogs: _clearAllStoredLogsFn,
                      
                        /**
                         * Function that prints all the current stored SDK <code>console</code> logs into the
                         * <a href="https://developer.mozilla.org/en/docs/Web/API/console">Javascript Web Console</a>.
                         * @property SkylinkLogs.printAllLogs
                         * @type Function
                         * @example
                         *   // Example 1: Print all the logs
                         *   SkylinkLogs.printAllLogs();
                         * @global true
                         * @triggerForPropHackNone true
                         * @for Skylink
                         * @since 0.5.5
                         */
                        printAllLogs: _printAllStoredLogsFn
                      };
                      
                      /**
                       * Function that handles the logs received and prints in the Web Console interface according to the log level set.
                       * @method _logFn
                       * @private
                       * @required
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.5
                       */
                      var _logFn = function(logLevel, message, debugObject) {
                        var outputLog = _LOG_KEY;
                      
                        if (typeof message === 'object') {
                          outputLog += (message[0]) ? ' [' + message[0] + '] -' : ' -';
                          outputLog += (message[1]) ? ' <<' + message[1] + '>>' : '';
                          if (message[2]) {
                            outputLog += ' ';
                            if (typeof message[2] === 'object') {
                              for (var i = 0; i < message[2].length; i++) {
                                outputLog += '(' + message[2][i] + ')';
                              }
                            } else {
                              outputLog += '(' + message[2] + ')';
                            }
                          }
                          outputLog += ' ' + message[3];
                        } else {
                          outputLog += ' - ' + message;
                        }
                      
                        if (_enableDebugMode && _enableDebugStack) {
                          // store the logs
                          var logItem = [(new Date()), _LOG_LEVELS[logLevel], outputLog];
                      
                          if (typeof debugObject !== 'undefined') {
                            logItem.push(debugObject);
                          }
                          _storedLogs.push(logItem);
                        }
                      
                        if (_logLevel >= logLevel) {
                          // Fallback to log if failure
                          logLevel = (typeof console[_LOG_LEVELS[logLevel]] === 'undefined') ? 3 : logLevel;
                      
                          if (_enableDebugMode && _enableDebugTrace) {
                            var logConsole = (typeof console.trace === 'undefined') ? logLevel[3] : 'trace';
                            if (typeof debugObject !== 'undefined') {
                              console[_LOG_LEVELS[logLevel]](outputLog, debugObject);
                              // output if supported
                              if (typeof console.trace !== 'undefined') {
                                console.trace('');
                              }
                            } else {
                              console[_LOG_LEVELS[logLevel]](outputLog);
                              // output if supported
                              if (typeof console.trace !== 'undefined') {
                                console.trace('');
                              }
                            }
                          } else {
                            if (typeof debugObject !== 'undefined') {
                              console[_LOG_LEVELS[logLevel]](outputLog, debugObject);
                            } else {
                              console[_LOG_LEVELS[logLevel]](outputLog);
                            }
                          }
                        }
                      };
                      
                      /**
                       * Stores the logging functions.
                       * @attribute log
                       * @param {Function} debug The function that handles the DEBUG level logs.
                       * @param {Function} log The function that handles the LOG level logs.
                       * @param {Function} info The function that handles the INFO level logs.
                       * @param {Function} warn The function that handles the WARN level logs.
                       * @param {Function} error The function that handles the ERROR level logs.
                       * @type JSON
                       * @private
                       * @scoped true
                       * @for Skylink
                       * @since 0.5.4
                       */
                      var log = {
                        debug: function (message, object) {
                          _logFn(4, message, object);
                        },
                      
                        log: function (message, object) {
                          _logFn(3, message, object);
                        },
                      
                        info: function (message, object) {
                          _logFn(2, message, object);
                        },
                      
                        warn: function (message, object) {
                          _logFn(1, message, object);
                        },
                      
                        error: function (message, object) {
                          _logFn(0, message, object);
                        }
                      };
                      
                      /**
                       * Function that configures the level of <code>console</code> API logs to be printed in the
                       * <a href="https://developer.mozilla.org/en/docs/Web/API/console">Javascript Web Console</a>.
                       * @method setLogLevel
                       * @param {Number} [logLevel] The specific log level of logs to return.
                       * - When not provided or that the level does not exists, it will not overwrite the current log level.
                       *   <small>By default, the initial log level is <code>ERROR</code>.</small>
                       *   [Rel: Skylink.LOG_LEVEL]
                       * @example
                       *   // Example 1: Print all of the console.debug, console.log, console.info, console.warn and console.error logs.
                       *   skylinkDemo.setLogLevel(skylinkDemo.LOG_LEVEL.DEBUG);
                       *
                       *   // Example 2: Print only the console.log, console.info, console.warn and console.error logs.
                       *   skylinkDemo.setLogLevel(skylinkDemo.LOG_LEVEL.LOG);
                       *
                       *   // Example 3: Print only the console.info, console.warn and console.error logs.
                       *   skylinkDemo.setLogLevel(skylinkDemo.LOG_LEVEL.INFO);
                       *
                       *   // Example 4: Print only the console.warn and console.error logs.
                       *   skylinkDemo.setLogLevel(skylinkDemo.LOG_LEVEL.WARN);
                       *
                       *   // Example 5: Print only the console.error logs. This is done by default.
                       *   skylinkDemo.setLogLevel(skylinkDemo.LOG_LEVEL.ERROR);
                       * @for Skylink
                       * @since 0.5.5
                       */
                      Skylink.prototype.setLogLevel = function(logLevel) {
                        if(logLevel === undefined) {
                          logLevel = Skylink.LOG_LEVEL.WARN;
                        }
                        for (var level in this.LOG_LEVEL) {
                          if (this.LOG_LEVEL[level] === logLevel) {
                            _logLevel = logLevel;
                            log.log([null, 'Log', level, 'Log level exists. Level is set']);
                            return;
                          }
                        }
                        log.error([null, 'Log', level, 'Log level does not exist. Level is not set']);
                      };
                      
                      /**
                       * Function that configures the debugging mode of the SDK.
                       * @method setDebugMode
                       * @param {Boolean|JSON} [options=false] The debugging options.
                       * - When provided as a boolean, this sets both <code>options.trace</code>
                       *   and <code>options.storeLogs</code> to its boolean value.
                       * @param {Boolean} [options.trace=false] The flag if SDK <code>console</code> logs
                       *   should output as <code>console.trace()</code> logs for tracing the <code>Function</code> call stack.
                       *   <small>Note that the <code>console.trace()</code> output logs is determined by the log level set
                       *   <a href="#method_setLogLevel"><code>setLogLevel()</code> method</a>.</small>
                       *   <small>If <code>console.trace()</code> API is not supported, <code>setDebugMode()</code>
                       *   will fallback to use <code>console.log()</code> API.</small>
                       * @param {Boolean} [options.storeLogs=false] The flag if SDK should store the <code>console</code> logs.
                       *   <small>This is required to be enabled for <a href="#prop_SkylinkLogs"><code>SkylinkLogs</code> API</a>.</small>
                       * @example
                       *   // Example 1: Enable both options.storeLogs and options.trace
                       *   skylinkDemo.setDebugMode(true);
                       *
                       *   // Example 2: Enable only options.storeLogs
                       *   skylinkDemo.setDebugMode({ storeLogs: true });
                       *
                       *   // Example 3: Disable debugging mode
                       *   skylinkDemo.setDebugMode();
                       * @for Skylink
                       * @since 0.5.2
                       */
                      Skylink.prototype.setDebugMode = function(isDebugMode) {
                        if (typeof isDebugMode === 'object') {
                          if (Object.keys(isDebugMode).length > 0) {
                            _enableDebugTrace = !!isDebugMode.trace;
                            _enableDebugStack = !!isDebugMode.storeLogs;
                          } else {
                            _enableDebugMode = false;
                            _enableDebugTrace = false;
                            _enableDebugStack = false;
                          }
                        }
                        if (isDebugMode === false) {
                          _enableDebugMode = false;
                          _enableDebugTrace = false;
                          _enableDebugStack = false;
                      
                          return;
                        }
                        _enableDebugMode = true;
                        _enableDebugTrace = true;
                        _enableDebugStack = true;
                      };