1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is The JavaScript Debugger.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * Robert Ginda, <rginda@netscape.com>, original author
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 function initRecords()
43 [/* "real" commands */
44 ["show-functions", cmdShowFunctions
, CMD_CONSOLE
],
45 ["show-ecmas", cmdShowECMAs
, CMD_CONSOLE
],
46 ["show-constants", cmdShowConstants
, CMD_CONSOLE
],
49 ["toggle-functions", "show-functions toggle", 0],
50 ["toggle-ecmas", "show-ecma toggle", 0],
51 ["toggle-constants", "show-constants toggle", 0]
54 console
.commandManager
.defineCommands (cmdary
);
56 var atomsvc
= console
.atomService
;
58 WindowRecord
.prototype.property
= atomsvc
.getAtom("item-window");
60 FileContainerRecord
.prototype.property
= atomsvc
.getAtom("item-files");
62 FileRecord
.prototype.property
= atomsvc
.getAtom("item-file");
64 FrameRecord
.prototype.property
= atomsvc
.getAtom("item-frame");
65 FrameRecord
.prototype.atomCurrent
= atomsvc
.getAtom("current-frame-flag");
67 ScriptInstanceRecord
.prototype.atomUnknown
= atomsvc
.getAtom("item-unk");
68 ScriptInstanceRecord
.prototype.atomHTML
= atomsvc
.getAtom("item-html");
69 ScriptInstanceRecord
.prototype.atomJS
= atomsvc
.getAtom("item-js");
70 ScriptInstanceRecord
.prototype.atomXUL
= atomsvc
.getAtom("item-xul");
71 ScriptInstanceRecord
.prototype.atomXML
= atomsvc
.getAtom("item-xml");
72 ScriptInstanceRecord
.prototype.atomDisabled
=
73 atomsvc
.getAtom("script-disabled");
75 ScriptRecord
.prototype.atomFunction
= atomsvc
.getAtom("file-function");
76 ScriptRecord
.prototype.atomBreakpoint
= atomsvc
.getAtom("item-has-bp");
77 ScriptRecord
.prototype.atomDisabled
= atomsvc
.getAtom("script-disabled");
81 ["valueRecord.showFunctions", false],
82 ["valueRecord.showECMAProps", false],
83 ["valueRecord.showConstants", false],
84 ["valueRecord.brokenObjects", "^JavaPackage$"]
87 console
.prefManager
.addPrefs(prefs
);
91 ValueRecord
.prototype.brokenObjects
=
92 new RegExp (console
.prefs
["valueRecord.brokenObjects"]);
96 display (MSN_ERR_INVALID_PREF
,
97 ["valueRecord.brokenObjects",
98 console
.prefs
["valueRecord.brokenObjects"]], MT_ERROR
);
99 display (formatException(ex
), MT_ERROR
);
100 ValueRecord
.prototype.brokenObjects
= /^JavaPackage$/;
103 ValueRecord
.prototype.atomVoid
= atomsvc
.getAtom("item-void");
104 ValueRecord
.prototype.atomNull
= atomsvc
.getAtom("item-null");
105 ValueRecord
.prototype.atomBool
= atomsvc
.getAtom("item-bool");
106 ValueRecord
.prototype.atomInt
= atomsvc
.getAtom("item-int");
107 ValueRecord
.prototype.atomDouble
= atomsvc
.getAtom("item-double");
108 ValueRecord
.prototype.atomString
= atomsvc
.getAtom("item-string");
109 ValueRecord
.prototype.atomFunction
= atomsvc
.getAtom("item-function");
110 ValueRecord
.prototype.atomObject
= atomsvc
.getAtom("item-object");
111 ValueRecord
.prototype.atomError
= atomsvc
.getAtom("item-error");
112 ValueRecord
.prototype.atomException
= atomsvc
.getAtom("item-exception");
113 ValueRecord
.prototype.atomHinted
= atomsvc
.getAtom("item-hinted");
116 /*******************************************************************************
118 * One prototype for all breakpoint types, works only in the Breakpoints View.
119 *******************************************************************************/
121 function BPRecord (breakWrapper
)
123 this.setColumnPropertyName ("col-0", "name");
124 this.setColumnPropertyName ("col-1", "line");
126 this.breakWrapper
= breakWrapper
;
128 if ("pc" in breakWrapper
)
130 this.type
= "instance";
131 this.name
= breakWrapper
.scriptWrapper
.functionName
;
132 this.line
= getMsg(MSN_FMT_PC
, String(breakWrapper
.pc
));
134 else if (breakWrapper
instanceof FutureBreakpoint
)
136 this.type
= "future";
137 var ary
= breakWrapper
.url
.match(/\/([^\/?]+)(\?|$)/);
141 this.name
= breakWrapper
.url
;
143 this.line
= breakWrapper
.lineNumber
;
147 BPRecord
.prototype = new XULTreeViewRecord(console
.views
.breaks
.share
);
149 /*******************************************************************************
150 * Stack Frame Record.
151 * Represents a jsdIStackFrame, for use in the Stack View only.
152 *******************************************************************************/
154 function FrameRecord (jsdFrame
)
156 if (!(jsdFrame
instanceof jsdIStackFrame
))
157 throw new BadMojo (ERR_INVALID_PARAM
, "value");
159 this.setColumnPropertyName ("col-0", "functionName");
160 this.setColumnPropertyName ("col-1", "location");
162 this.functionName
= jsdFrame
.functionName
;
163 if (!jsdFrame
.isNative
)
165 this.scriptWrapper
= getScriptWrapper(jsdFrame
.script
);
166 this.location
= getMsg(MSN_FMT_FRAME_LOCATION
,
167 [getFileFromPath(jsdFrame
.script
.fileName
),
168 jsdFrame
.line
, jsdFrame
.pc
]);
169 this.functionName
= this.scriptWrapper
.functionName
;
173 this.scriptWrapper
= null;
174 this.location
= MSG_URL_NATIVE
;
177 this.jsdFrame
= jsdFrame
;
180 FrameRecord
.prototype = new XULTreeViewRecord (console
.views
.stack
.share
);
182 /*******************************************************************************
184 * Represents a DOM window with files and child windows. For use in the
186 *******************************************************************************/
188 function WindowRecord (win
, baseURL
)
190 function none() { return ""; };
191 this.setColumnPropertyName ("col-0", "displayName");
194 this.url
= win
.location
.href
;
195 if (this.url
.search(/^\w+:/) == -1)
197 if (this.url
[0] == "/")
199 this.url
= win
.location
.protocol
+ "//" + win
.location
.host
+
204 this.url
= baseURL
+ this.url
;
206 this.baseURL
= baseURL
;
210 this.baseURL
= getPathFromURL(this.url
);
211 if (this.baseURL
.indexOf("file:///") == 0)
212 this.baseURL
= "file:/" + this.baseURL
.substr(8)
215 this.reserveChildren(true);
216 this.shortName
= getFileFromPath (this.url
);
217 if (console
.prefs
["enableChromeFilter"] && this.shortName
== "navigator.xul")
219 this.displayName
= MSG_NAVIGATOR_XUL
;
221 else if (console
.prefs
["enableChromeFilter"] && this.shortName
== "browser.xul")
223 this.displayName
= MSG_BROWSER_XUL
;
227 this.filesRecord
= new FileContainerRecord(this);
228 this.displayName
= this.shortName
;
233 WindowRecord
.prototype = new XULTreeViewRecord(console
.views
.windows
.share
);
235 WindowRecord
.prototype.onPreOpen
=
236 function wr_preopen()
238 this.childData
= new Array();
240 if ("filesRecord" in this)
241 this.appendChild(this.filesRecord
);
243 var framesLength
= this.window
.frames
.length
;
244 for (var i
= 0; i
< framesLength
; ++i
)
246 this.appendChild(new WindowRecord(this.window
.frames
[i
].window
,
251 /*******************************************************************************
252 * "File Container" Record.
253 * List of script tags found in the parent record's |window.document| property.
254 * For use in the Windows View, as a child of a WindowRecord.
255 *******************************************************************************/
257 function FileContainerRecord (windowRecord
)
259 function files() { return MSG_FILES_REC
; }
260 function none() { return ""; }
261 this.setColumnPropertyName ("col-0", files
);
262 this.windowRecord
= windowRecord
;
263 this.reserveChildren(true);
266 FileContainerRecord
.prototype =
267 new XULTreeViewRecord(console
.views
.windows
.share
);
269 FileContainerRecord
.prototype.onPreOpen
=
270 function fcr_getkids ()
272 if (!("parentRecord" in this))
275 this.childData
= new Array();
276 var doc
= this.windowRecord
.window
.document
;
277 var loc
= this.windowRecord
.window
.location
;
278 var nodeList
= doc
.getElementsByTagName("script");
280 for (var i
= 0; i
< nodeList
.length
; ++i
)
282 var url
= nodeList
.item(i
).getAttribute("src");
285 if (url
.search(/^\w+:/) == -1)
288 url
= loc
.protocol
+ "//" + loc
.host
+ url
;
290 url
= this.windowRecord
.baseURL
+ url
;
294 this.baseURL
= getPathFromURL(url
);
297 this.appendChild(new FileRecord(url
));
302 /*******************************************************************************
304 * Represents a URL, for use in the Windows View only.
305 *******************************************************************************/
307 function FileRecord (url
)
309 function none() { return ""; }
310 this.setColumnPropertyName ("col-0", "shortName");
312 this.shortName
= getFileFromPath(url
);
315 FileRecord
.prototype = new XULTreeViewRecord(console
.views
.windows
.share
);
317 /*******************************************************************************
318 * Script Instance Record.
319 * Represents a ScriptInstance, for use in the Scripts View only.
320 *******************************************************************************/
322 function ScriptInstanceRecord(scriptInstance
)
324 if (!ASSERT(scriptInstance
.isSealed
,
325 "Attempt to create ScriptInstanceRecord for unsealed instance"))
330 this.setColumnPropertyName ("col-0", "displayName");
331 this.setColumnPropertyValue ("col-1", "");
332 this.setColumnPropertyValue ("col-2", "");
333 this.reserveChildren(true);
334 this.url
= scriptInstance
.url
;
335 var sv
= console
.views
.scripts
;
336 this.fileType
= this.atomUnknown
;
337 this.shortName
= this.url
;
339 this.scriptInstance
= scriptInstance
;
340 this.lastScriptCount
= 0;
341 this.sequence
= scriptInstance
.sequence
;
343 this.shortName
= getFileFromPath(this.url
);
344 var ary
= this.shortName
.match (/\.(js|html|xul|xml)$/i);
347 switch (ary
[1].toLowerCase())
350 this.fileType
= this.atomJS
;
356 this.fileType
= this.atomHTML
;
361 this.fileType
= this.atomXUL
;
366 this.fileType
= this.atomXML
;
371 this.displayName
= this.shortName
;
372 this.sortName
= this.shortName
.toLowerCase();
376 ScriptInstanceRecord
.prototype =
377 new XULTreeViewRecord(console
.views
.scripts
.share
);
379 ScriptInstanceRecord
.prototype.onDragStart
=
380 function scr_dragstart (e
, transferData
, dragAction
)
382 transferData
.data
= new TransferData();
383 transferData
.data
.addDataForFlavour("text/x-venkman-file", this.fileName
);
384 transferData
.data
.addDataForFlavour("text/x-moz-url", this.fileName
);
385 transferData
.data
.addDataForFlavour("text/unicode", this.fileName
);
386 transferData
.data
.addDataForFlavour("text/html",
387 "<a href='" + this.fileName
+
388 "'>" + this.fileName
+ "</a>");
392 ScriptInstanceRecord
.prototype.getProperties
=
393 function scr_getprops (properties
)
395 properties
.AppendElement(this.fileType
);
397 if (this.scriptInstance
.disabledScripts
> 0)
398 properties
.AppendElement (this.atomDisabled
);
401 ScriptInstanceRecord
.prototype.super_resort
= XTRootRecord
.prototype.resort
;
403 ScriptInstanceRecord
.prototype.resort
=
404 function scr_resort ()
406 console
._groupFiles
= console
.prefs
["scriptsView.groupFiles"];
408 delete console
._groupFiles
;
411 ScriptInstanceRecord
.prototype.sortCompare
=
412 function scr_compare (a
, b
)
416 if (a
.group
< b
.group
)
419 if (a
.group
> b
.group
)
423 if (a
.sortName
< b
.sortName
)
426 if (a
.sortName
> b
.sortName
)
429 if (a
.sequence
< b
.sequence
)
432 if (a
.sequence
> b
.sequence
)
435 dd ("ack, all equal?");
439 ScriptInstanceRecord
.prototype.onPreOpen
=
440 function scr_preopen ()
442 if (!this.scriptInstance
.sourceText
.isLoaded
)
443 this.scriptInstance
.sourceText
.loadSource();
445 if (this.lastScriptCount
!= this.scriptInstance
.scriptCount
)
449 console
.views
.scripts
.freeze();
450 this.childData
= new Array();
451 var scriptWrapper
= this.scriptInstance
.topLevel
;
454 sr
= new ScriptRecord(scriptWrapper
);
455 scriptWrapper
.scriptRecord
= sr
;
456 this.appendChild(sr
);
459 var functions
= this.scriptInstance
.functions
;
460 for (var f
in functions
)
462 if (functions
[f
].jsdScript
.isValid
)
464 sr
= new ScriptRecord(functions
[f
]);
465 functions
[f
].scriptRecord
= sr
;
466 this.appendChild(sr
);
469 console
.views
.scripts
.thaw();
470 this.lastScriptCount
= this.scriptInstance
.scriptCount
;
474 /*******************************************************************************
476 * Represents a ScriptWrapper, for use in the Scripts View only.
477 *******************************************************************************/
479 function ScriptRecord(scriptWrapper
)
481 this.setColumnPropertyName ("col-0", "functionName");
482 this.setColumnPropertyName ("col-1", "baseLineNumber");
483 this.setColumnPropertyName ("col-2", "lineExtent");
485 this.functionName
= scriptWrapper
.functionName
486 this.baseLineNumber
= scriptWrapper
.jsdScript
.baseLineNumber
;
487 this.lineExtent
= scriptWrapper
.jsdScript
.lineExtent
;
488 this.scriptWrapper
= scriptWrapper
;
490 this.jsdurl
= "jsd:sourcetext?url=" +
491 encodeURIComponent(this.scriptWrapper
.jsdScript
.fileName
) +
492 "&base=" + this.baseLineNumber
+ "&extent=" + this.lineExtent
+
493 "&name=" + this.functionName
;
496 ScriptRecord
.prototype = new XULTreeViewRecord(console
.views
.scripts
.share
);
498 ScriptRecord
.prototype.onDragStart
=
499 function sr_dragstart (e
, transferData
, dragAction
)
501 var fileName
= this.script
.fileName
;
502 transferData
.data
= new TransferData();
503 transferData
.data
.addDataForFlavour("text/x-jsd-url", this.jsdurl
);
504 transferData
.data
.addDataForFlavour("text/x-moz-url", fileName
);
505 transferData
.data
.addDataForFlavour("text/unicode", fileName
);
506 transferData
.data
.addDataForFlavour("text/html",
507 "<a href='" + fileName
+
508 "'>" + fileName
+ "</a>");
512 ScriptRecord
.prototype.getProperties
=
513 function sr_getprops (properties
)
515 properties
.AppendElement (this.atomFunction
);
517 if (this.scriptWrapper
.breakpointCount
)
518 properties
.AppendElement (this.atomBreakpoint
);
520 if (this.scriptWrapper
.jsdScript
.isValid
&&
521 this.scriptWrapper
.jsdScript
.flags
& SCRIPT_NODEBUG
)
523 properties
.AppendElement (this.atomDisabled
);
527 /*******************************************************************************
529 * Use this to show a jsdIValue in any tree.
530 *******************************************************************************/
532 function cmdShowFunctions (e
)
534 if (e
.toggle
!= null)
536 e
.toggle
= getToggle(e
.toggle
, ValueRecord
.prototype.showFunctions
);
537 ValueRecord
.prototype.showFunctions
= e
.toggle
;
538 console
.prefs
["valueRecord.showFunctions"] = e
.toggle
;
541 if ("isInteractive" in e
&& e
.isInteractive
)
542 dispatch("pref valueRecord.showFunctions", { isInteractive
: true });
545 function cmdShowECMAs (e
)
547 if (e
.toggle
!= null)
549 e
.toggle
= getToggle(e
.toggle
, ValueRecord
.prototype.showECMAProps
);
550 ValueRecord
.prototype.showECMAProps
= e
.toggle
;
551 console
.prefs
["valueRecord.showECMAProps"] = e
.toggle
;
554 if ("isInteractive" in e
&& e
.isInteractive
)
555 dispatch("pref valueRecord.showECMAProps", { isInteractive
: true });
558 function cmdShowConstants (e
)
560 if (e
.toggle
!= null)
562 e
.toggle
= getToggle(e
.toggle
, ValueRecord
.prototype.showConstants
);
563 ValueRecord
.prototype.showConstants
= e
.toggle
;
564 console
.prefs
["valueRecord.showConstants"] = e
.toggle
;
567 if ("isInteractive" in e
&& e
.isInteractive
)
568 dispatch("pref valueRecord.showConstants", { isInteractive
: true });
571 function ValueRecord (value
, name
, flags
, jsdFrame
)
573 if (!(value
instanceof jsdIValue
))
574 throw new BadMojo (ERR_INVALID_PARAM
, "value", String(value
));
576 this.setColumnPropertyName ("col-0", "displayName");
577 this.setColumnPropertyName ("col-1", "displayType");
578 this.setColumnPropertyName ("col-2", "displayValue");
579 this.setColumnPropertyName ("col-3", "displayFlags");
580 this.displayName
= name
;
581 this.displayFlags
= formatFlags(flags
);
585 this.jsdFrame
= jsdFrame
;
587 this.onPreRefresh
= false;
589 delete this.onPreRefresh
;
592 ValueRecord
.prototype = new XULTreeViewRecord (null);
594 ValueRecord
.prototype.__defineGetter__("_share", vr_getshare
);
595 function vr_getshare()
597 if ("__share" in this)
600 if ("parentRecord" in this)
601 return this.__share
= this.parentRecord
._share
;
603 ASSERT (0, "ValueRecord cannot be the root of a visible tree.");
607 ValueRecord
.prototype.__defineGetter__("expression", vr_getexpressionl
);
608 function vr_getexpressionl()
610 return this.getExpression();
613 ValueRecord
.prototype.getExpression
=
614 function vr_getexpression(extra
)
616 var items
= [this.displayName
];
618 if ("value" in this.parentRecord
)
620 var cur
= this.parentRecord
;
621 while (!("isRootRecord" in cur
) || !cur
.isRootRecord
)
623 if ("isECMAProto" in cur
)
624 items
.unshift("__proto__");
625 else if ("isECMAParent" in cur
)
626 items
.unshift("__parent__");
628 items
.unshift(cur
.displayName
);
629 cur
= cur
.parentRecord
;
633 if (typeof extra
== "string")
636 return makeExpression(items
);
639 ValueRecord
.prototype.evalString
=
640 function vr_evalstring(string
)
642 //dd("ValueRecord(" + this.displayName + ").evalString(" + string + ")");
643 var rval
= new Object();
644 if (this.jsdFrame
.eval(string
, JSD_URL_SCHEME
+ "value-record", 1, rval
))
649 ValueRecord
.prototype.showFunctions
= false;
650 ValueRecord
.prototype.showECMAProps
= false;
651 ValueRecord
.prototype.showConstants
= false;
653 ValueRecord
.prototype.getProperties
=
654 function vr_getprops (properties
)
656 if ("valueIsException" in this || this.flags
& PROP_EXCEPTION
)
657 properties
.AppendElement (this.atomException
);
659 if (this.flags
& PROP_ERROR
)
660 properties
.AppendElement (this.atomError
);
662 if (this.flags
& PROP_HINTED
)
663 properties
.AppendElement (this.atomHinted
);
665 properties
.AppendElement (this.property
);
668 ValueRecord
.prototype.onPreRefresh
=
669 function vr_prerefresh ()
671 if (!ASSERT("parentRecord" in this, "onPreRefresh with no parent"))
674 if ("isECMAProto" in this)
676 if (this.parentRecord
.value
.jsPrototype
)
677 this.value
= this.parentRecord
.value
.jsPrototype
;
679 this.value
= console
.jsds
.wrapValue(null);
681 else if ("isECMAParent" in this)
683 if (this.parentRecord
.value
.jsParent
)
684 this.value
= this.parentRecord
.value
.jsParent
;
686 this.value
= console
.jsds
.wrapValue(null);
690 var value
= this.parentRecord
.value
;
691 var prop
= value
.getProperty (this.name
);
694 this.flags
= prop
.flags
;
695 this.value
= prop
.value
;
699 ASSERT(this.jsdFrame
, "ValueRecord(" + this.displayName
+
700 ").onPreRefresh: no jsdIStackFrame to safely eval on!");
702 this.value
= this.evalString(this.expression
);
703 this.flags
= PROP_ENUMERATE
| PROP_HINTED
;
708 ValueRecord
.prototype.refresh
=
709 function vr_refresh ()
711 if (this.onPreRefresh
)
716 delete this.valueIsException
;
721 dd ("caught exception refreshing " + this.displayName);
722 if (typeof ex == "object")
723 dd (dumpObjectTree(ex));
727 if (!(ex
instanceof jsdIValue
))
728 ex
= console
.jsds
.wrapValue(ex
);
731 this.valueIsException
= true;
735 this.jsType
= this.value
.jsType
;
736 delete this.alwaysHasChildren
;
743 this.displayValue
= MSG_TYPE_VOID
744 this.displayType
= MSG_TYPE_VOID
;
745 this.property
= this.atomVoid
;
748 this.displayValue
= MSG_TYPE_NULL
;
749 this.displayType
= MSG_TYPE_NULL
;
750 this.property
= this.atomNull
;
753 this.displayValue
= this.value
.stringValue
;
754 this.displayType
= MSG_TYPE_BOOLEAN
;
755 this.property
= this.atomBool
;
758 this.displayValue
= this.value
.intValue
;
759 this.displayType
= MSG_TYPE_INT
;
760 this.property
= this.atomInt
;
763 this.displayValue
= this.value
.doubleValue
;
764 this.displayType
= MSG_TYPE_DOUBLE
;
765 this.property
= this.atomDouble
;
768 strval
= this.value
.stringValue
;
769 if (strval
.length
> console
.prefs
["maxStringLength"])
770 strval
= getMsg(MSN_FMT_LONGSTR
, strval
.length
);
772 strval
= strval
.quote();
773 this.displayValue
= strval
;
774 this.displayType
= MSG_TYPE_STRING
;
775 this.property
= this.atomString
;
779 this.displayType
= MSG_TYPE_OBJECT
;
780 this.property
= this.atomObject
;
782 this.alwaysHasChildren
= true;
783 this.value
.refresh();
785 var ctor
= this.value
.jsClassName
;
791 this.displayType
= MSG_TYPE_FUNCTION
;
792 ctor
= (this.value
.isNative
? MSG_CLASS_NATIVE_FUN
:
793 MSG_CLASS_SCRIPT_FUN
);
794 this.property
= this.atomFunction
;
798 if (this.value
.jsConstructor
)
799 ctor
= this.value
.jsConstructor
.jsFunctionName
;
802 case "XPCWrappedNative_NoHelper":
803 ctor
= MSG_CLASS_CONST_XPCOBJ
;
806 case "XPC_WN_ModsAllowed_Proto_JSClass":
807 ctor
= MSG_CLASS_XPCOBJ
;
811 strval
= this.value
.stringValue
;
812 if (strval
.length
> console
.prefs
["maxStringLength"])
813 strval
= getMsg(MSN_FMT_LONGSTR
, strval
.length
);
815 strval
= strval
.quote();
820 strval
= this.value
.stringValue
;
826 this.displayValue
= strval
;
833 if (this.brokenObjects
.test(ctor
))
835 /* XXX these objects do Bad Things when you enumerate
841 propCount
= this.countProperties();
844 this.displayValue
= getMsg (MSN_FMT_OBJECT_VALUE
,
849 this.displayValue
= "{" + ctor
+ "}";
853 /* if we have children, refresh them. */
854 if ("childData" in this && this.childData
.length
> 0)
856 if (!this.refreshChildren())
858 dd ("refreshChilren failed for " + this.displayName
);
859 delete this.childData
;
866 ASSERT (0, "invalid value");
870 ValueRecord
.prototype.countProperties
=
871 function vr_countprops ()
873 ASSERT(this.jsdFrame
, "ValueRecord(" + this.displayName
+
874 ").countProperties: no jsdIStackFrame to safely eval on!");
876 // Note: uses an inline function to avoid polluting the frame's scope.
877 var code
= "(function(obj){" +
879 " for (var prop in obj)" +
882 "})(" + this.expression
+ ")";
884 // rv is undefined if an exception occured.
885 var rv
= this.evalString(code
);
886 if (typeof rv
== "undefined")
892 ValueRecord
.prototype.listProperties
=
893 function vr_listprops ()
895 function charEscapeReplace(s
, c
)
897 return String
.fromCharCode(parseInt(c
, 16));
900 // the ":" prefix for keys in the propMap avoid collisions with "real"
901 // pseudo-properties, such as __proto__. If we were to actually assign
902 // to those we would introduce bad side affects.
904 //dd ("listProperties {");
906 var propMap
= new Object();
908 /* get the enumerable properties */
910 ASSERT(this.jsdFrame
, "ValueRecord(" + this.displayName
+
911 ").listProperties: no jsdIStackFrame to safely eval on!");
913 var propList
= new Array();
915 // quote() puts double-quotes at either end of the string,
916 // backspash-escapes double-quotes in the string, and (quite
917 // importantly) uses \xXX and \uXXXX escapes for non-ASCII
920 // Note: uses an inline function to avoid polluting the frame's scope.
921 var code
= "(function(obj){" +
922 " var string = '';" +
923 " for (var prop in obj) {" +
926 " string += prop.quote();" +
929 "})(" + this.expression
+ ")";
931 // list is undefined if an exception occured.
932 var list
= this.evalString(code
);
933 if (typeof list
!= "undefined") {
934 list
= list
.stringValue
;
935 //dd("ValueRecord(" + this.displayName +
936 // ").listProperties: list: " + list);
938 list
= ('",' + list
+ ',"').split('","');
940 for (i
= 0; i
< list
.length
; i
++)
946 prop
= prop
.replace(/\\x([0-9a-f]{2})/i, charEscapeReplace
);
947 prop
= prop
.replace(/\\u([0-9a-f]{4})/i, charEscapeReplace
);
948 prop
= prop
.replace(/\\(.)/, "$1");
950 //dd("ValueRecord(" + this.displayName +
951 // ").listProperties: prop: " + prop);
956 for (i
= 0; i
< propList
.length
; i
++)
962 value
= this.evalString(this.getExpression(p
));
964 if (this.showFunctions
|| value
.jsType
!= TYPE_FUNCTION
)
966 propMap
[":" + p
] = { name
: p
, value
: value
,
967 flags
: PROP_ENUMERATE
| PROP_HINTED
};
971 //dd ("not including function " + name);
972 propMap
[":" + p
] = null;
977 propMap
[":" + p
] = { name
: p
, value
: console
.jsds
.wrapValue(ex
),
978 flags
: PROP_EXCEPTION
};
981 //dd ("jsval props: adding " + p + ", " + propMap[":" + p]);
985 /* get the local properties, may or may not be enumerable */
986 var localProps
= new Object()
987 this.value
.getProperties(localProps
, {});
988 localProps
= localProps
.value
;
989 var len
= localProps
.length
;
990 for (i
= 0; i
< len
; ++i
)
992 var prop
= localProps
[i
];
993 var name
= prop
.name
.stringValue
;
995 if (!((":" + name
) in propMap
))
997 if ((this.showFunctions
|| prop
.value
.jsType
!= TYPE_FUNCTION
) &&
998 (this.showConstants
|| !(prop
.flags
& PROP_READONLY
)))
1000 //dd ("localProps: adding " + name + ", " + prop);
1001 propMap
[":" + name
] = { name
: name
, value
: prop
.value
,
1002 flags
: prop
.flags
};
1006 //dd ("not including function " + name);
1007 propMap
[":" + name
] = null;
1012 if (!this.showConstants
&& (prop
.flags
& PROP_READONLY
))
1013 propMap
[":" + name
] = null;
1014 if (propMap
[":" + name
])
1015 propMap
[":" + name
].flags
= prop
.flags
;
1019 /* sort the property list */
1020 var nameList
= keys(propMap
);
1021 //dd ("nameList is " + nameList);
1024 var propertyList
= new Array();
1025 for (i
= 0; i
< nameList
.length
; ++i
)
1029 propertyList
.push (propMap
[name
]);
1032 //dd ("} " + propertyList.length + " properties");
1034 return propertyList
;
1037 ValueRecord
.prototype.refreshChildren
=
1038 function vr_refreshkids ()
1040 var leadingProps
= 0;
1042 this.propertyList
= this.listProperties();
1044 for (var i
= 0; i
< this.childData
.length
; ++i
)
1046 if ("isECMAParent" in this.childData
[i
] ||
1047 "isECMAProto" in this.childData
[i
])
1051 else if (this.childData
.length
- leadingProps
!=
1052 this.propertyList
.length
)
1054 dd ("refreshChildren: property length mismatch");
1057 else if (this.childData
[i
]._colValues
["col-0"] !=
1058 this.propertyList
[i
- leadingProps
].name
)
1060 dd ("refreshChildren: " +
1061 this.childData
[i
]._colValues
["col-0"] + " != " +
1062 this.propertyList
[i
- leadingProps
].name
);
1066 this.childData
[i
].refresh();
1069 if (this.childData
.length
- leadingProps
!=
1070 this.propertyList
.length
)
1072 dd ("refreshChildren: property length mismatch");
1078 ValueRecord
.prototype.onPreOpen
=
1079 function vr_preopen()
1083 if (!ASSERT(this.value
.jsType
== TYPE_OBJECT
||
1084 this.value
.jsType
== TYPE_FUNCTION
,
1085 "onPreOpen called for non object?"))
1090 this.childData
= new Array();
1091 this.propertyList
= this.listProperties();
1093 if (this.showECMAProps
)
1096 if (this.value
.jsPrototype
)
1098 rec
= new ValueRecord(this.value
.jsPrototype
,
1099 MSG_VAL_PROTO
, "", this.jsdFrame
);
1100 rec
.isECMAProto
= true;
1101 this.appendChild (rec
);
1104 if (this.value
.jsParent
)
1106 rec
= new ValueRecord(this.value
.jsParent
,
1107 MSG_VAL_PARENT
, "", this.jsdFrame
);
1108 rec
.isECMAParent
= true;
1109 this.appendChild (rec
);
1113 if (!this.childData
.length
&& !this.propertyList
.length
)
1115 rec
= new XTLabelRecord ("col-0", MSG_VAL_NONE
,
1116 ["col-1", "col-2", "col-3"]);
1117 this.appendChild(rec
);
1121 for (var i
= 0; i
< this.propertyList
.length
; ++i
)
1123 var prop
= this.propertyList
[i
];
1124 this.appendChild(new ValueRecord(prop
.value
,
1132 display (getMsg (MSN_ERR_FAILURE
, ex
), MT_ERROR
);
1136 ValueRecord
.prototype.onPostClose
=
1137 function vr_destroy()
1139 this.childData
= new Array();
1140 delete this.propertyList
;