[483] | 1 | define([ |
---|
| 2 | "../_base/kernel", |
---|
| 3 | "require", |
---|
| 4 | "../_base/html", |
---|
| 5 | "../sniff", |
---|
| 6 | "../_base/array", |
---|
| 7 | "../_base/lang", |
---|
| 8 | "../_base/event", |
---|
| 9 | "../_base/unload"], function(dojo, require, html, has){ |
---|
| 10 | |
---|
| 11 | // module: |
---|
| 12 | // dojo/_firebug/firebug |
---|
| 13 | // summary: |
---|
| 14 | // Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox |
---|
| 15 | // description: |
---|
| 16 | // Opens a console for logging, debugging, and error messages. |
---|
| 17 | // Contains partial functionality to Firebug. See function list below. |
---|
| 18 | // |
---|
| 19 | // NOTE: |
---|
| 20 | // Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug. |
---|
| 21 | // Firebug Lite is included in Dojo by permission from Joe Hewitt |
---|
| 22 | // If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug |
---|
| 23 | // functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html |
---|
| 24 | // |
---|
| 25 | // NOTE: |
---|
| 26 | // To test Firebug Lite in Firefox: |
---|
| 27 | // |
---|
| 28 | // - FF2: set "console = null" before loading dojo and set djConfig.isDebug=true |
---|
| 29 | // - FF3: disable Firebug and set djConfig.isDebug=true |
---|
| 30 | // |
---|
| 31 | // example: |
---|
| 32 | // Supports inline objects in object inspector window (only simple trace of dom nodes, however) |
---|
| 33 | // | console.log("my object", {foo:"bar"}) |
---|
| 34 | // example: |
---|
| 35 | // Option for console to open in popup window |
---|
| 36 | // | var djConfig = {isDebug: true, popup:true }; |
---|
| 37 | // example: |
---|
| 38 | // Option for console height (ignored for popup) |
---|
| 39 | // | var djConfig = {isDebug: true, debugHeight:100 } |
---|
| 40 | |
---|
| 41 | |
---|
| 42 | var isNewIE = (/Trident/.test(window.navigator.userAgent)); |
---|
| 43 | if(isNewIE){ |
---|
| 44 | // Fixing IE's console |
---|
| 45 | // IE doesn't insert space between arguments. How annoying. |
---|
| 46 | var calls = ["log", "info", "debug", "warn", "error"]; |
---|
| 47 | for(var i=0;i<calls.length;i++){ |
---|
| 48 | var m = calls[i]; |
---|
| 49 | if(!console[m] ||console[m]._fake){ |
---|
| 50 | // IE9 doesn't have console.debug method, a fake one is added later |
---|
| 51 | continue; |
---|
| 52 | } |
---|
| 53 | var n = "_"+calls[i]; |
---|
| 54 | console[n] = console[m]; |
---|
| 55 | console[m] = (function(){ |
---|
| 56 | var type = n; |
---|
| 57 | return function(){ |
---|
| 58 | console[type](Array.prototype.join.call(arguments, " ")); |
---|
| 59 | }; |
---|
| 60 | })(); |
---|
| 61 | } |
---|
| 62 | // clear the console on load. This is more than a convenience - too many logs crashes it. |
---|
| 63 | // If closed it throws an error |
---|
| 64 | try{ console.clear(); }catch(e){} |
---|
| 65 | } |
---|
| 66 | |
---|
| 67 | if( |
---|
| 68 | has("ff") || // Firefox has Firebug |
---|
| 69 | has("chrome") || // Chrome 3+ has a console |
---|
| 70 | has("safari") || // Safari 4 has a console |
---|
| 71 | isNewIE || // Has the new IE console |
---|
| 72 | window.firebug || // Testing for mozilla firebug lite |
---|
| 73 | (typeof console != "undefined" && console.firebug) || //The firebug console |
---|
| 74 | dojo.config.useCustomLogger || // Allow custom loggers |
---|
| 75 | has("air") // isDebug triggers AIRInsector, not Firebug |
---|
| 76 | ){ |
---|
| 77 | return; |
---|
| 78 | } |
---|
| 79 | |
---|
| 80 | // don't build firebug in iframes |
---|
| 81 | try{ |
---|
| 82 | if(window != window.parent){ |
---|
| 83 | // but if we've got a parent logger, connect to it |
---|
| 84 | if(window.parent["console"]){ |
---|
| 85 | window.console = window.parent.console; |
---|
| 86 | } |
---|
| 87 | return; |
---|
| 88 | } |
---|
| 89 | }catch(e){/*squelch*/} |
---|
| 90 | |
---|
| 91 | // *************************************************************************** |
---|
| 92 | // Placing these variables before the functions that use them to avoid a |
---|
| 93 | // shrinksafe bug where variable renaming does not happen correctly otherwise. |
---|
| 94 | |
---|
| 95 | // most of the objects in this script are run anonomously |
---|
| 96 | var _firebugDoc = document; |
---|
| 97 | var _firebugWin = window; |
---|
| 98 | var __consoleAnchorId__ = 0; |
---|
| 99 | |
---|
| 100 | var consoleFrame = null; |
---|
| 101 | var consoleBody = null; |
---|
| 102 | var consoleObjectInspector = null; |
---|
| 103 | var fireBugTabs = null; |
---|
| 104 | var commandLine = null; |
---|
| 105 | var consoleToolbar = null; |
---|
| 106 | |
---|
| 107 | var frameVisible = false; |
---|
| 108 | var messageQueue = []; |
---|
| 109 | var groupStack = []; |
---|
| 110 | var timeMap = {}; |
---|
| 111 | var countMap = {}; |
---|
| 112 | |
---|
| 113 | var consoleDomInspector = null; |
---|
| 114 | var _inspectionMoveConnection; |
---|
| 115 | var _inspectionClickConnection; |
---|
| 116 | var _inspectionEnabled = false; |
---|
| 117 | var _inspectionTimer = null; |
---|
| 118 | var _inspectTempNode = document.createElement("div"); |
---|
| 119 | |
---|
| 120 | |
---|
| 121 | var _inspectCurrentNode; |
---|
| 122 | var _restoreBorderStyle; |
---|
| 123 | |
---|
| 124 | // *************************************************************************** |
---|
| 125 | |
---|
| 126 | window.console = { |
---|
| 127 | _connects: [], |
---|
| 128 | log: function(){ |
---|
| 129 | // summary: |
---|
| 130 | // Sends arguments to console. |
---|
| 131 | logFormatted(arguments, ""); |
---|
| 132 | }, |
---|
| 133 | |
---|
| 134 | debug: function(){ |
---|
| 135 | // summary: |
---|
| 136 | // Sends arguments to console. Missing finctionality to show script line of trace. |
---|
| 137 | logFormatted(arguments, "debug"); |
---|
| 138 | }, |
---|
| 139 | |
---|
| 140 | info: function(){ |
---|
| 141 | // summary: |
---|
| 142 | // Sends arguments to console, highlighted with (I) icon. |
---|
| 143 | logFormatted(arguments, "info"); |
---|
| 144 | }, |
---|
| 145 | |
---|
| 146 | warn: function(){ |
---|
| 147 | // summary: |
---|
| 148 | // Sends warning arguments to console, highlighted with (!) icon and blue style. |
---|
| 149 | logFormatted(arguments, "warning"); |
---|
| 150 | }, |
---|
| 151 | |
---|
| 152 | error: function(){ |
---|
| 153 | // summary: |
---|
| 154 | // Sends error arguments (object) to console, highlighted with (X) icon and yellow style |
---|
| 155 | // NEW: error object now displays in object inspector |
---|
| 156 | logFormatted(arguments, "error"); |
---|
| 157 | }, |
---|
| 158 | |
---|
| 159 | assert: function(truth, message){ |
---|
| 160 | // summary: |
---|
| 161 | // Tests for true. Throws exception if false. |
---|
| 162 | if(!truth){ |
---|
| 163 | var args = []; |
---|
| 164 | for(var i = 1; i < arguments.length; ++i){ |
---|
| 165 | args.push(arguments[i]); |
---|
| 166 | } |
---|
| 167 | |
---|
| 168 | logFormatted(args.length ? args : ["Assertion Failure"], "error"); |
---|
| 169 | throw message ? message : "Assertion Failure"; |
---|
| 170 | } |
---|
| 171 | }, |
---|
| 172 | |
---|
| 173 | dir: function(obj){ |
---|
| 174 | var str = printObject( obj ); |
---|
| 175 | str = str.replace(/\n/g, "<br />"); |
---|
| 176 | str = str.replace(/\t/g, " "); |
---|
| 177 | logRow([str], "dir"); |
---|
| 178 | }, |
---|
| 179 | |
---|
| 180 | dirxml: function(node){ |
---|
| 181 | var html = []; |
---|
| 182 | appendNode(node, html); |
---|
| 183 | logRow(html, "dirxml"); |
---|
| 184 | }, |
---|
| 185 | |
---|
| 186 | group: function(){ |
---|
| 187 | // summary: |
---|
| 188 | // collects log messages into a group, starting with this call and ending with |
---|
| 189 | // groupEnd(). Missing collapse functionality |
---|
| 190 | logRow(arguments, "group", pushGroup); |
---|
| 191 | }, |
---|
| 192 | |
---|
| 193 | groupEnd: function(){ |
---|
| 194 | // summary: |
---|
| 195 | // Closes group. See above |
---|
| 196 | logRow(arguments, "", popGroup); |
---|
| 197 | }, |
---|
| 198 | |
---|
| 199 | time: function(name){ |
---|
| 200 | // summary: |
---|
| 201 | // Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title); |
---|
| 202 | // example: |
---|
| 203 | // | console.time("load"); |
---|
| 204 | // | console.time("myFunction"); |
---|
| 205 | // | console.timeEnd("load"); |
---|
| 206 | // | console.timeEnd("myFunction"); |
---|
| 207 | timeMap[name] = new Date().getTime(); |
---|
| 208 | }, |
---|
| 209 | |
---|
| 210 | timeEnd: function(name){ |
---|
| 211 | // summary: |
---|
| 212 | // See above. |
---|
| 213 | if(name in timeMap){ |
---|
| 214 | var delta = (new Date()).getTime() - timeMap[name]; |
---|
| 215 | logFormatted([name+ ":", delta+"ms"]); |
---|
| 216 | delete timeMap[name]; |
---|
| 217 | } |
---|
| 218 | }, |
---|
| 219 | |
---|
| 220 | count: function(name){ |
---|
| 221 | // summary: |
---|
| 222 | // Not supported |
---|
| 223 | if(!countMap[name]) countMap[name] = 0; |
---|
| 224 | countMap[name]++; |
---|
| 225 | logFormatted([name+": "+countMap[name]]); |
---|
| 226 | }, |
---|
| 227 | |
---|
| 228 | trace: function(_value){ |
---|
| 229 | var stackAmt = _value || 3; |
---|
| 230 | var f = console.trace.caller; //function that called trace |
---|
| 231 | console.log(">>> console.trace(stack)"); |
---|
| 232 | for(var i=0;i<stackAmt;i++){ |
---|
| 233 | var func = f.toString(); |
---|
| 234 | var args=[]; |
---|
| 235 | for (var a = 0; a < f.arguments.length; a++){ |
---|
| 236 | args.push(f.arguments[a]); |
---|
| 237 | } |
---|
| 238 | if(f.arguments.length){ |
---|
| 239 | console.dir({"function":func, "arguments":args}); |
---|
| 240 | }else{ |
---|
| 241 | console.dir({"function":func}); |
---|
| 242 | } |
---|
| 243 | |
---|
| 244 | f = f.caller; |
---|
| 245 | } |
---|
| 246 | }, |
---|
| 247 | |
---|
| 248 | profile: function(){ |
---|
| 249 | // summary: |
---|
| 250 | // Not supported |
---|
| 251 | this.warn(["profile() not supported."]); |
---|
| 252 | }, |
---|
| 253 | |
---|
| 254 | profileEnd: function(){ }, |
---|
| 255 | |
---|
| 256 | clear: function(){ |
---|
| 257 | // summary: |
---|
| 258 | // Clears message console. Do not call this directly |
---|
| 259 | if(consoleBody){ |
---|
| 260 | while(consoleBody.childNodes.length){ |
---|
| 261 | dojo.destroy(consoleBody.firstChild); |
---|
| 262 | } |
---|
| 263 | } |
---|
| 264 | dojo.forEach(this._connects,dojo.disconnect); |
---|
| 265 | }, |
---|
| 266 | |
---|
| 267 | open: function(){ |
---|
| 268 | // summary: |
---|
| 269 | // Opens message console. Do not call this directly |
---|
| 270 | toggleConsole(true); |
---|
| 271 | }, |
---|
| 272 | |
---|
| 273 | close: function(){ |
---|
| 274 | // summary: |
---|
| 275 | // Closes message console. Do not call this directly |
---|
| 276 | if(frameVisible){ |
---|
| 277 | toggleConsole(); |
---|
| 278 | } |
---|
| 279 | }, |
---|
| 280 | _restoreBorder: function(){ |
---|
| 281 | if(_inspectCurrentNode){ |
---|
| 282 | _inspectCurrentNode.style.border = _restoreBorderStyle; |
---|
| 283 | } |
---|
| 284 | }, |
---|
| 285 | openDomInspector: function(){ |
---|
| 286 | _inspectionEnabled = true; |
---|
| 287 | consoleBody.style.display = "none"; |
---|
| 288 | consoleDomInspector.style.display = "block"; |
---|
| 289 | consoleObjectInspector.style.display = "none"; |
---|
| 290 | document.body.style.cursor = "pointer"; |
---|
| 291 | _inspectionMoveConnection = dojo.connect(document, "mousemove", function(evt){ |
---|
| 292 | if(!_inspectionEnabled){ return; } |
---|
| 293 | if(!_inspectionTimer){ |
---|
| 294 | _inspectionTimer = setTimeout(function(){ _inspectionTimer = null; }, 50); |
---|
| 295 | }else{ |
---|
| 296 | return; |
---|
| 297 | } |
---|
| 298 | var node = evt.target; |
---|
| 299 | if(node && (_inspectCurrentNode !== node)){ |
---|
| 300 | var parent = true; |
---|
| 301 | |
---|
| 302 | console._restoreBorder(); |
---|
| 303 | var html = []; |
---|
| 304 | appendNode(node, html); |
---|
| 305 | consoleDomInspector.innerHTML = html.join(""); |
---|
| 306 | |
---|
| 307 | _inspectCurrentNode = node; |
---|
| 308 | _restoreBorderStyle = _inspectCurrentNode.style.border; |
---|
| 309 | _inspectCurrentNode.style.border = "#0000FF 1px solid"; |
---|
| 310 | } |
---|
| 311 | }); |
---|
| 312 | setTimeout(function(){ |
---|
| 313 | _inspectionClickConnection = dojo.connect(document, "click", function(evt){ |
---|
| 314 | document.body.style.cursor = ""; |
---|
| 315 | _inspectionEnabled = !_inspectionEnabled; |
---|
| 316 | dojo.disconnect(_inspectionClickConnection); |
---|
| 317 | // console._restoreBorder(); |
---|
| 318 | }); |
---|
| 319 | }, 30); |
---|
| 320 | }, |
---|
| 321 | _closeDomInspector: function(){ |
---|
| 322 | document.body.style.cursor = ""; |
---|
| 323 | dojo.disconnect(_inspectionMoveConnection); |
---|
| 324 | dojo.disconnect(_inspectionClickConnection); |
---|
| 325 | _inspectionEnabled = false; |
---|
| 326 | console._restoreBorder(); |
---|
| 327 | }, |
---|
| 328 | openConsole:function(){ |
---|
| 329 | // summary: |
---|
| 330 | // Closes object inspector and opens message console. Do not call this directly |
---|
| 331 | consoleBody.style.display = "block"; |
---|
| 332 | consoleDomInspector.style.display = "none"; |
---|
| 333 | consoleObjectInspector.style.display = "none"; |
---|
| 334 | console._closeDomInspector(); |
---|
| 335 | }, |
---|
| 336 | openObjectInspector:function(){ |
---|
| 337 | consoleBody.style.display = "none"; |
---|
| 338 | consoleDomInspector.style.display = "none"; |
---|
| 339 | consoleObjectInspector.style.display = "block"; |
---|
| 340 | console._closeDomInspector(); |
---|
| 341 | }, |
---|
| 342 | recss: function(){ |
---|
| 343 | // this is placed in dojo since the console is most likely |
---|
| 344 | // in another window and dojo is easilly accessible |
---|
| 345 | var i,a,s;a=document.getElementsByTagName('link'); |
---|
| 346 | for(i=0;i<a.length;i++){ |
---|
| 347 | s=a[i]; |
---|
| 348 | if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href){ |
---|
| 349 | var h=s.href.replace(/(&|%5C?)forceReload=\d+/,''); |
---|
| 350 | s.href=h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+new Date().valueOf(); |
---|
| 351 | } |
---|
| 352 | } |
---|
| 353 | } |
---|
| 354 | }; |
---|
| 355 | |
---|
| 356 | // *************************************************************************** |
---|
| 357 | |
---|
| 358 | function toggleConsole(forceOpen){ |
---|
| 359 | frameVisible = forceOpen || !frameVisible; |
---|
| 360 | if(consoleFrame){ |
---|
| 361 | consoleFrame.style.display = frameVisible ? "block" : "none"; |
---|
| 362 | } |
---|
| 363 | } |
---|
| 364 | |
---|
| 365 | function focusCommandLine(){ |
---|
| 366 | toggleConsole(true); |
---|
| 367 | if(commandLine){ |
---|
| 368 | commandLine.focus(); |
---|
| 369 | } |
---|
| 370 | } |
---|
| 371 | |
---|
| 372 | function openWin(x,y,w,h){ |
---|
| 373 | var win = window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0"); |
---|
| 374 | if(!win){ |
---|
| 375 | var msg = "Firebug Lite could not open a pop-up window, most likely because of a blocker.\n" + |
---|
| 376 | "Either enable pop-ups for this domain, or change the djConfig to popup=false."; |
---|
| 377 | alert(msg); |
---|
| 378 | } |
---|
| 379 | createResizeHandler(win); |
---|
| 380 | var newDoc=win.document; |
---|
| 381 | //Safari needs an HTML height |
---|
| 382 | var HTMLstring= '<html style="height:100%;"><head><title>Firebug Lite</title></head>\n' + |
---|
| 383 | '<body bgColor="#ccc" style="height:97%;" onresize="opener.onFirebugResize()">\n' + |
---|
| 384 | '<div id="fb"></div>' + |
---|
| 385 | '</body></html>'; |
---|
| 386 | |
---|
| 387 | newDoc.write(HTMLstring); |
---|
| 388 | newDoc.close(); |
---|
| 389 | return win; |
---|
| 390 | } |
---|
| 391 | |
---|
| 392 | function createResizeHandler(wn){ |
---|
| 393 | // summary: |
---|
| 394 | // Creates handle for onresize window. Called from script in popup's body tag (so that it will work with IE). |
---|
| 395 | // |
---|
| 396 | |
---|
| 397 | var d = new Date(); |
---|
| 398 | d.setTime(d.getTime()+(60*24*60*60*1000)); // 60 days |
---|
| 399 | d = d.toUTCString(); |
---|
| 400 | |
---|
| 401 | var dc = wn.document, |
---|
| 402 | getViewport; |
---|
| 403 | |
---|
| 404 | if (wn.innerWidth){ |
---|
| 405 | getViewport = function(){ |
---|
| 406 | return{w:wn.innerWidth, h:wn.innerHeight}; |
---|
| 407 | }; |
---|
| 408 | }else if (dc.documentElement && dc.documentElement.clientWidth){ |
---|
| 409 | getViewport = function(){ |
---|
| 410 | return{w:dc.documentElement.clientWidth, h:dc.documentElement.clientHeight}; |
---|
| 411 | }; |
---|
| 412 | }else if (dc.body){ |
---|
| 413 | getViewport = function(){ |
---|
| 414 | return{w:dc.body.clientWidth, h:dc.body.clientHeight}; |
---|
| 415 | }; |
---|
| 416 | } |
---|
| 417 | |
---|
| 418 | |
---|
| 419 | window.onFirebugResize = function(){ |
---|
| 420 | |
---|
| 421 | //resize the height of the console log body |
---|
| 422 | layout(getViewport().h); |
---|
| 423 | |
---|
| 424 | clearInterval(wn._firebugWin_resize); |
---|
| 425 | wn._firebugWin_resize = setTimeout(function(){ |
---|
| 426 | var x = wn.screenLeft, |
---|
| 427 | y = wn.screenTop, |
---|
| 428 | w = wn.outerWidth || wn.document.body.offsetWidth, |
---|
| 429 | h = wn.outerHeight || wn.document.body.offsetHeight; |
---|
| 430 | |
---|
| 431 | document.cookie = "_firebugPosition=" + [x,y,w,h].join(",") + "; expires="+d+"; path=/"; |
---|
| 432 | |
---|
| 433 | }, 5000); //can't capture window.onMove - long timeout gives better chance of capturing a resize, then the move |
---|
| 434 | |
---|
| 435 | }; |
---|
| 436 | } |
---|
| 437 | |
---|
| 438 | |
---|
| 439 | /*****************************************************************************/ |
---|
| 440 | |
---|
| 441 | |
---|
| 442 | function createFrame(){ |
---|
| 443 | if(consoleFrame){ |
---|
| 444 | return; |
---|
| 445 | } |
---|
| 446 | toggleConsole(true); |
---|
| 447 | if(dojo.config.popup){ |
---|
| 448 | var containerHeight = "100%"; |
---|
| 449 | var cookieMatch = document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/); |
---|
| 450 | var p = cookieMatch ? cookieMatch[1].split(",") : [2,2,320,480]; |
---|
| 451 | |
---|
| 452 | _firebugWin = openWin(p[0],p[1],p[2],p[3]); // global |
---|
| 453 | _firebugDoc = _firebugWin.document; // global |
---|
| 454 | |
---|
| 455 | dojo.config.debugContainerId = 'fb'; |
---|
| 456 | |
---|
| 457 | // connecting popup |
---|
| 458 | _firebugWin.console = window.console; |
---|
| 459 | _firebugWin.dojo = window.dojo; |
---|
| 460 | }else{ |
---|
| 461 | _firebugDoc = document; |
---|
| 462 | containerHeight = (dojo.config.debugHeight || 300) + "px"; |
---|
| 463 | } |
---|
| 464 | |
---|
| 465 | var styleElement = _firebugDoc.createElement("link"); |
---|
| 466 | styleElement.href = require.toUrl("./firebug.css"); |
---|
| 467 | styleElement.rel = "stylesheet"; |
---|
| 468 | styleElement.type = "text/css"; |
---|
| 469 | var styleParent = _firebugDoc.getElementsByTagName("head"); |
---|
| 470 | if(styleParent){ |
---|
| 471 | styleParent = styleParent[0]; |
---|
| 472 | } |
---|
| 473 | if(!styleParent){ |
---|
| 474 | styleParent = _firebugDoc.getElementsByTagName("html")[0]; |
---|
| 475 | } |
---|
| 476 | if(has("ie")){ |
---|
| 477 | window.setTimeout(function(){ styleParent.appendChild(styleElement); }, 0); |
---|
| 478 | }else{ |
---|
| 479 | styleParent.appendChild(styleElement); |
---|
| 480 | } |
---|
| 481 | |
---|
| 482 | if(dojo.config.debugContainerId){ |
---|
| 483 | consoleFrame = _firebugDoc.getElementById(dojo.config.debugContainerId); |
---|
| 484 | } |
---|
| 485 | if(!consoleFrame){ |
---|
| 486 | consoleFrame = _firebugDoc.createElement("div"); |
---|
| 487 | _firebugDoc.body.appendChild(consoleFrame); |
---|
| 488 | } |
---|
| 489 | consoleFrame.className += " firebug"; |
---|
| 490 | consoleFrame.id = "firebug"; |
---|
| 491 | consoleFrame.style.height = containerHeight; |
---|
| 492 | consoleFrame.style.display = (frameVisible ? "block" : "none"); |
---|
| 493 | |
---|
| 494 | var buildLink = function(label, title, method, _class){ |
---|
| 495 | return '<li class="'+_class+'"><a href="javascript:void(0);" onclick="console.'+ method +'(); return false;" title="'+title+'">'+label+'</a></li>'; |
---|
| 496 | }; |
---|
| 497 | consoleFrame.innerHTML = |
---|
| 498 | '<div id="firebugToolbar">' |
---|
| 499 | + ' <ul id="fireBugTabs" class="tabs">' |
---|
| 500 | |
---|
| 501 | + buildLink("Clear", "Remove All Console Logs", "clear", "") |
---|
| 502 | + buildLink("ReCSS", "Refresh CSS without reloading page", "recss", "") |
---|
| 503 | |
---|
| 504 | + buildLink("Console", "Show Console Logs", "openConsole", "gap") |
---|
| 505 | + buildLink("DOM", "Show DOM Inspector", "openDomInspector", "") |
---|
| 506 | + buildLink("Object", "Show Object Inspector", "openObjectInspector", "") |
---|
| 507 | + ((dojo.config.popup) ? "" : buildLink("Close", "Close the console", "close", "gap")) |
---|
| 508 | |
---|
| 509 | + ' </ul>' |
---|
| 510 | + '</div>' |
---|
| 511 | + '<input type="text" id="firebugCommandLine" />' |
---|
| 512 | + '<div id="firebugLog"></div>' |
---|
| 513 | + '<div id="objectLog" style="display:none;">Click on an object in the Log display</div>' |
---|
| 514 | + '<div id="domInspect" style="display:none;">Hover over HTML elements in the main page. Click to hold selection.</div>'; |
---|
| 515 | |
---|
| 516 | |
---|
| 517 | consoleToolbar = _firebugDoc.getElementById("firebugToolbar"); |
---|
| 518 | |
---|
| 519 | commandLine = _firebugDoc.getElementById("firebugCommandLine"); |
---|
| 520 | addEvent(commandLine, "keydown", onCommandLineKeyDown); |
---|
| 521 | |
---|
| 522 | addEvent(_firebugDoc, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown); |
---|
| 523 | |
---|
| 524 | consoleBody = _firebugDoc.getElementById("firebugLog"); |
---|
| 525 | consoleObjectInspector = _firebugDoc.getElementById("objectLog"); |
---|
| 526 | consoleDomInspector = _firebugDoc.getElementById("domInspect"); |
---|
| 527 | fireBugTabs = _firebugDoc.getElementById("fireBugTabs"); |
---|
| 528 | layout(); |
---|
| 529 | flush(); |
---|
| 530 | } |
---|
| 531 | |
---|
| 532 | dojo.addOnLoad(createFrame); |
---|
| 533 | |
---|
| 534 | function clearFrame(){ |
---|
| 535 | _firebugDoc = null; |
---|
| 536 | |
---|
| 537 | if(_firebugWin.console){ |
---|
| 538 | _firebugWin.console.clear(); |
---|
| 539 | } |
---|
| 540 | _firebugWin = null; |
---|
| 541 | consoleFrame = null; |
---|
| 542 | consoleBody = null; |
---|
| 543 | consoleObjectInspector = null; |
---|
| 544 | consoleDomInspector = null; |
---|
| 545 | commandLine = null; |
---|
| 546 | messageQueue = []; |
---|
| 547 | groupStack = []; |
---|
| 548 | timeMap = {}; |
---|
| 549 | } |
---|
| 550 | |
---|
| 551 | |
---|
| 552 | function evalCommandLine(){ |
---|
| 553 | var text = commandLine.value; |
---|
| 554 | commandLine.value = ""; |
---|
| 555 | |
---|
| 556 | logRow(["> ", text], "command"); |
---|
| 557 | |
---|
| 558 | var value; |
---|
| 559 | try{ |
---|
| 560 | value = eval(text); |
---|
| 561 | }catch(e){ |
---|
| 562 | console.debug(e); // put exception on the console |
---|
| 563 | } |
---|
| 564 | |
---|
| 565 | console.log(value); |
---|
| 566 | } |
---|
| 567 | |
---|
| 568 | function layout(h){ |
---|
| 569 | var tHeight = 25; //consoleToolbar.offsetHeight; // tab style not ready on load - throws off layout |
---|
| 570 | var height = h ? |
---|
| 571 | h - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" : |
---|
| 572 | (consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px"; |
---|
| 573 | |
---|
| 574 | consoleBody.style.top = tHeight + "px"; |
---|
| 575 | consoleBody.style.height = height; |
---|
| 576 | consoleObjectInspector.style.height = height; |
---|
| 577 | consoleObjectInspector.style.top = tHeight + "px"; |
---|
| 578 | consoleDomInspector.style.height = height; |
---|
| 579 | consoleDomInspector.style.top = tHeight + "px"; |
---|
| 580 | commandLine.style.bottom = 0; |
---|
| 581 | |
---|
| 582 | dojo.addOnWindowUnload(clearFrame); |
---|
| 583 | } |
---|
| 584 | |
---|
| 585 | function logRow(message, className, handler){ |
---|
| 586 | if(consoleBody){ |
---|
| 587 | writeMessage(message, className, handler); |
---|
| 588 | }else{ |
---|
| 589 | messageQueue.push([message, className, handler]); |
---|
| 590 | } |
---|
| 591 | } |
---|
| 592 | |
---|
| 593 | function flush(){ |
---|
| 594 | var queue = messageQueue; |
---|
| 595 | messageQueue = []; |
---|
| 596 | |
---|
| 597 | for(var i = 0; i < queue.length; ++i){ |
---|
| 598 | writeMessage(queue[i][0], queue[i][1], queue[i][2]); |
---|
| 599 | } |
---|
| 600 | } |
---|
| 601 | |
---|
| 602 | function writeMessage(message, className, handler){ |
---|
| 603 | var isScrolledToBottom = |
---|
| 604 | consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight; |
---|
| 605 | |
---|
| 606 | handler = handler||writeRow; |
---|
| 607 | |
---|
| 608 | handler(message, className); |
---|
| 609 | |
---|
| 610 | if(isScrolledToBottom){ |
---|
| 611 | consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight; |
---|
| 612 | } |
---|
| 613 | } |
---|
| 614 | |
---|
| 615 | function appendRow(row){ |
---|
| 616 | var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody; |
---|
| 617 | container.appendChild(row); |
---|
| 618 | } |
---|
| 619 | |
---|
| 620 | function writeRow(message, className){ |
---|
| 621 | var row = consoleBody.ownerDocument.createElement("div"); |
---|
| 622 | row.className = "logRow" + (className ? " logRow-"+className : ""); |
---|
| 623 | row.innerHTML = message.join(""); |
---|
| 624 | appendRow(row); |
---|
| 625 | } |
---|
| 626 | |
---|
| 627 | function pushGroup(message, className){ |
---|
| 628 | logFormatted(message, className); |
---|
| 629 | |
---|
| 630 | //var groupRow = consoleBody.ownerDocument.createElement("div"); |
---|
| 631 | //groupRow.className = "logGroup"; |
---|
| 632 | var groupRowBox = consoleBody.ownerDocument.createElement("div"); |
---|
| 633 | groupRowBox.className = "logGroupBox"; |
---|
| 634 | //groupRow.appendChild(groupRowBox); |
---|
| 635 | appendRow(groupRowBox); |
---|
| 636 | groupStack.push(groupRowBox); |
---|
| 637 | } |
---|
| 638 | |
---|
| 639 | function popGroup(){ |
---|
| 640 | groupStack.pop(); |
---|
| 641 | } |
---|
| 642 | |
---|
| 643 | // *************************************************************************** |
---|
| 644 | |
---|
| 645 | function logFormatted(objects, className){ |
---|
| 646 | var html = []; |
---|
| 647 | |
---|
| 648 | var format = objects[0]; |
---|
| 649 | var objIndex = 0; |
---|
| 650 | |
---|
| 651 | if(typeof(format) != "string"){ |
---|
| 652 | format = ""; |
---|
| 653 | objIndex = -1; |
---|
| 654 | } |
---|
| 655 | |
---|
| 656 | var parts = parseFormat(format); |
---|
| 657 | |
---|
| 658 | for(var i = 0; i < parts.length; ++i){ |
---|
| 659 | var part = parts[i]; |
---|
| 660 | if(part && typeof part == "object"){ |
---|
| 661 | part.appender(objects[++objIndex], html); |
---|
| 662 | }else{ |
---|
| 663 | appendText(part, html); |
---|
| 664 | } |
---|
| 665 | } |
---|
| 666 | |
---|
| 667 | |
---|
| 668 | var ids = []; |
---|
| 669 | var obs = []; |
---|
| 670 | for(i = objIndex+1; i < objects.length; ++i){ |
---|
| 671 | appendText(" ", html); |
---|
| 672 | |
---|
| 673 | var object = objects[i]; |
---|
| 674 | if(object === undefined || object === null ){ |
---|
| 675 | appendNull(object, html); |
---|
| 676 | |
---|
| 677 | }else if(typeof(object) == "string"){ |
---|
| 678 | appendText(object, html); |
---|
| 679 | |
---|
| 680 | }else if(object instanceof Date){ |
---|
| 681 | appendText(object.toString(), html); |
---|
| 682 | |
---|
| 683 | }else if(object.nodeType == 9){ |
---|
| 684 | appendText("[ XmlDoc ]", html); |
---|
| 685 | |
---|
| 686 | }else{ |
---|
| 687 | // Create link for object inspector |
---|
| 688 | // need to create an ID for this link, since it is currently text |
---|
| 689 | var id = "_a" + __consoleAnchorId__++; |
---|
| 690 | ids.push(id); |
---|
| 691 | // need to save the object, so the arrays line up |
---|
| 692 | obs.push(object); |
---|
| 693 | var str = '<a id="'+id+'" href="javascript:void(0);">'+getObjectAbbr(object)+'</a>'; |
---|
| 694 | |
---|
| 695 | appendLink( str , html); |
---|
| 696 | } |
---|
| 697 | } |
---|
| 698 | |
---|
| 699 | logRow(html, className); |
---|
| 700 | |
---|
| 701 | // Now that the row is inserted in the DOM, loop through all of the links that were just created |
---|
| 702 | for(i=0; i<ids.length; i++){ |
---|
| 703 | var btn = _firebugDoc.getElementById(ids[i]); |
---|
| 704 | if(!btn){ continue; } |
---|
| 705 | |
---|
| 706 | // store the object in the dom btn for reference later |
---|
| 707 | // avoid parsing these objects unless necessary |
---|
| 708 | btn.obj = obs[i]; |
---|
| 709 | |
---|
| 710 | _firebugWin.console._connects.push(dojo.connect(btn, "onclick", function(){ |
---|
| 711 | |
---|
| 712 | console.openObjectInspector(); |
---|
| 713 | |
---|
| 714 | try{ |
---|
| 715 | printObject(this.obj); |
---|
| 716 | }catch(e){ |
---|
| 717 | this.obj = e; |
---|
| 718 | } |
---|
| 719 | consoleObjectInspector.innerHTML = "<pre>" + printObject( this.obj ) + "</pre>"; |
---|
| 720 | })); |
---|
| 721 | } |
---|
| 722 | } |
---|
| 723 | |
---|
| 724 | function parseFormat(format){ |
---|
| 725 | var parts = []; |
---|
| 726 | |
---|
| 727 | var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/; |
---|
| 728 | var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat}; |
---|
| 729 | |
---|
| 730 | for(var m = reg.exec(format); m; m = reg.exec(format)){ |
---|
| 731 | var type = m[8] ? m[8] : m[5]; |
---|
| 732 | var appender = type in appenderMap ? appenderMap[type] : appendObject; |
---|
| 733 | var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); |
---|
| 734 | |
---|
| 735 | parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); |
---|
| 736 | parts.push({appender: appender, precision: precision}); |
---|
| 737 | |
---|
| 738 | format = format.substr(m.index+m[0].length); |
---|
| 739 | } |
---|
| 740 | |
---|
| 741 | parts.push(format); |
---|
| 742 | |
---|
| 743 | return parts; |
---|
| 744 | } |
---|
| 745 | |
---|
| 746 | function escapeHTML(value){ |
---|
| 747 | function replaceChars(ch){ |
---|
| 748 | switch(ch){ |
---|
| 749 | case "<": |
---|
| 750 | return "<"; |
---|
| 751 | case ">": |
---|
| 752 | return ">"; |
---|
| 753 | case "&": |
---|
| 754 | return "&"; |
---|
| 755 | case "'": |
---|
| 756 | return "'"; |
---|
| 757 | case '"': |
---|
| 758 | return """; |
---|
| 759 | } |
---|
| 760 | return "?"; |
---|
| 761 | } |
---|
| 762 | return String(value).replace(/[<>&"']/g, replaceChars); |
---|
| 763 | } |
---|
| 764 | |
---|
| 765 | function objectToString(object){ |
---|
| 766 | try{ |
---|
| 767 | return object+""; |
---|
| 768 | }catch(e){ |
---|
| 769 | return null; |
---|
| 770 | } |
---|
| 771 | } |
---|
| 772 | |
---|
| 773 | // *************************************************************************** |
---|
| 774 | function appendLink(object, html){ |
---|
| 775 | // needed for object links - no HTML escaping |
---|
| 776 | html.push( objectToString(object) ); |
---|
| 777 | } |
---|
| 778 | |
---|
| 779 | function appendText(object, html){ |
---|
| 780 | html.push(escapeHTML(objectToString(object))); |
---|
| 781 | } |
---|
| 782 | |
---|
| 783 | function appendNull(object, html){ |
---|
| 784 | html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>'); |
---|
| 785 | } |
---|
| 786 | |
---|
| 787 | function appendString(object, html){ |
---|
| 788 | html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)), |
---|
| 789 | '"</span>'); |
---|
| 790 | } |
---|
| 791 | |
---|
| 792 | function appendInteger(object, html){ |
---|
| 793 | html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>'); |
---|
| 794 | } |
---|
| 795 | |
---|
| 796 | function appendFloat(object, html){ |
---|
| 797 | html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>'); |
---|
| 798 | } |
---|
| 799 | |
---|
| 800 | function appendFunction(object, html){ |
---|
| 801 | html.push('<span class="objectBox-function">', getObjectAbbr(object), '</span>'); |
---|
| 802 | } |
---|
| 803 | |
---|
| 804 | function appendObject(object, html){ |
---|
| 805 | try{ |
---|
| 806 | if(object === undefined){ |
---|
| 807 | appendNull("undefined", html); |
---|
| 808 | }else if(object === null){ |
---|
| 809 | appendNull("null", html); |
---|
| 810 | }else if(typeof object == "string"){ |
---|
| 811 | appendString(object, html); |
---|
| 812 | }else if(typeof object == "number"){ |
---|
| 813 | appendInteger(object, html); |
---|
| 814 | }else if(typeof object == "function"){ |
---|
| 815 | appendFunction(object, html); |
---|
| 816 | }else if(object.nodeType == 1){ |
---|
| 817 | appendSelector(object, html); |
---|
| 818 | }else if(typeof object == "object"){ |
---|
| 819 | appendObjectFormatted(object, html); |
---|
| 820 | }else{ |
---|
| 821 | appendText(object, html); |
---|
| 822 | } |
---|
| 823 | }catch(e){ |
---|
| 824 | /* squelch */ |
---|
| 825 | } |
---|
| 826 | } |
---|
| 827 | |
---|
| 828 | function appendObjectFormatted(object, html){ |
---|
| 829 | var text = objectToString(object); |
---|
| 830 | var reObject = /\[object (.*?)\]/; |
---|
| 831 | |
---|
| 832 | var m = reObject.exec(text); |
---|
| 833 | html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>'); |
---|
| 834 | } |
---|
| 835 | |
---|
| 836 | function appendSelector(object, html){ |
---|
| 837 | html.push('<span class="objectBox-selector">'); |
---|
| 838 | |
---|
| 839 | html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>'); |
---|
| 840 | if(object.id){ |
---|
| 841 | html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>'); |
---|
| 842 | } |
---|
| 843 | if(object.className){ |
---|
| 844 | html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>'); |
---|
| 845 | } |
---|
| 846 | |
---|
| 847 | html.push('</span>'); |
---|
| 848 | } |
---|
| 849 | |
---|
| 850 | function appendNode(node, html){ |
---|
| 851 | if(node.nodeType == 1){ |
---|
| 852 | html.push( |
---|
| 853 | '<div class="objectBox-element">', |
---|
| 854 | '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>'); |
---|
| 855 | |
---|
| 856 | for(var i = 0; i < node.attributes.length; ++i){ |
---|
| 857 | var attr = node.attributes[i]; |
---|
| 858 | if(!attr.specified){ continue; } |
---|
| 859 | |
---|
| 860 | html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(), |
---|
| 861 | '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue), |
---|
| 862 | '</span>"'); |
---|
| 863 | } |
---|
| 864 | |
---|
| 865 | if(node.firstChild){ |
---|
| 866 | html.push('></div><div class="nodeChildren">'); |
---|
| 867 | |
---|
| 868 | for(var child = node.firstChild; child; child = child.nextSibling){ |
---|
| 869 | appendNode(child, html); |
---|
| 870 | } |
---|
| 871 | |
---|
| 872 | html.push('</div><div class="objectBox-element"></<span class="nodeTag">', |
---|
| 873 | node.nodeName.toLowerCase(), '></span></div>'); |
---|
| 874 | }else{ |
---|
| 875 | html.push('/></div>'); |
---|
| 876 | } |
---|
| 877 | }else if (node.nodeType == 3){ |
---|
| 878 | html.push('<div class="nodeText">', escapeHTML(node.nodeValue), |
---|
| 879 | '</div>'); |
---|
| 880 | } |
---|
| 881 | } |
---|
| 882 | |
---|
| 883 | // *************************************************************************** |
---|
| 884 | |
---|
| 885 | function addEvent(object, name, handler){ |
---|
| 886 | if(document.all){ |
---|
| 887 | object.attachEvent("on"+name, handler); |
---|
| 888 | }else{ |
---|
| 889 | object.addEventListener(name, handler, false); |
---|
| 890 | } |
---|
| 891 | } |
---|
| 892 | |
---|
| 893 | function removeEvent(object, name, handler){ |
---|
| 894 | if(document.all){ |
---|
| 895 | object.detachEvent("on"+name, handler); |
---|
| 896 | }else{ |
---|
| 897 | object.removeEventListener(name, handler, false); |
---|
| 898 | } |
---|
| 899 | } |
---|
| 900 | |
---|
| 901 | function cancelEvent(event){ |
---|
| 902 | if(document.all){ |
---|
| 903 | event.cancelBubble = true; |
---|
| 904 | }else{ |
---|
| 905 | event.stopPropagation(); |
---|
| 906 | } |
---|
| 907 | } |
---|
| 908 | |
---|
| 909 | function onError(msg, href, lineNo){ |
---|
| 910 | var lastSlash = href.lastIndexOf("/"); |
---|
| 911 | var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1); |
---|
| 912 | |
---|
| 913 | var html = [ |
---|
| 914 | '<span class="errorMessage">', msg, '</span>', |
---|
| 915 | '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>' |
---|
| 916 | ]; |
---|
| 917 | |
---|
| 918 | logRow(html, "error"); |
---|
| 919 | } |
---|
| 920 | |
---|
| 921 | |
---|
| 922 | //After converting to div instead of iframe, now getting two keydowns right away in IE 6. |
---|
| 923 | //Make sure there is a little bit of delay. |
---|
| 924 | var onKeyDownTime = new Date().getTime(); |
---|
| 925 | |
---|
| 926 | function onKeyDown(event){ |
---|
| 927 | var timestamp = (new Date()).getTime(); |
---|
| 928 | if(timestamp > onKeyDownTime + 200){ |
---|
| 929 | event = dojo.fixEvent(event); |
---|
| 930 | var keys = dojo.keys; |
---|
| 931 | var ekc = event.keyCode; |
---|
| 932 | onKeyDownTime = timestamp; |
---|
| 933 | if(ekc == keys.F12){ |
---|
| 934 | toggleConsole(); |
---|
| 935 | }else if( |
---|
| 936 | (ekc == keys.NUMPAD_ENTER || ekc == 76) && |
---|
| 937 | event.shiftKey && |
---|
| 938 | (event.metaKey || event.ctrlKey) |
---|
| 939 | ){ |
---|
| 940 | focusCommandLine(); |
---|
| 941 | }else{ |
---|
| 942 | return; |
---|
| 943 | } |
---|
| 944 | cancelEvent(event); |
---|
| 945 | } |
---|
| 946 | } |
---|
| 947 | |
---|
| 948 | function onCommandLineKeyDown(e){ |
---|
| 949 | var dk = dojo.keys; |
---|
| 950 | if(e.keyCode == 13 && commandLine.value){ |
---|
| 951 | addToHistory(commandLine.value); |
---|
| 952 | evalCommandLine(); |
---|
| 953 | }else if(e.keyCode == 27){ |
---|
| 954 | commandLine.value = ""; |
---|
| 955 | }else if(e.keyCode == dk.UP_ARROW || e.charCode == dk.UP_ARROW){ |
---|
| 956 | navigateHistory("older"); |
---|
| 957 | }else if(e.keyCode == dk.DOWN_ARROW || e.charCode == dk.DOWN_ARROW){ |
---|
| 958 | navigateHistory("newer"); |
---|
| 959 | }else if(e.keyCode == dk.HOME || e.charCode == dk.HOME){ |
---|
| 960 | historyPosition = 1; |
---|
| 961 | navigateHistory("older"); |
---|
| 962 | }else if(e.keyCode == dk.END || e.charCode == dk.END){ |
---|
| 963 | historyPosition = 999999; |
---|
| 964 | navigateHistory("newer"); |
---|
| 965 | } |
---|
| 966 | } |
---|
| 967 | |
---|
| 968 | var historyPosition = -1; |
---|
| 969 | var historyCommandLine = null; |
---|
| 970 | |
---|
| 971 | function addToHistory(value){ |
---|
| 972 | var history = cookie("firebug_history"); |
---|
| 973 | history = (history) ? dojo.fromJson(history) : []; |
---|
| 974 | var pos = dojo.indexOf(history, value); |
---|
| 975 | if (pos != -1){ |
---|
| 976 | history.splice(pos, 1); |
---|
| 977 | } |
---|
| 978 | history.push(value); |
---|
| 979 | cookie("firebug_history", dojo.toJson(history), 30); |
---|
| 980 | while(history.length && !cookie("firebug_history")){ |
---|
| 981 | history.shift(); |
---|
| 982 | cookie("firebug_history", dojo.toJson(history), 30); |
---|
| 983 | } |
---|
| 984 | historyCommandLine = null; |
---|
| 985 | historyPosition = -1; |
---|
| 986 | } |
---|
| 987 | |
---|
| 988 | function navigateHistory(direction){ |
---|
| 989 | var history = cookie("firebug_history"); |
---|
| 990 | history = (history) ? dojo.fromJson(history) : []; |
---|
| 991 | if(!history.length){ |
---|
| 992 | return; |
---|
| 993 | } |
---|
| 994 | |
---|
| 995 | if(historyCommandLine === null){ |
---|
| 996 | historyCommandLine = commandLine.value; |
---|
| 997 | } |
---|
| 998 | |
---|
| 999 | if(historyPosition == -1){ |
---|
| 1000 | historyPosition = history.length; |
---|
| 1001 | } |
---|
| 1002 | |
---|
| 1003 | if(direction == "older"){ |
---|
| 1004 | --historyPosition; |
---|
| 1005 | if(historyPosition < 0){ |
---|
| 1006 | historyPosition = 0; |
---|
| 1007 | } |
---|
| 1008 | }else if(direction == "newer"){ |
---|
| 1009 | ++historyPosition; |
---|
| 1010 | if(historyPosition > history.length){ |
---|
| 1011 | historyPosition = history.length; |
---|
| 1012 | } |
---|
| 1013 | } |
---|
| 1014 | |
---|
| 1015 | if(historyPosition == history.length){ |
---|
| 1016 | commandLine.value = historyCommandLine; |
---|
| 1017 | historyCommandLine = null; |
---|
| 1018 | }else{ |
---|
| 1019 | commandLine.value = history[historyPosition]; |
---|
| 1020 | } |
---|
| 1021 | } |
---|
| 1022 | |
---|
| 1023 | function cookie(name, value){ |
---|
| 1024 | var c = document.cookie; |
---|
| 1025 | if(arguments.length == 1){ |
---|
| 1026 | var matches = c.match(new RegExp("(?:^|; )" + name + "=([^;]*)")); |
---|
| 1027 | return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined |
---|
| 1028 | }else{ |
---|
| 1029 | var d = new Date(); |
---|
| 1030 | d.setMonth(d.getMonth()+1); |
---|
| 1031 | document.cookie = name + "=" + encodeURIComponent(value) + ((d.toUtcString) ? "; expires=" + d.toUTCString() : ""); |
---|
| 1032 | } |
---|
| 1033 | } |
---|
| 1034 | |
---|
| 1035 | function isArray(it){ |
---|
| 1036 | return it && it instanceof Array || typeof it == "array"; |
---|
| 1037 | } |
---|
| 1038 | |
---|
| 1039 | //*************************************************************************************************** |
---|
| 1040 | // Print Object Helpers |
---|
| 1041 | function objectLength(o){ |
---|
| 1042 | var cnt = 0; |
---|
| 1043 | for(var nm in o){ |
---|
| 1044 | cnt++; |
---|
| 1045 | } |
---|
| 1046 | return cnt; |
---|
| 1047 | } |
---|
| 1048 | |
---|
| 1049 | function printObject(o, i, txt, used){ |
---|
| 1050 | // Recursively trace object, indenting to represent depth for display in object inspector |
---|
| 1051 | var ind = " \t"; |
---|
| 1052 | txt = txt || ""; |
---|
| 1053 | i = i || ind; |
---|
| 1054 | used = used || []; |
---|
| 1055 | var opnCls; |
---|
| 1056 | |
---|
| 1057 | if(o && o.nodeType == 1){ |
---|
| 1058 | var html = []; |
---|
| 1059 | appendNode(o, html); |
---|
| 1060 | return html.join(""); |
---|
| 1061 | } |
---|
| 1062 | |
---|
| 1063 | var br=",\n", cnt = 0, length = objectLength(o); |
---|
| 1064 | |
---|
| 1065 | if(o instanceof Date){ |
---|
| 1066 | return i + o.toString() + br; |
---|
| 1067 | } |
---|
| 1068 | looking: |
---|
| 1069 | for(var nm in o){ |
---|
| 1070 | cnt++; |
---|
| 1071 | if(cnt==length){br = "\n";} |
---|
| 1072 | if(o[nm] === window || o[nm] === document){ |
---|
| 1073 | // do nothing |
---|
| 1074 | }else if(o[nm] === null){ |
---|
| 1075 | txt += i+nm + " : NULL" + br; |
---|
| 1076 | }else if(o[nm] && o[nm].nodeType){ |
---|
| 1077 | if(o[nm].nodeType == 1){ |
---|
| 1078 | //txt += i+nm + " : < "+o[nm].tagName+" id=\""+ o[nm].id+"\" />" + br; |
---|
| 1079 | }else if(o[nm].nodeType == 3){ |
---|
| 1080 | txt += i+nm + " : [ TextNode "+o[nm].data + " ]" + br; |
---|
| 1081 | } |
---|
| 1082 | |
---|
| 1083 | }else if(typeof o[nm] == "object" && (o[nm] instanceof String || o[nm] instanceof Number || o[nm] instanceof Boolean)){ |
---|
| 1084 | txt += i+nm + " : " + o[nm] + "," + br; |
---|
| 1085 | |
---|
| 1086 | }else if(o[nm] instanceof Date){ |
---|
| 1087 | txt += i+nm + " : " + o[nm].toString() + br; |
---|
| 1088 | |
---|
| 1089 | }else if(typeof(o[nm]) == "object" && o[nm]){ |
---|
| 1090 | for(var j = 0, seen; seen = used[j]; j++){ |
---|
| 1091 | if(o[nm] === seen){ |
---|
| 1092 | txt += i+nm + " : RECURSION" + br; |
---|
| 1093 | continue looking; |
---|
| 1094 | } |
---|
| 1095 | } |
---|
| 1096 | used.push(o[nm]); |
---|
| 1097 | |
---|
| 1098 | opnCls = (isArray(o[nm]))?["[","]"]:["{","}"]; |
---|
| 1099 | txt += i+nm +" : " + opnCls[0] + "\n";//non-standard break, (no comma) |
---|
| 1100 | txt += printObject(o[nm], i+ind, "", used); |
---|
| 1101 | txt += i + opnCls[1] + br; |
---|
| 1102 | |
---|
| 1103 | }else if(typeof o[nm] == "undefined"){ |
---|
| 1104 | txt += i+nm + " : undefined" + br; |
---|
| 1105 | }else if(nm == "toString" && typeof o[nm] == "function"){ |
---|
| 1106 | var toString = o[nm](); |
---|
| 1107 | if(typeof toString == "string" && toString.match(/function ?(.*?)\(/)){ |
---|
| 1108 | toString = escapeHTML(getObjectAbbr(o[nm])); |
---|
| 1109 | } |
---|
| 1110 | txt += i+nm +" : " + toString + br; |
---|
| 1111 | }else{ |
---|
| 1112 | txt += i+nm +" : "+ escapeHTML(getObjectAbbr(o[nm])) + br; |
---|
| 1113 | } |
---|
| 1114 | } |
---|
| 1115 | return txt; |
---|
| 1116 | } |
---|
| 1117 | |
---|
| 1118 | function getObjectAbbr(obj){ |
---|
| 1119 | // Gets an abbreviation of an object for display in log |
---|
| 1120 | // X items in object, including id |
---|
| 1121 | // X items in an array |
---|
| 1122 | // TODO: Firebug Sr. actually goes by char count |
---|
| 1123 | var isError = (obj instanceof Error); |
---|
| 1124 | if(obj.nodeType == 1){ |
---|
| 1125 | return escapeHTML('< '+obj.tagName.toLowerCase()+' id=\"'+ obj.id+ '\" />'); |
---|
| 1126 | } |
---|
| 1127 | if(obj.nodeType == 3){ |
---|
| 1128 | return escapeHTML('[TextNode: "'+obj.nodeValue+'"]'); |
---|
| 1129 | } |
---|
| 1130 | var nm = (obj && (obj.id || obj.name || obj.ObjectID || obj.widgetId)); |
---|
| 1131 | if(!isError && nm){ return "{"+nm+"}"; } |
---|
| 1132 | |
---|
| 1133 | var obCnt = 2; |
---|
| 1134 | var arCnt = 4; |
---|
| 1135 | var cnt = 0; |
---|
| 1136 | |
---|
| 1137 | if(isError){ |
---|
| 1138 | nm = "[ Error: "+(obj.message || obj.description || obj)+" ]"; |
---|
| 1139 | }else if(isArray(obj)){ |
---|
| 1140 | nm = "[" + obj.slice(0,arCnt).join(","); |
---|
| 1141 | if(obj.length > arCnt){ |
---|
| 1142 | nm += " ... ("+obj.length+" items)"; |
---|
| 1143 | } |
---|
| 1144 | nm += "]"; |
---|
| 1145 | }else if(typeof obj == "function"){ |
---|
| 1146 | nm = obj + ""; |
---|
| 1147 | var reg = /function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/; |
---|
| 1148 | var m = reg.exec(nm); |
---|
| 1149 | if(m){ |
---|
| 1150 | if(!m[1]){ |
---|
| 1151 | m[1] = "function"; |
---|
| 1152 | } |
---|
| 1153 | nm = m[1] + m[2]; |
---|
| 1154 | }else{ |
---|
| 1155 | nm = "function()"; |
---|
| 1156 | } |
---|
| 1157 | }else if(typeof obj != "object" || typeof obj == "string"){ |
---|
| 1158 | nm = obj + ""; |
---|
| 1159 | }else{ |
---|
| 1160 | nm = "{"; |
---|
| 1161 | for(var i in obj){ |
---|
| 1162 | cnt++; |
---|
| 1163 | if(cnt > obCnt){ break; } |
---|
| 1164 | nm += i+":"+escapeHTML(obj[i])+" "; |
---|
| 1165 | } |
---|
| 1166 | nm+="}"; |
---|
| 1167 | } |
---|
| 1168 | |
---|
| 1169 | return nm; |
---|
| 1170 | } |
---|
| 1171 | |
---|
| 1172 | //************************************************************************************* |
---|
| 1173 | |
---|
| 1174 | //window.onerror = onError; |
---|
| 1175 | |
---|
| 1176 | addEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown); |
---|
| 1177 | |
---|
| 1178 | if( (document.documentElement.getAttribute("debug") == "true")|| |
---|
| 1179 | (dojo.config.isDebug) |
---|
| 1180 | ){ |
---|
| 1181 | toggleConsole(true); |
---|
| 1182 | } |
---|
| 1183 | |
---|
| 1184 | dojo.addOnWindowUnload(function(){ |
---|
| 1185 | // Erase the globals and event handlers I created, to prevent spurious leak warnings |
---|
| 1186 | removeEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown); |
---|
| 1187 | window.onFirebugResize = null; |
---|
| 1188 | window.console = null; |
---|
| 1189 | }); |
---|
| 1190 | |
---|
| 1191 | }); |
---|