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 | }); |
---|