API Documentation for: 1.0.1
Show:

File:Debug.js

  1. (function(window, undefined){
  2. /**
  3. * A static closure to provide easy access to the console
  4. * without having errors if the console doesn't exist
  5. * to use call: Debug.log('Your log here')
  6. *
  7. * @class Debug
  8. * @static
  9. */
  10. var Debug = function(){};
  11. /**
  12. * If we have a console
  13. *
  14. * @private
  15. * @property {bool} hasConsole
  16. */
  17. var hasConsole = (window.console !== undefined);
  18. /**
  19. * The most general default debug level
  20. * @static
  21. * @final
  22. * @property {int} GENERAL
  23. */
  24. Debug.GENERAL = 0;
  25. /**
  26. * Log level for debug messages
  27. * @static
  28. * @final
  29. * @property {int} DEBUG
  30. */
  31. Debug.DEBUG = 1;
  32. /**
  33. * Log level for debug messages
  34. * @static
  35. * @final
  36. * @property {int} INFO
  37. */
  38. Debug.INFO = 2;
  39. /**
  40. * Log level for warning messages
  41. * @static
  42. * @final
  43. * @property {int} WARN
  44. */
  45. Debug.WARN = 3;
  46. /**
  47. * Log level for error messages
  48. * @static
  49. * @final
  50. * @property {int} ERROR
  51. */
  52. Debug.ERROR = 4;
  53. /**
  54. * The minimum log level to show, by default it's set to
  55. * show all levels of logging.
  56. * @public
  57. * @static
  58. * @property {int} minLogLevel
  59. */
  60. Debug.minLogLevel = Debug.GENERAL;
  61. /**
  62. * Boolean to turn on or off the debugging
  63. * @public
  64. * @static
  65. * @property {bool} enabled
  66. */
  67. Debug.enabled = true;
  68. /**
  69. * The jQuery element to output debug messages to
  70. *
  71. * @public
  72. * @static
  73. * @property {jQuery} output
  74. */
  75. Debug.output = null;
  76.  
  77. /**
  78. * If the console is currently connected with JSConsole (jsconsole.com).
  79. * @private
  80. * @static
  81. * @property {bool} _isJSConsole
  82. */
  83. Debug._isJSConsole = window.remote === window.console;//The JSConsole script sets one object as 'remote' and trys to overwrite 'console'
  84. /**
  85. * Browser port for the websocket browsers tend to block ports
  86. * @static
  87. * @private
  88. * @property {int} _NET_PORT
  89. * @default 1025
  90. */
  91. Debug._NET_PORT = 1025;
  92. /**
  93. * If the web socket is connected
  94. * @static
  95. * @private
  96. * @default false
  97. * @property {bool} _isConnected
  98. */
  99. Debug._isConnected = false;
  100. /**
  101. * The socket connection
  102. * @static
  103. * @private
  104. * @property {WebSocket} _socket
  105. */
  106. Debug._socket = null;
  107. /**
  108. * The current message object being sent to the `WebSocket`
  109. * @static
  110. * @private
  111. * @property {object} _messageObj
  112. */
  113. Debug._messageObj = null;
  114. /**
  115. * The `WebSocket` message queue
  116. * @static
  117. * @private
  118. * @property {Array} _messageQueue
  119. */
  120. Debug._messageQueue = null;
  121. /**
  122. * Connect to the `WebSocket`
  123. * @public
  124. * @static
  125. * @method connect
  126. * @param {string} The IP address to connect to
  127. */
  128. Debug.connect = function(ipAddr)
  129. {
  130. // Make sure WebSocket exists without prefixes for us
  131. if(!("WebSocket" in window) && !("MozWebSocket" in window)) return false;
  132. window.WebSocket = WebSocket || MozWebSocket;
  133. try
  134. {
  135. var s = Debug._socket = new WebSocket("ws://" + ipAddr + ":" + Debug._NET_PORT);
  136. s.onopen = onConnect;
  137. s.onmessage = function(){};
  138. s.onclose = onClose;
  139. s.onerror = onClose;
  140. Debug._messageQueue = [];
  141. Debug._isConnected = true;
  142. }
  143. catch(error)
  144. {
  145. return false;
  146. }
  147. return true;
  148. };
  149. /**
  150. * Disconnect from the `WebSocket`
  151. * @public
  152. * @static
  153. * @method disconnect
  154. */
  155. Debug.disconnect = function()
  156. {
  157. if(Debug._isConnected)
  158. {
  159. Debug._socket.close();
  160. onClose();
  161. }
  162. };
  163. /**
  164. * Callback when the `WebSocket` is connected
  165. * @private
  166. * @static
  167. * @method onConnect
  168. */
  169. var onConnect = function()
  170. {
  171. // set up a function to handle all messages
  172. window.onerror = globalErrorHandler;
  173. // create and send a new session message
  174. Debug._messageObj = {level:"session", message:""};
  175. Debug._socket.send(JSON.stringify(Debug._messageObj));
  176. // send any queued logs
  177. for(var i = 0; i < Debug._messageQueue.length; ++i)
  178. {
  179. Debug._socket.send(JSON.stringify(Debug._messageQueue[i]));
  180. }
  181. // get rid of this, since we are connected
  182. Debug._messageQueue = null;
  183. };
  184. /**
  185. * Global window error handler
  186. * @static
  187. * @private
  188. * @method globalErrorHandler
  189. * @param THe error message
  190. * @param The url of the file
  191. * @param The line within the file
  192. */
  193. var globalErrorHandler = function(errorMsg, url, lineNumber)
  194. {
  195. Debug.remoteLog("Error: " + errorMsg + " in " + url + " at line " + lineNumber, "ERROR");
  196. return false;
  197. };
  198. /**
  199. * Callback for when the websocket is closed
  200. * @private
  201. * @static
  202. * @method onClose
  203. */
  204. var onClose = function()
  205. {
  206. window.onerror = null;
  207. Debug._isConnected = false;
  208. var s = Debug._socket;
  209. s.onopen = null;
  210. s.onmessage = null;
  211. s.onclose = null;
  212. s.onerror = null;
  213. Debug._socket = null;
  214. Debug._messageObj = null;
  215. Debug._messageQueue = null;
  216. };
  217. /**
  218. * Sent to the output
  219. * @private
  220. * @static
  221. * @method output
  222. * @param {string} level The log level
  223. * @param {string} args Additional arguments
  224. */
  225. function output(level, args)
  226. {
  227. if (Debug.output)
  228. {
  229. Debug.output.append("<div class=\""+level+"\">" + args + "</div>");
  230. }
  231. }
  232. /**
  233. * Send a remote log message using the socket connection
  234. * @public
  235. * @static
  236. * @method remoteLog
  237. * @param {string} message The message to send
  238. * @param {level} level The log level to send
  239. */
  240. Debug.remoteLog = function(message, level)
  241. {
  242. if(!level)
  243. level = "GENERAL";
  244. if(Debug._messageQueue)//If we are still in the process of connecting, queue up the log
  245. {
  246. Debug._messageQueue.push({message:message, level:level});
  247. }
  248. else//send the log immediately
  249. {
  250. Debug._messageObj.level = level;
  251. Debug._messageObj.message = message;
  252. Debug._socket.send(JSON.stringify(Debug._messageObj));
  253. }
  254. };
  255.  
  256. function JSC_stringify(obj, depth)
  257. {
  258. if(!depth)
  259. depth = 1;
  260. var spacing = "";
  261. var endSpacing = "";
  262. for(var i = 0; i < depth * 4; ++i)
  263. {
  264. spacing += "&nbsp;";
  265. if(i < (depth - 1) * 4)
  266. endSpacing += "&nbsp;";
  267. }
  268. var rtn = "{<br />";
  269. for(var key in obj)
  270. {
  271. //avoid doing properties that are known to be DOM objects, because those have circular references
  272. if(key == "document" || key == "window" || key == "ownerDocument" || key == "view")
  273. continue;
  274. if(key == "target" || key == "currentTarget" || key == "originalTarget" || key == "explicitOriginalTarget" || key == "rangeParent")
  275. continue;
  276. if(key == "srcElement" || key == "relatedTarget" || key == "fromElement" || key == "toElement")
  277. continue;
  278. switch(typeof obj[key])
  279. {
  280. case "string":
  281. case "number":
  282. case "boolean":
  283. case "bool":
  284. rtn += spacing + key + ": " + obj[key] + "<br />";
  285. break;
  286. case "object":
  287. rtn += spacing + key + ": " + JSC_stringify(obj[key], depth + 1) + "<br />";
  288. break;
  289. case "function":
  290. rtn += spacing + key + ": (function)<br />";
  291. break;
  292. default:
  293. rtn += spacing + key + ": " + obj[key] + "<br />";
  294. break;
  295. }
  296. }
  297. rtn += endSpacing + "}";
  298. return rtn;
  299. }
  300.  
  301. function JSC_format(input)
  302. {
  303. if(typeof input == "string")
  304. {
  305. return input.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;").replace(/\n/g, "<br />");
  306. }
  307. else if(typeof input == "object")
  308. {
  309. return JSC_stringify(input);
  310. }
  311. return input;
  312. }
  313. /**
  314. * Log something in the console or remote
  315. * @static
  316. * @public
  317. * @method log
  318. * @param {*} params The statement or object to log
  319. */
  320. Debug.log = function(params)
  321. {
  322. if(!Debug.enabled) return;
  323. if(Debug._isConnected)
  324. {
  325. Debug.remoteLog(params, "GENERAL");
  326. }
  327. else if (Debug.minLogLevel == Debug.GENERAL && hasConsole)
  328. {
  329. console.log(Debug._isJSConsole ? JSC_format(params) : params);
  330. output("general", params);
  331. }
  332. };
  333. /**
  334. * Debug something in the console or remote
  335. * @static
  336. * @public
  337. * @method debug
  338. * @param {*} params The statement or object to debug
  339. */
  340. Debug.debug = function(params)
  341. {
  342. if(!Debug.enabled) return;
  343. if(Debug._isConnected)
  344. {
  345. Debug.remoteLog(params, "DEBUG");
  346. }
  347. else if (Debug.minLogLevel <= Debug.DEBUG && hasConsole)
  348. {
  349. console.debug(Debug._isJSConsole ? JSC_format(params) : params);
  350. output("debug", params);
  351. }
  352. };
  353. /**
  354. * Info something in the console or remote
  355. * @static
  356. * @public
  357. * @method info
  358. * @param {*} params The statement or object to info
  359. */
  360. Debug.info = function(params)
  361. {
  362. if(!Debug.enabled) return;
  363. if(Debug._isConnected)
  364. {
  365. Debug.remoteLog(params, "INFO");
  366. }
  367. else if (Debug.minLogLevel <= Debug.INFO && hasConsole)
  368. {
  369. console.info(Debug._isJSConsole ? JSC_format(params) : params);
  370. output("info", params);
  371. }
  372. };
  373. /**
  374. * Warn something in the console or remote
  375. * @static
  376. * @public
  377. * @method warn
  378. * @param {*} params The statement or object to warn
  379. */
  380. Debug.warn = function(params)
  381. {
  382. if(!Debug.enabled) return;
  383. if(Debug._isConnected)
  384. {
  385. Debug.remoteLog(params, "WARNING");
  386. }
  387. else if (Debug.minLogLevel <= Debug.WARN && hasConsole)
  388. {
  389. console.warn(Debug._isJSConsole ? JSC_format(params) : params);
  390. output("warn", params);
  391. }
  392. };
  393. /**
  394. * Error something in the console or remote
  395. * @static
  396. * @public
  397. * @method error
  398. * @param {*} params The statement or object to error
  399. */
  400. Debug.error = function(params)
  401. {
  402. if(!Debug.enabled) return;
  403. if(Debug._isConnected)
  404. {
  405. Debug.remoteLog(params, "ERROR");
  406. }
  407. else if (hasConsole)
  408. {
  409. console.error(Debug._isJSConsole ? JSC_format(params) : params);
  410. output("error", params);
  411. }
  412. };
  413. /**
  414. * Assert that something is true
  415. * @static
  416. * @public
  417. * @method assert
  418. * @param {bool} truth As statement that is assumed true
  419. * @param {*} params The message to error if the assert is false
  420. */
  421. Debug.assert = function(truth, params)
  422. {
  423. if (hasConsole && Debug.enabled && console.assert)
  424. {
  425. console.assert(truth, Debug._isJSConsole ? JSC_format(params) : params);
  426. if (!truth) output("error", params);
  427. }
  428. };
  429. /**
  430. * Method to describe an object in the console
  431. * @static
  432. * @method dir
  433. * @public
  434. * @param {object} params The object to describe in the console
  435. */
  436. Debug.dir = function(params)
  437. {
  438. if (Debug.minLogLevel == Debug.GENERAL && hasConsole && Debug.enabled)
  439. {
  440. console.dir(Debug._isJSConsole ? JSC_format(params) : params);
  441. }
  442. };
  443. /**
  444. * Method to clear the console
  445. *
  446. * @static
  447. * @public
  448. * @method clear
  449. */
  450. Debug.clear = function()
  451. {
  452. if (hasConsole && Debug.enabled)
  453. {
  454. console.clear();
  455. if (Debug.output) Debug.output.html("");
  456. }
  457. };
  458. /**
  459. * Generate a stack track in the output
  460. * @static
  461. * @public
  462. * @method trace
  463. * @param {*} params Optional parameters to log
  464. */
  465. Debug.trace = function(params)
  466. {
  467. if (Debug.minLogLevel == Debug.GENERAL && hasConsole && Debug.enabled)
  468. {
  469. console.trace(Debug._isJSConsole ? JSC_format(params) : params);
  470. }
  471. };
  472. // Make the debug class globally accessible
  473. // If the console doesn't exist, use the dummy to prevent errors
  474. window.Debug = Debug;
  475. }(window));