1 /** 2 * Socketbug - Web Socket Remote Debugging 3 * 4 * Copyright (c) 2011 Manifest Interactive, LLC 5 * 6 * Licensed under the LGPL v3 licenses. 7 * 8 * @version v0.2.1 ( 7/4/2011 ) 9 * 10 * @author <a href="http://www.socketbug.com">Website</a> 11 * @author <a href="http://www.vimeo.com/user7532036/videos">Video Tutorials ( HD )</a> 12 * @author <a href="http://www.twitter.com/socketbug_dev">Twitter</a> 13 * @author <a href="http://github.com/manifestinteractive/socketbug">Source Code</a> 14 * @author <a href="http://socketbug.userecho.com">Support & Feature Requests</a> 15 */ 16 17 if(typeof(socketbug) === 'undefined') 18 { 19 /** 20 * @private 21 */ 22 var _encryption_salt = 'Ch4ng3^M3'; 23 24 /** 25 * @namespace Socketbug Console 26 */ 27 var socketbug = { 28 29 /** 30 * Check if we're connected to Socketbug 31 * 32 * @param {Boolean} connected 33 */ 34 connected: false, 35 36 /** 37 * Store Socketbug Session ID 38 * 39 * @param {String} session_id 40 */ 41 session_id: null, 42 43 /** 44 * Define Group Data 45 * 46 * @param {Object} group 47 */ 48 group: 49 { 50 'id': hex_md5(_encryption_salt + _sbs.group_id), 51 'name': _sbs.group_name 52 }, 53 54 /** 55 * Define Application Data 56 * 57 * @param {Object} application 58 */ 59 application: 60 { 61 'id': hex_md5(_encryption_salt + _sbs.application_id), 62 'name': _sbs.application_name 63 }, 64 65 /** 66 * Define Client Data 67 * 68 * @param {Object} client 69 */ 70 client: 71 { 72 'id': hex_md5(_encryption_salt + GUID.create()), 73 'name': '' 74 }, 75 76 /** 77 * Debug Level 78 * 79 * @example 5 = log, debug, info, warn, & error 80 * @example 4 = debug, info, warn, & error 81 * @example 3 = info, warn, & error 82 * @example 2 = warn, & error 83 * @example 1 = error 84 * @example 0 = disable all debug messages 85 * 86 * @param {Number} debug_level This is set in the HTML Configuration 87 */ 88 debug_level: _sbs.debug_level, 89 90 /** Socketbug Server Comminication */ 91 sb_manager: io.connect(_sbs.host + ':' + _sbs.port + '/sb_manager'), 92 93 /** Socketbug Appliction Comminication */ 94 sb_application: io.connect(_sbs.host + ':' + _sbs.port + '/sb_application'), 95 96 /** Socketbug Console Comminication */ 97 sb_console: io.connect(_sbs.host + ':' + _sbs.port + '/sb_console'), 98 99 /** 100 * Setup Ouput Log for Console 101 * 102 * @function 103 * @param {String} message This is the message to Log 104 * @param {String} level The is the Debug Level 105 * @param {String} mode This is the Mode ( application | console ) 106 */ 107 log: function(message, level, mode) 108 { 109 /* Prepare Variables for the Log */ 110 var now = new Date(); 111 var date = dateFormat(now, "yyyy-mm-dd HH:MM:ss"); 112 var sb_mode = (typeof(mode) == 'undefined') ? 'console':mode; 113 var css_class_prefix = (sb_mode == 'console') ? 'con_debug_':'app_debug_'; 114 115 /* Remove all Recent Classes from Log List */ 116 jQuery('#output ul li').removeClass('recent'); 117 118 /* Determine the Log Level so we can Customize it for our Ouput */ 119 switch(level) 120 { 121 case 'log': 122 if(_sbs.debug_level == 5) 123 { 124 jQuery('#output ul').prepend('<li class="recent ' + css_class_prefix + level + '" style="display: none;"><span>[ ' + date + ' ]</span> ' + message + '</li>'); 125 } 126 break; 127 128 case 'debug': 129 if(_sbs.debug_level >= 4) 130 { 131 jQuery('#output ul').prepend('<li class="recent ' + css_class_prefix + level + '" style="display: none;"><span>[ ' + date + ' ]</span> ' + message + '</li>'); 132 } 133 break; 134 135 case 'info': 136 if(_sbs.debug_level >= 3) 137 { 138 jQuery('#output ul').prepend('<li class="recent ' + css_class_prefix + level + '" style="display: none;"><span>[ ' + date + ' ]</span> ' + message + '</li>'); 139 } 140 break; 141 142 case 'warn': 143 if(_sbs.debug_level >= 2) 144 { 145 jQuery('#output ul').prepend('<li class="recent ' + css_class_prefix + level + '" style="display: none;"><span>[ ' + date + ' ]</span> <span class="warn">' + message + '</span></li>'); 146 } 147 break; 148 149 case 'error': 150 if(_sbs.debug_level >= 1) 151 { 152 jQuery('#output ul').prepend('<li class="recent ' + css_class_prefix + level + '" style="display: none;"><span>[ ' + date + ' ]</span> <span class="error">' + message + '</span></li>'); 153 } 154 break; 155 } 156 157 /* Fade in New Log Entry */ 158 jQuery('.recent').fadeIn(); 159 160 }, 161 162 /** 163 * Send Javascript Command 164 * 165 * @function 166 * @param {String} javascript Command to Execute 167 */ 168 js: function(javascript) 169 { 170 /** 171 * Fun Times for those who viewed this Source Code 172 * Some Magical Word unlocks the Awesomeness ... 173 * Good Luck, and FYI, You Rock! But you already know that ;) 174 */ 175 if(hex_md5(javascript) == '93bdae2e846d2c226c8c2c201e15ffdb') 176 { 177 /* Add Custom Class */ 178 jQuery('#watermark').addClass('its_alive'); 179 180 /* Set Timeout to Remove Class so we can repeat this later */ 181 setTimeout(function(){ jQuery('#watermark').removeClass('its_alive'); }, 5100); 182 183 socketbug.log('<span class="value">IT\'S ALIVE!!!</span>', 'error', 'console'); 184 185 jQuery('#command').val('').blur(); 186 187 /* Exit */ 188 return true; 189 } 190 else 191 { 192 /* Start Loading Animation */ 193 jQuery('#loading').fadeIn('fast'); 194 195 /* Send JSON to Socketbug Server */ 196 socketbug.sb_application.emit('execute_js', javascript, 197 function() 198 { 199 jQuery('#loading').fadeOut('fast'); 200 socketbug.log('Executed Remote Javascript: <span class="value">' + javascript + '</span>', 'info', 'console'); 201 } 202 ); 203 } 204 }, 205 206 /** 207 * Get Source Code 208 * 209 * @function 210 */ 211 view_source: function() 212 { 213 /** Start Loading Animation */ 214 jQuery('#loading').fadeIn('fast'); 215 216 /** Send JSON to Socketbug Server */ 217 socketbug.sb_application.emit('view_source', 218 function() 219 { 220 socketbug.log('Fetching Remote Source Code...', 'info', 'console'); 221 } 222 ); 223 } 224 }; 225 226 /** 227 * Capture Connecting Event 228 * 229 * @function 230 * @param {String} transport_type Connecting Transport Type 231 */ 232 socketbug.sb_manager.on('connecting', function (transport_type) 233 { 234 socketbug.log('Attempting to connect to Socketbug via ' + transport_type + '...', 'log', 'console'); 235 socketbug.connected = false; 236 }); 237 238 /** 239 * Capture Connect Event 240 * 241 * @function 242 */ 243 socketbug.sb_manager.on('connect', function () 244 { 245 /* Stop Loading Animation */ 246 jQuery('#loading').fadeOut('slow'); 247 248 /* Toggle Connection Indicator to ON Position */ 249 jQuery('#connect').attr('checked', true).trigger('change'); 250 251 if(socketbug.connected === false) 252 { 253 if( !GUID.is_valid(_sbs.group_id)) 254 { 255 socketbug.log('Invalid Socketbug Group ID', 'error', 'console'); 256 } 257 else if( !GUID.is_valid(_sbs.application_id)) 258 { 259 socketbug.log('Invalid Socketbug Application ID', 'error', 'console'); 260 } 261 else 262 { 263 var date = new Date(); 264 265 socketbug.log('Socketbug Connected', 'log', 'console'); 266 socketbug.connected = true; 267 268 socketbug.sb_manager.emit('connection_manager', socketbug.group, socketbug.application, socketbug.client, 269 function(session_id) 270 { 271 socketbug.log('Connected to Socketbug with Session ID: '+session_id); 272 273 socketbug.session_id = session_id; 274 275 /* Do Callback if one set */ 276 if(typeof(_sbs.connect_callback) == 'function') 277 { 278 _sbs.connect_callback(session_id); 279 } 280 } 281 ); 282 283 /* Do Callback if one set */ 284 if(typeof(_sbs.connect_callback) === "function") 285 { 286 _sbs.connect_callback(); 287 } 288 } 289 } 290 }); 291 292 /** 293 * Capture Responses from Socketbug Manager 294 * 295 * @function 296 * @param {String} message Manager Response Message 297 * @param {String} level Manager Response Level 298 */ 299 socketbug.sb_manager.on('manager_response', function (message, level) 300 { 301 socketbug.log(message, level, 'console'); 302 }); 303 304 /** 305 * Capture Connect Failed Event 306 * 307 * @function 308 */ 309 socketbug.sb_manager.on('connect_failed', function () 310 { 311 /* Stop Loading Animation */ 312 jQuery('#loading').fadeOut('slow'); 313 314 /* Toggle Connection Indicator to OFF Position */ 315 jQuery('#connect').attr('checked', false).trigger('change'); 316 317 socketbug.log('Failed to Connect to Socketbug', 'error', 'console'); 318 socketbug.connected = false; 319 socketbug.disconnect(); 320 321 }); 322 323 /** 324 * Capture Remote Debug Application Message 325 * 326 * @function 327 * @param {String} level Debug Level 328 * @param {Object} data Debug Data 329 */ 330 socketbug.sb_console.on('application_debug', function (level, data) 331 { 332 /* Check the Debug Level */ 333 switch(level) 334 { 335 case 'log': 336 /* Show Message in Console Ouput Window */ 337 if(typeof(data) == 'string') 338 { 339 socketbug.log('<img src="./img/debug_log.png">Remote LOG: <span class="log">' + data + '</span>', 'log', 'application'); 340 } 341 else 342 { 343 socketbug.log('<img src="./img/debug_log.png">Remote LOG: <span class="log">Remote Data Sent to Browser Console ( could not be displayed here )</span>', 'log', 'application'); 344 debug.log(data); 345 } 346 break; 347 348 case 'debug': 349 /* Show Message in Console Ouput Window */ 350 if(typeof(data) == 'string') 351 { 352 socketbug.log('<img src="./img/debug_debug.png">Remote DEBUG: <span class="debug">' + data + '</span>', 'debug', 'application'); 353 } 354 else 355 { 356 socketbug.log('<img src="./img/debug_debug.png">Remote DEBUG: <span class="debug">Remote Data Sent to Browser Console ( could not be displayed here )</span>', 'debug', 'application'); 357 debug.debug(data); 358 } 359 break; 360 361 case 'info': 362 /* Show Message in Console Ouput Window */ 363 if(typeof(data) == 'string') 364 { 365 socketbug.log('<img src="./img/debug_info.png">Remote INFO: <span class="info">' + data + '</span>', 'info', 'application'); 366 } 367 else 368 { 369 socketbug.log('<img src="./img/debug_info.png">Remote INFO: <span class="info">Remote Data Sent to Browser Console ( could not be displayed here )</span>', 'info', 'application'); 370 debug.info(data); 371 } 372 break; 373 374 case 'warn': 375 /* Show Message in Console Ouput Window */ 376 if(typeof(data) == 'string') 377 { 378 socketbug.log('<img src="./img/debug_warn.png">Remote WARN: <span class="warn">' + data + '</span>', 'warn', 'application'); 379 } 380 else 381 { 382 socketbug.log('<img src="./img/debug_warn.png">Remote WARN: <span class="warn">Remote Data Sent to Browser Console ( could not be displayed here )</span>', 'warn', 'application'); 383 debug.warn(data); 384 } 385 break; 386 387 case 'error': 388 /* Show Message in Console Ouput Window */ 389 if(typeof(data) == 'string') 390 { 391 socketbug.log('<img src="./img/debug_error.png">Remote ERROR: <span class="error">' + data + '</span>', 'error', 'application'); 392 } 393 else 394 { 395 socketbug.log('<img src="./img/debug_error.png">Remote ERROR: <span class="error">Remote Data Sent to Browser Console ( could not be displayed here )</span>', 'error', 'application'); 396 debug.error(data); 397 } 398 break; 399 } 400 }); 401 402 /** 403 * Capture Failed Authentication Event 404 * 405 * @function 406 * @param {Boolean} group_valid 407 * @param {Boolean} application_valid 408 */ 409 socketbug.sb_manager.on('authentication_failed', function (group_valid, application_valid) 410 { 411 if( !group_valid) 412 { 413 alert('You are Not Authorized to use Socketbug. Your Group ID is Invalid.'); 414 } 415 if( !application_valid) 416 { 417 alert('You are Not Authorized to use Socketbug. Your Application ID is Invalid.'); 418 } 419 420 /* Disconnect Client from Socketbug Services */ 421 socketbug.sb_manager.disconnect(); 422 socketbug.sb_application.disconnect(); 423 socketbug.sb_console.disconnect(); 424 }); 425 426 /** 427 * Capture Message Event 428 * 429 * @function 430 * @param {String} src HTML Source Code 431 */ 432 socketbug.sb_console.on('view_source', function (src) 433 { 434 socketbug.log('Received Source Code', 'info', 'console'); 435 436 /* Prepare Syntax Highlighting for Source Code */ 437 var brush = new SyntaxHighlighter.brushes.Xml(), 438 code = src,html; 439 440 /* Render Syntax Highligher */ 441 brush.init( 442 { 443 'toolbar': false, 444 'auto-links': true, 445 'smart-tabs': true, 446 'gutter': true 447 }); 448 html = brush.getHtml(code); 449 450 /* Update Interface Elements */ 451 jQuery('#source_code pre').remove(); 452 jQuery('#source_code').append('<pre></pre>'); 453 jQuery('#source_code pre').html(html); 454 jQuery('#source_code').slideDown(); 455 jQuery('#output').slideUp(); 456 jQuery('#settings').slideUp(); 457 458 /* Stop Loading Animation */ 459 jQuery('#loading').fadeOut('slow'); 460 }); 461 462 /** 463 * Capture Close Event 464 * 465 * @function 466 */ 467 socketbug.sb_manager.on('close', function () 468 { 469 socketbug.log('Connection to Socketbug Closed', 'warn', 'console'); 470 socketbug.connected = false; 471 }); 472 473 /** 474 * Capture Disconnect Event 475 * 476 * @function 477 */ 478 socketbug.sb_manager.on('disconnect', function () 479 { 480 /* Toggle Connection Indicator to OFF Position */ 481 jQuery('#connect').attr('checked', false).trigger('change'); 482 483 socketbug.log('Socketbug Disconnected', 'warn', 'console'); 484 socketbug.connected = false; 485 486 /* Do Callback if one set */ 487 if(_sbs.disconnect_callback && typeof(_sbs.disconnect_callback) === "function") 488 { 489 _sbs.disconnect_callback(); 490 } 491 }); 492 493 /** 494 * Capture Reconnect Event 495 * 496 * @function 497 * @param {String} transport_type 498 * @param {Number} reconnectionAttempts 499 */ 500 socketbug.sb_manager.on('reconnect', function (transport_type, reconnectionAttempts) 501 { 502 socketbug.log('Successfully Reconnected to Socketbug via ' + transport_type + ' with Attempt #' + reconnectionAttempts, 'log', 'console'); 503 socketbug.connected = false; 504 }); 505 506 /** 507 * Capture Reconnecting Event 508 * 509 * @function 510 * @param {Number} reconnectionDelay 511 * @param {Number} reconnectionAttempts 512 */ 513 socketbug.sb_manager.on('reconnecting', function (reconnectionDelay, reconnectionAttempts) 514 { 515 socketbug.log('Attempt #' + reconnectionAttempts + ' at Reconnecting to Socketbug...', 'warn', 'console'); 516 socketbug.connected = false; 517 }); 518 519 /** 520 * Capture Close Event 521 * 522 * @function 523 */ 524 socketbug.sb_manager.on('reconnect_failed', function () 525 { 526 socketbug.log('Failed to Reconnect to Socketbug', 'error', 'console'); 527 socketbug.connected = false; 528 }); 529 530 /** Set Debug Level for Socketbug Console */ 531 debug.setLevel(socketbug.debug_level); 532 }