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