PK
lB+C? skin/modern/venkman/contents.rdfUT W; VDDUx
PK
,k;U U content/venkman/venkman.xulUT CE= VDDUx
PK
㆕.H% % ! content/venkman/venkman-views.xulUT ڄ>!VDDUx
PK
,
# content/venkman/venkman-floater.xulUT 6=!VDDUx
PK
I^y.Z> " content/venkman/venkman-floater.jsUT >!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
var dd = opener.dd;
var console = opener.console;
var getMsg = opener.getMsg;
var dispatch = console.dispatch;
var windowId;
var containedViews = new Object();
function onLoad()
{
var ary = document.location.search.match(/(?:\?|&)id=([^&]+)/);
if (!ary)
{
dd ("No window id in url " + document.location);
return;
}
windowId = ary[1];
if (console.prefs["menubarInFloaters"])
console.createMainMenu (window.document);
if ("arguments" in window && 0 in window.arguments &&
typeof window.arguments[0] == "function")
{
setTimeout(window.arguments[0], 500, window);
}
}
function onClose()
{
window.isClosing = true;
return true;
}
function onUnload()
{
console.viewManager.destroyWindow (windowId);
}
function onViewRemoved(view)
{
delete containedViews[view.viewId];
updateTitle();
}
function onViewAdded(view)
{
containedViews[view.viewId] = view;
updateTitle();
}
function updateTitle()
{
var ary = new Array();
for (v in containedViews)
ary.push(containedViews[v].caption);
var views = ary.join(opener.MSG_COMMASP);
if (views == "")
views = opener.MSG_VAL_NONE;
document.title = getMsg(opener.MSN_FLOATER_TITLE, views);
}
PK
.Hp? ? $ content/venkman/venkman-bindings.xmlUT (>!VDDUx
PK
q.+ ! content/venkman/venkman-menus.xulUT %q>!VDDUx
PK
Xz/" " content/venkman/venkman-menus.jsUT PA?!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
function initMenus()
{
function onMenuCommand (event, window)
{
var params;
var commandName = event.originalTarget.getAttribute("commandname");
if ("cx" in console.menuManager && console.menuManager.cx)
{
console.menuManager.cx.sourceWindow = window;
params = console.menuManager.cx;
}
else
{
params = { sourceWindow: window };
}
dispatch (commandName, params);
delete console.menuManager.cx;
};
console.onMenuCommand = onMenuCommand;
console.menuSpecs = new Object();
var menuManager =
console.menuManager = new MenuManager(console.commandManager,
console.menuSpecs,
getCommandContext,
"console.onMenuCommand(event, " +
"window);");
console.menuSpecs["maintoolbar"] = {
items:
[
["stop"],
["-"],
["cont"],
["next"],
["step"],
["finish"],
["-"],
["profile-tb"],
["toggle-pprint"]
]
};
console.menuSpecs["mainmenu:file"] = {
label: MSG_MNU_FILE,
items:
[
["open-url"],
["find-file"],
["close-source-tab",
{enabledif: "console.views.source2.currentContent && " +
"console.views.source2.sourceTabList.length"}],
["close"],
["-"],
["save-source-tab", { enabledif: "console.views.source2.canSave()" }],
["save-profile"],
["-"],
["save-settings"],
["restore-settings"],
["toggle-save-settings",
{type: "checkbox",
checkedif: "console.prefs['saveSettingsOnExit']"}],
["-"],
[navigator.platform.search(/win/i) == -1 ? "quit" : "exit"]
]
};
console.menuSpecs["mainmenu:view"] = {
label: MSG_MNU_VIEW,
items:
[
[">popup:showhide"],
["-"],
["reload-source-tab"],
["toggle-source-coloring",
{type: "checkbox",
checkedif: "console.prefs['services.source.colorize']"} ],
["toggle-pprint",
{type: "checkbox",
checkedif: "console.prefs['prettyprint']"}],
["-"],
["clear-session"],
[">session:colors"],
["-"],
["save-default-layout"],
["toggle-save-layout",
{type: "checkbox",
checkedif: "console.prefs['saveLayoutOnExit']"}]
]
};
console.menuSpecs["mainmenu:debug"] = {
label: MSG_MNU_DEBUG,
items:
[
["stop",
{type: "checkbox",
checkedif: "console.jsds.interruptHook"}],
["cont"],
["next"],
["step"],
["finish"],
["-"],
[">popup:emode"],
[">popup:tmode"],
["-"],
["toggle-chrome",
{type: "checkbox",
checkedif: "console.prefs['enableChromeFilter']"}]
/*
["toggle-ias",
{type: "checkbox",
checkedif: "console.jsds.initAtStartup"}]
*/
]
};
console.menuSpecs["mainmenu:profile"] = {
label: MSG_MNU_PROFILE,
items:
[
["toggle-profile",
{type: "checkbox",
checkedif: "console.jsds.flags & COLLECT_PROFILE_DATA"}],
["clear-profile"],
["save-profile"]
]
};
/* Mac expects a help menu with this ID, and there is nothing we can do
* about it. */
console.menuSpecs["mainmenu:help"] = {
label: MSG_MNU_HELP,
domID: "menu_Help",
items:
[
["version"],
["-"],
["help"]
]
};
console.menuSpecs["popup:emode"] = {
label: MSG_MNU_EMODE,
items:
[
["em-ignore",
{type: "radio", name: "em",
checkedif: "console.errorMode == EMODE_IGNORE"}],
["em-trace",
{type: "radio", name: "em",
checkedif: "console.errorMode == EMODE_TRACE"}],
["em-break",
{type: "radio", name: "em",
checkedif: "console.errorMode == EMODE_BREAK"}]
]
};
console.menuSpecs["popup:tmode"] = {
label: MSG_MNU_TMODE,
items:
[
["tm-ignore",
{type: "radio", name: "tm",
checkedif: "console.throwMode == TMODE_IGNORE"}],
["tm-trace",
{type: "radio", name: "tm",
checkedif: "console.throwMode == TMODE_TRACE"}],
["tm-break",
{type: "radio", name: "tm",
checkedif: "console.throwMode == TMODE_BREAK"}]
]
};
console.menuSpecs["popup:showhide"] = {
label: MSG_MNU_SHOWHIDE,
items: [ /* filled by initViews() */ ]
};
}
console.createMainMenu = createMainMenu;
function createMainMenu(document)
{
var mainmenu = document.getElementById("mainmenu");
var menuManager = console.menuManager;
for (var id in console.menuSpecs)
{
var domID;
if ("domID" in console.menuSpecs[id])
domID = console.menuSpecs[id].domID;
else
domID = id;
if (id.indexOf("mainmenu:") == 0)
menuManager.createMenu (mainmenu, null, id, domID);
}
mainmenu.removeAttribute ("collapsed");
var toolbox = document.getElementById("main-toolbox");
toolbox.removeAttribute ("collapsed");
}
console.createMainToolbar = createMainToolbar;
function createMainToolbar(document)
{
var maintoolbar = document.getElementById("maintoolbar");
var menuManager = console.menuManager;
var spec = console.menuSpecs["maintoolbar"];
for (var i in spec.items)
{
menuManager.appendToolbarItem (maintoolbar, null, spec.items[i]);
}
maintoolbar = document.getElementById("maintoolbar-outer");
maintoolbar.removeAttribute ("collapsed");
maintoolbar.className = "toolbar-primary chromeclass-toolbar";
var toolbox = document.getElementById("main-toolbox");
toolbox.removeAttribute ("collapsed");
}
function getCommandContext (id, event)
{
var cx = { originalEvent: event };
if (id in console.menuSpecs)
{
if ("getContext" in console.menuSpecs[id])
cx = console.menuSpecs[id].getContext(cx);
else if ("cx" in console.menuManager)
{
//dd ("using existing context");
cx = console.menuManager.cx;
}
else
{
//dd ("no context at all");
}
}
else
{
dd ("getCommandContext: unknown menu id " + id);
}
if (typeof cx == "object")
{
if (!("menuManager" in cx))
cx.menuManager = console.menuManager;
if (!("contextSource" in cx))
cx.contextSource = id;
if ("dbgContexts" in console && console.dbgContexts)
dd ("context '" + id + "'\n" + dumpObjectTree(cx));
}
return cx;
}
PK
m.S˿ # content/venkman/venkman-scripts.xulUT >!VDDUx
PK
/z/
I5
]
] content/venkman/venkman-utils.jsUT ?!VDDUx /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code
*
* The Initial Developer of the Original Code is New Dimensions Consulting,
* Inc. Portions created by New Dimensions Consulting, Inc. are
* Copyright (C) 1999 New Dimensions Consulting, Inc. All Rights Reserved.
*
* Contributor(s):
* Robert Ginda, rginda@ndcico.com, original author
*
*
* JavaScript utility functions.
*/
var dumpln;
var dd;
const nsIBaseWindow = Components.interfaces.nsIBaseWindow;
const nsIXULWindow = Components.interfaces.nsIXULWindow;
const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
var utils = new Object();
if (typeof document == "undefined") /* in xpcshell */
{
dumpln = print;
}
else
{
if (typeof dump == "function")
dumpln = function (str) {dump (str + "\n");}
else if (jsenv.HAS_RHINO)
{
dumpln = function (str) {
var out = java.lang.System.out;
out.println(str); out.flush();
}
}
else
dumpln = function () {} /* no suitable function */
}
if (DEBUG) {
var _dd_pfx = "";
var _dd_singleIndent = " ";
var _dd_indentLength = _dd_singleIndent.length;
var _dd_currentIndent = "";
var _dd_lastDumpWasOpen = false;
var _dd_timeStack = new Array();
var _dd_disableDepth = Number.MAX_VALUE;
var _dd_currentDepth = 0;
dd = function _dd (str) {
if (typeof str != "string") {
dumpln (str);
} else if (str[str.length - 1] == "{") {
++_dd_currentDepth;
if (_dd_currentDepth >= _dd_disableDepth)
return;
if (str.indexOf("OFF") == 0)
_dd_disableDepth = _dd_currentDepth;
_dd_timeStack.push (new Date());
if (_dd_lastDumpWasOpen)
dump("\n");
dump (_dd_pfx + _dd_currentIndent + str);
_dd_currentIndent += _dd_singleIndent;
_dd_lastDumpWasOpen = true;
} else if (str[0] == "}") {
if (--_dd_currentDepth >= _dd_disableDepth)
return;
_dd_disableDepth = Number.MAX_VALUE;
var sufx = (new Date() - _dd_timeStack.pop()) / 1000 + " sec";
_dd_currentIndent =
_dd_currentIndent.substr (0, _dd_currentIndent.length -
_dd_indentLength);
if (_dd_lastDumpWasOpen)
dumpln (str + " " + sufx);
else
dumpln (_dd_pfx + _dd_currentIndent + str + " " + sufx);
_dd_lastDumpWasOpen = false;
} else {
if (_dd_currentDepth >= _dd_disableDepth)
return;
if (_dd_lastDumpWasOpen)
dump ("\n");
dumpln (_dd_pfx + _dd_currentIndent + str);
_dd_lastDumpWasOpen = false;
}
}
} else {
dd = function (){};
}
var jsenv = new Object();
jsenv.HAS_SECURITYMANAGER = ((typeof netscape == "object") &&
(typeof netscape.security == "object"));
jsenv.HAS_XPCOM = ((typeof Components == "object") &&
(typeof Components.classes == "object"));
jsenv.HAS_JAVA = (typeof java == "object");
jsenv.HAS_RHINO = (typeof defineClass == "function");
jsenv.HAS_DOCUMENT = (typeof document == "object");
/* Dumps an object in tree format, recurse specifiec the the number of objects
* to recurse, compress is a boolean that can uncompress (true) the output
* format, and level is the number of levels to intitialy indent (only useful
* internally.) A sample dumpObjectTree (o, 1) is shown below.
*
* + parent (object)
* + users (object)
* | + jsbot (object)
* | + mrjs (object)
* | + nakkezzzz (object)
* | *
* + bans (object)
* | *
* + topic (string) 'ircclient.js:59: nothing is not defined'
* + getUsersLength (function) 9 lines
* *
*/
function dumpObjectTree (o, recurse, compress, level)
{
var s = "";
var pfx = "";
if (typeof recurse == "undefined")
recurse = 0;
if (typeof level == "undefined")
level = 0;
if (typeof compress == "undefined")
compress = true;
for (var i = 0; i < level; i++)
pfx += (compress) ? "| " : "| ";
var tee = (compress) ? "+ " : "+- ";
for (i in o)
{
var t;
try
{
t = typeof o[i];
switch (t)
{
case "function":
var sfunc = String(o[i]).split("\n");
if (sfunc[2] == " [native code]")
sfunc = "[native code]";
else
sfunc = sfunc.length + " lines";
s += pfx + tee + i + " (function) " + sfunc + "\n";
break;
case "object":
s += pfx + tee + i + " (object) " + o[i] + "\n";
if (!compress)
s += pfx + "|\n";
if ((i != "parent") && (recurse))
s += dumpObjectTree (o[i], recurse - 1,
compress, level + 1);
break;
case "string":
if (o[i].length > 200)
s += pfx + tee + i + " (" + t + ") " +
o[i].length + " chars\n";
else
s += pfx + tee + i + " (" + t + ") '" + o[i] + "'\n";
break;
default:
s += pfx + tee + i + " (" + t + ") " + o[i] + "\n";
}
}
catch (ex)
{
s += pfx + tee + i + " (exception) " + ex + "\n";
}
if (!compress)
s += pfx + "|\n";
}
s += pfx + "*\n";
return s;
}
function safeHTML(str)
{
function replaceChars(ch)
{
switch (ch)
{
case "<":
return "<";
case ">":
return ">";
case "&":
return "&";
}
return "?";
};
return String(str).replace(/[<>&]/g, replaceChars);
}
function alert(msg, parent, title)
{
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
var nsIPromptService = Components.interfaces.nsIPromptService;
var ps = Components.classes[PROMPT_CTRID].createInstance(nsIPromptService);
if (!parent)
parent = window;
if (!title)
title = MSG_ALERT;
ps.alert (parent, title, msg);
}
function confirm(msg, parent, title)
{
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
var nsIPromptService = Components.interfaces.nsIPromptService;
var ps = Components.classes[PROMPT_CTRID].createInstance(nsIPromptService);
if (!parent)
parent = window;
if (!title)
title = MSG_CONFIRM;
return ps.confirm (parent, title, msg);
}
function prompt(msg, initial, parent, title)
{
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
var nsIPromptService = Components.interfaces.nsIPromptService;
var ps = Components.classes[PROMPT_CTRID].createInstance(nsIPromptService);
if (!parent)
parent = window;
if (!title)
title = MSG_PROMPT;
rv = { value: initial };
if (!ps.prompt (parent, title, msg, rv, null, {value: null}))
return null;
return rv.value
}
function getChildById (element, id)
{
var nl = element.getElementsByAttribute("id", id);
return nl.item(0);
}
function openTopWin (url)
{
var window = getWindowByType ("navigator:browser");
if (window)
{
var base = getBaseWindowFromWindow (window);
if (base.enabled)
{
window.focus();
window._content.location.href = url;
return window;
}
}
return openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
}
function getWindowByType (windowType)
{
const MEDIATOR_CONTRACTID =
"@mozilla.org/appshell/window-mediator;1";
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
var windowManager =
Components.classes[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
return windowManager.getMostRecentWindow(windowType);
}
function htmlVA (attribs, href, contents)
{
if (!attribs)
attribs = {"class": "venkman-link", target: "_content"};
else if (attribs["class"])
attribs["class"] += " venkman-link";
else
attribs["class"] = "venkman-link";
if (typeof contents == "undefined")
{
contents = htmlSpan();
insertHyphenatedWord (href, contents);
}
return htmlA (attribs, href, contents);
}
function insertHyphenatedWord (longWord, containerTag)
{
var wordParts = splitLongWord (longWord, MAX_WORD_LEN);
containerTag.appendChild (htmlWBR());
for (var i = 0; i < wordParts.length; ++i)
{
containerTag.appendChild (document.createTextNode (wordParts[i]));
if (i != wordParts.length)
containerTag.appendChild (htmlWBR());
}
}
function insertLink (matchText, containerTag)
{
var href;
var linkText;
var trailing;
ary = matchText.match(/([.,]+)$/);
if (ary)
{
linkText = RegExp.leftContext;
trailing = ary[1];
}
else
{
linkText = matchText;
}
var ary = linkText.match (/^(\w[\w-]+):/);
if (ary)
{
if (!("schemes" in utils))
{
var pfx = "@mozilla.org/network/protocol;1?name=";
var len = pfx.length
utils.schemes = new Object();
for (var c in Components.classes)
{
if (c.indexOf(pfx) == 0)
utils.schemes[c.substr(len)] = true;
}
}
if (!(ary[1] in utils.schemes))
{
insertHyphenatedWord(matchText, containerTag);
return;
}
href = linkText;
}
else
{
href = "http://" + linkText;
}
var anchor = htmlVA (null, href, "");
insertHyphenatedWord (linkText, anchor);
containerTag.appendChild (anchor);
if (trailing)
insertHyphenatedWord (trailing, containerTag);
}
function insertQuote (matchText, containerTag, msgtype)
{
if (msgtype[0] == "#")
{
containerTag.appendChild(document.createTextNode(matchText));
return;
}
if (matchText == "``")
containerTag.appendChild(document.createTextNode("\u201c"));
else
containerTag.appendChild(document.createTextNode("\u201d"));
}
/* length should be an even number >= 6 */
function abbreviateWord (str, length)
{
if (str.length <= length || length < 6)
return str;
var left = str.substr (0, (length / 2) - 1);
var right = str.substr (str.length - (length / 2) + 1);
return left + "..." + right;
}
function toBool (val)
{
switch (typeof val)
{
case "boolean":
return val;
case "number":
return val != 0;
default:
val = String(val);
/* fall through */
case "string":
return (val.search(/true|on|yes|1/i) != -1);
}
return null;
}
/* some of the drag and drop code has an annoying appetite for exceptions. any
* exception raised during a dnd operation causes the operation to fail silently.
* passing the function through one of these adapters lets you use "return
* false on planned failure" symantics, and dumps any exceptions caught
* to the console. */
function Prophylactic (parentObj, fun)
{
function adapter ()
{
var ex;
var rv = false;
try
{
rv = fun.apply (parentObj, arguments);
}
catch (ex)
{
dd ("Prophylactic caught an exception:\n" +
dumpObjectTree(ex));
}
if (!rv)
throw "goodger";
return rv;
};
return adapter;
}
function argumentsAsArray (args, start)
{
if (typeof start == "undefined")
start = 0;
if (start >= args.length)
return null;
var rv = new Array();
for (var i = start; i < args.length; ++i)
rv.push(args[i]);
return rv;
}
function splitLongWord (str, pos)
{
if (str.length <= pos)
return [str];
var ary = new Array();
var right = str;
while (right.length > pos)
{
/* search for a nice place to break the word, fuzzfactor of +/-5,
* centered around |pos| */
var splitPos =
right.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
ary.push(right.substr (0, splitPos));
right = right.substr (splitPos);
}
ary.push (right);
return ary;
}
function wrapText (str, width)
{
var rv = "";
while (str.length > width)
{
rv += str.substr(0, width) + "\n";
str = str.substr(width);
}
return rv + str;
}
function wordCap (str)
{
if (!str)
return str;
return str[0].toUpperCase() + str.substr(1);
}
/*
* Clones an existing object (Only the enumerable properties
* of course.) use as a function..
* var c = Clone (obj);
* or a constructor...
* var c = new Clone (obj);
*/
function Clone (obj)
{
var robj = new Object();
for (var p in obj)
robj[p] = obj[p];
return robj;
}
function getXULWindowFromWindow (win)
{
var rv;
//dd ("getXULWindowFromWindow: before: getInterface is " + win.getInterface);
try
{
var requestor = win.QueryInterface(nsIInterfaceRequestor);
var nav = requestor.getInterface(nsIWebNavigation);
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
var owner = dsti.treeOwner;
requestor = owner.QueryInterface(nsIInterfaceRequestor);
rv = requestor.getInterface(nsIXULWindow);
}
catch (ex)
{
rv = null;
//dd ("not a nsIXULWindow: " + formatException(ex));
/* ignore no-interface exception */
}
//dd ("getXULWindowFromWindow: after: getInterface is " + win.getInterface);
return rv;
}
function getBaseWindowFromWindow (win)
{
var rv;
//dd ("getBaseWindowFromWindow: before: getInterface is " + win.getInterface);
try
{
var requestor = win.QueryInterface(nsIInterfaceRequestor);
var nav = requestor.getInterface(nsIWebNavigation);
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
var owner = dsti.treeOwner;
requestor = owner.QueryInterface(nsIInterfaceRequestor);
rv = requestor.getInterface(nsIBaseWindow);
}
catch (ex)
{
rv = null;
//dd ("not a nsIXULWindow: " + formatException(ex));
/* ignore no-interface exception */
}
//dd ("getBaseWindowFromWindow: after: getInterface is " + win.getInterface);
return rv;
}
function getSpecialDirectory(name)
{
if (!("directoryService" in utils))
{
const DS_CTR = "@mozilla.org/file/directory_service;1";
const nsIProperties = Components.interfaces.nsIProperties;
utils.directoryService =
Components.classes[DS_CTR].getService(nsIProperties);
}
return utils.directoryService.get(name, Components.interfaces.nsIFile);
}
function getPathFromURL (url)
{
var ary = url.match(/^(.*\/)([^\/?#]+)(\?|#|$)/);
if (ary)
return ary[1];
return url;
}
function getFileFromPath (path)
{
var ary = path.match(/\/([^\/?#;]+)(\?|#|$|;)/);
if (ary)
return ary[1];
return path;
}
function getURLSpecFromFile (file)
{
if (!file)
return null;
const IOS_CTRID = "@mozilla.org/network/io-service;1";
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const nsIIOService = Components.interfaces.nsIIOService;
const nsILocalFile = Components.interfaces.nsILocalFile;
if (typeof file == "string")
{
var fileObj =
Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
fileObj.initWithPath(file);
file = fileObj;
}
var service = Components.classes[IOS_CTRID].getService(nsIIOService);
/* In sept 2002, bug 166792 moved this method to the nsIFileProtocolHandler
* interface, but we need to support older versions too. */
if ("getURLSpecFromFile" in service)
return service.getURLSpecFromFile(file);
var nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler;
var fileHandler = service.getProtocolHandler("file");
fileHandler = fileHandler.QueryInterface(nsIFileProtocolHandler);
return fileHandler.getURLSpecFromFile(file);
}
function getCommonPfx (list)
{
var pfx = list[0];
var l = list.length;
for (var i = 1; i < l; i++)
{
for (var c = 0; c < pfx.length; c++)
if (pfx[c] != list[i][c])
pfx = pfx.substr (0, c);
}
return pfx;
}
function renameProperty (obj, oldname, newname)
{
if (oldname == newname)
return;
obj[newname] = obj[oldname];
delete obj[oldname];
}
function newObject(contractID, iface)
{
if (!jsenv.HAS_XPCOM)
return null;
var obj = Components.classes[contractID].createInstance();
var rv;
switch (typeof iface)
{
case "string":
rv = obj.QueryInterface(Components.interfaces[iface]);
break;
case "object":
rv = obj.QueryInterface[iface];
break;
default:
rv = null;
break;
}
return rv;
}
function keys (o)
{
var rv = new Array();
for (var p in o)
rv.push(p);
return rv;
}
function parseSections (str, sections)
{
var rv = new Object();
var currentSection;
for (var s in sections)
{
if (!currentSection)
currentSection = s;
if (sections[s])
{
var i = str.search(sections[s]);
if (i != -1)
{
rv[currentSection] = str.substr(0, i);
currentSection = 0;
str = RegExp.rightContext;
str = str.replace(/^(\n|\r|\r\n)/, "");
}
}
else
{
rv[currentSection] = str;
str = "";
break;
}
}
return rv;
}
function replaceStrings (str, obj)
{
if (!str)
return str;
for (var p in obj)
str = str.replace(RegExp(p, "g"), obj[p]);
return str;
}
function stringTrim (s)
{
if (!s)
return "";
s = s.replace (/^\s+/, "");
return s.replace (/\s+$/, "");
}
function formatDateOffset (seconds, format)
{
seconds = Math.floor(seconds);
var minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
var hours = Math.floor(minutes / 60);
minutes = minutes % 60;
var days = Math.floor(hours / 24);
hours = hours % 24;
if (!format)
{
var ary = new Array();
if (days > 0)
ary.push (days + " days");
if (hours > 0)
ary.push (hours + " hours");
if (minutes > 0)
ary.push (minutes + " minutes");
if (seconds > 0)
ary.push (seconds + " seconds");
format = ary.join(", ");
}
else
{
format = format.replace ("%d", days);
format = format.replace ("%h", hours);
format = format.replace ("%m", minutes);
format = format.replace ("%s", seconds);
}
return format;
}
function arrayHasElementAt(ary, i)
{
return typeof ary[i] != "undefined";
}
function arraySpeak (ary, single, plural)
{
var rv = "";
switch (ary.length)
{
case 0:
break;
case 1:
rv = ary[0];
if (single)
rv += " " + single;
break;
case 2:
rv = ary[0] + " and " + ary[1];
if (plural)
rv += " " + plural;
break;
default:
for (var i = 0; i < ary.length - 1; ++i)
rv += ary[i] + ", ";
rv += "and " + ary[ary.length - 1];
if (plural)
rv += " " + plural;
break;
}
return rv;
}
function arrayOrFlag (ary, i, flag)
{
if (i in ary)
ary[i] |= flag;
else
ary[i] = flag;
}
function arrayAndFlag (ary, i, flag)
{
if (i in ary)
ary[i] &= flag;
else
ary[i] = 0;
}
function arrayContains (ary, elem)
{
return (arrayIndexOf (ary, elem) != -1);
}
function arrayIndexOf (ary, elem, start)
{
if (!ary)
return -1;
var len = ary.length;
if (typeof start == "undefined")
start = 0;
for (var i = start; i < len; ++i)
{
if (ary[i] == elem)
return i;
}
return -1;
}
function arrayInsertAt (ary, i, o)
{
ary.splice (i, 0, o);
}
function arrayRemoveAt (ary, i)
{
ary.splice (i, 1);
}
function getRandomElement (ary)
{
var i = Math.floor (Math.random() * ary.length)
if (i == ary.length) i = 0;
return ary[i];
}
function zeroPad (num, decimals)
{
var rv = String(num);
var len = rv.length;
for (var i = 0; i < decimals - len; ++i)
rv = "0" + rv;
return rv;
}
function leftPadString (str, num, ch)
{
var rv = "";
var len = rv.length;
for (var i = len; i < num; ++i)
rv += ch;
return rv + str;
}
function roundTo (num, prec)
{
return Math.round(num * Math.pow (10, prec)) / Math.pow (10, prec);
}
function randomRange (min, max)
{
if (typeof min == "undefined")
min = 0;
if (typeof max == "undefined")
max = 1;
var rv = (Math.floor(Math.round((Math.random() * (max - min)) + min )));
return rv;
}
function getStackTrace ()
{
if (!jsenv.HAS_XPCOM)
return "No stack trace available.";
var frame = Components.stack.caller;
var str = "";
while (frame)
{
var name = frame.name ? frame.name : "[anonymous]";
str += "\n" + name + "@" + frame.lineNumber;
frame = frame.caller;
}
return str;
}
function getInterfaces (cls)
{
if (!jsenv.HAS_XPCOM)
return null;
var rv = new Object();
var e;
for (var i in Components.interfaces)
{
try
{
var ifc = Components.interfaces[i];
cls.QueryInterface(ifc);
rv[i] = ifc;
}
catch (e)
{
/* nada */
}
}
return rv;
}
PK
Xz/ content/venkman/venkman-dev.jsUT PA?!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
function initDev()
{
var cmdary =
[["dumpcontexts", cmdDumpContexts, CMD_CONSOLE | CMD_NO_HELP],
["dumpfilters", cmdDumpFilters, CMD_CONSOLE | CMD_NO_HELP],
["dumpprofile", cmdDumpProfile, CMD_CONSOLE | CMD_NO_HELP],
["dumptree", cmdDumpTree, CMD_CONSOLE | CMD_NO_HELP],
["dumpscripts", cmdDumpScripts, CMD_CONSOLE | CMD_NO_HELP],
["reloadui", cmdReloadUI, CMD_CONSOLE | CMD_NO_HELP],
["sync-debug", cmdSyncDebug, CMD_CONSOLE | CMD_NO_HELP],
["test", cmdTest, CMD_CONSOLE | CMD_NO_HELP],
["testargs", cmdTestArgs, CMD_CONSOLE | CMD_NO_HELP],
["testargs1", cmdTestArgs, CMD_CONSOLE | CMD_NO_HELP],
["testfilters", cmdTestFilters, CMD_CONSOLE | CMD_NO_HELP],
["treetest", cmdTreeTest, CMD_CONSOLE | CMD_NO_HELP],
["multialias", "help pref; help props", CMD_CONSOLE | CMD_NO_HELP]];
console.commandManager.defineCommands (cmdary);
if (!("devState" in console.pluginState))
{
console.prefManager.addPref ("dbgContexts", false);
console.prefManager.addPref ("dbgDispatch", false);
console.prefManager.addPref ("dbgRealize", false);
}
console.pluginState.devState = true;
dispatch ("sync-debug");
return "Venkman development functions loaded OK.";
}
function cmdDumpContexts()
{
console.contexts = new Array();
var i = 0;
var enumer = {
enumerateContext: function _ec (context) {
if (!context.isValid)
{
dd("enumerate got invalid context");
}
else
{
var v = context.globalObject.getWrappedValue();
var title = "";
if (v instanceof Object &&
"document" in v)
{
title = v.document.title;
}
dd ("enumerateContext: Index " + i +
", Version " + context.version +
", Options " + context.options +
", Private " + context.privateData +
", Tag " + context.tag +
", Title " + title +
", Scripts Enabled " +
context.scriptsEnabled);
}
console.contexts[i++] = context;
}
};
console.jsds.enumerateContexts(enumer);
return true;
}
function cmdDumpFilters()
{
console.filters = new Array();
var i = 0;
var enumer = {
enumerateFilter: function enum_f (filter) {
dd (i + ": " + filter.globalObject +
" '" + filter.urlPattern + "' " + filter.flags);
console.filters[i++] = filter;
}
};
console.jsds.enumerateFilters (enumer);
}
function cmdDumpProfile(e)
{
var list = console.getProfileSummary();
for (var i = 0; i < list.length; ++i)
dd(list[i].str);
}
function cmdDumpTree(e)
{
if (!e.depth)
e.depth = 0;
dd(e.tree + ":\n" + tov_formatBranch (eval(e.tree), "", e.depth));
}
function cmdDumpScripts(e)
{
var nl;
if ("frames" in console)
{
frame = getCurrentFrame();
var targetWindow = frame.executionContext.globalObject.getWrappedValue();
nl = targetWindow.document.getElementsByTagName("script");
}
else
{
nl = document.getElementsByTagName("script");
}
for (var i = 0; i < nl.length; ++i)
dd("src: " + nl.item(i).getAttribute ("src"));
}
function cmdReloadUI()
{
if ("frames" in console)
{
display (MSG_NOTE_NOSTACK, MT_ERROR);
return;
}
var bs = Components.classes["@mozilla.org/intl/stringbundle;1"];
bs = bs.createInstance(Components.interfaces.nsIStringBundleService);
bs.flushBundles();
window.location.href = window.location.href;
}
function cmdSyncDebug()
{
if (eval(console.prefs["dbgContexts"]))
console.dbgContexts = true;
else
delete console.dbgContexts;
if (eval(console.prefs["dbgDispatch"]))
console.dbgDispatch = true;
else
delete console.dbgDispatch;
if (eval(console.prefs["dbgRealize"]))
console.dbgRealize = true;
else
delete console.dbgRealize;
}
function cmdTest(e)
{
function f()
{
g();
h();
};
function g() {};
function h() {};
dd("start {");
for (var i = 0; i < 50000; ++i)
f();
dd("} stop");
}
function cmdTestArgs (e)
{
display (dumpObjectTree(e));
}
function cmdTestFilters ()
{
var filter1 = {
globalObject: null,
flags: jsdIFilter.FLAG_ENABLED,
urlPattern: "1",
startLine: 0,
endLine: 0
};
var filter2 = {
globalObject: null,
flags: jsdIFilter.FLAG_ENABLED,
urlPattern: "*2",
startLine: 0,
endLine: 0
};
var filter3 = {
globalObject: null,
flags: jsdIFilter.FLAG_ENABLED,
urlPattern: "3*",
startLine: 0,
endLine: 0
};
var filter4 = {
globalObject: null,
flags: jsdIFilter.FLAG_ENABLED,
urlPattern: "*4*",
startLine: 0,
endLine: 0
};
dd ("append f3 into an empty list.");
console.jsds.appendFilter (filter3);
console.jsds.GC();
dd("insert f1 at the top");
console.jsds.insertFilter (filter1, null);
console.jsds.GC();
dd("insert f2 after f1");
console.jsds.insertFilter (filter2, filter1);
console.jsds.GC();
dd("swap f4 in, f3 out");
console.jsds.swapFilters (filter3, filter4);
console.jsds.GC();
dd("append f3");
console.jsds.appendFilter (filter3);
console.jsds.GC();
dd("swap f4 and f3");
console.jsds.swapFilters (filter3, filter4);
console.jsds.GC();
dumpFilters();
}
function cmdTreeTest()
{
var w = openDialog("chrome://venkman/content/tests/tree.xul", "", "");
}
initDev();
PK
,+XQ Q # content/venkman/venkman-handlers.jsUT 6=!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
function initHandlers()
{
function wwObserve (subject, topic, data)
{
//dd ("wwObserver::Observe " + subject + ", " + topic);
if (topic == "domwindowopened")
console.onWindowOpen (subject);
else
console.onWindowClose (subject);
};
console.wwObserver = {observe: wwObserve};
console.windowWatcher.registerNotification (console.wwObserver);
console.hookedWindows = new Array();
var enumerator = console.windowWatcher.getWindowEnumerator();
while (enumerator.hasMoreElements())
{
var win = enumerator.getNext();
if (!isWindowFiltered(win))
{
console.onWindowOpen(win);
console.onWindowLoad();
}
}
}
function destroyHandlers()
{
console.windowWatcher.unregisterNotification (console.wwObserver);
while (console.hookedWindows.length)
{
var win = console.hookedWindows.pop();
win.removeEventListener ("load", console.onWindowLoad, false);
win.removeEventListener ("unload", console.onWindowUnload, false);
}
}
function isWindowFiltered (window)
{
var href = window.location.href;
var rv = ((href.search (/^chrome:\/\/venkman\//) != -1 &&
href.search (/test/) == -1) ||
(console.prefs["enableChromeFilter"] &&
href.search (/navigator.xul($|\?)/) == -1));
//dd ("isWindowFiltered " + window.location.href + ", returning " + rv);
return rv;
}
console.onWindowOpen =
function con_winopen (win)
{
if ("ChromeWindow" in win && win instanceof win.ChromeWindow &&
(win.location.href == "about:blank" || win.location.href == ""))
{
setTimeout (con_winopen, 0, win);
return;
}
if (isWindowFiltered(win))
return;
//dd ("window opened: " + win + " ``" + win.location + "''");
console.hookedWindows.push(win);
dispatch ("hook-window-opened", {window: win});
win.addEventListener ("load", console.onWindowLoad, false);
win.addEventListener ("unload", console.onWindowUnload, false);
//console.scriptsView.freeze();
}
console.onWindowLoad =
function con_winload (e)
{
dispatch ("hook-window-loaded", {event: e});
}
console.onWindowUnload =
function con_winunload (e)
{
dispatch ("hook-window-unloaded", {event: e});
// dd (dumpObjectTree(e));
}
console.onWindowClose =
function con_winclose (win)
{
if (isWindowFiltered(win))
return;
//dd ("window closed: " + win + " ``" + win.location + "''");
var i = arrayIndexOf(console.hookedWindows, win);
ASSERT (i != console.hookedWindows.length,
"WARNING: Can't find hook window for closed window " + i + ".");
arrayRemoveAt(console.hookedWindows, i);
dispatch ("hook-window-closed", {window: win});
//console.scriptsView.freeze();
}
console.onLoad =
function con_load (e)
{
var ex;
dd ("Application venkman, 'JavaScript Debugger' loaded.");
try
{
init();
}
catch (ex)
{
if ("bundleList" in console)
window.alert (getMsg (MSN_ERR_STARTUP, formatException(ex)));
else
window.alert (formatException(ex));
console.startupException = ex;
}
}
console.onClose =
function con_onclose (e)
{
dd ("onclose");
if (typeof console != "object" || "startupException" in console)
return true;
dd ("onclose: dispatching");
return dispatch ("hook-venkman-query-exit");
}
console.onUnload =
function con_unload (e)
{
dd ("Application venkman, 'JavaScript Debugger' unloading.");
if (typeof console != "object")
return;
dispatch ("hook-venkman-exit");
destroy();
}
console.onMouseOver =
function con_mouseover (e)
{
var element = e.originalTarget;
if (!("_lastElement" in console))
console._lastElement = null;
while (element)
{
if (element == console._lastElement)
return;
if ("getAttribute" in element)
{
var status = element.getAttribute ("venkmanstatustext");
if (status)
{
console.status = status;
console._lastElement = element;
return;
}
}
if ("localName" in element && element.localName == "floatingview")
{
console.status = console.viewManager.computeLocation (element);
console._lastElement = element;
return;
}
element = element.parentNode;
}
}
window.onresize =
function ()
{
dispatch ("hook-window-resized", { window: window });
// console.scrollDown();
}
PK
k06Y ! content/venkman/venkman-static.jsUT JQ@!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
const __vnk_version = "0.9.81";
const __vnk_requiredLocale = "0.9.81";
var __vnk_versionSuffix = "";
const __vnk_counter_url =
"http://www.hacksrus.com/~ginda/venkman/launch-counter/next-sequence.cgi"
/* dd is declared first in venkman-utils.js */
var warn;
var ASSERT;
if (DEBUG)
{
_dd_pfx = "vnk: ";
warn = function (msg) { dumpln ("** WARNING " + msg + " **"); }
ASSERT = function (expr, msg) {
if (!expr) {
dump ("** ASSERTION FAILED: " + msg + " **\n" +
getStackTrace() + "\n");
return false;
} else {
return true;
}
}
}
else
dd = warn = ASSERT = function (){};
const MAX_WORD_LEN = 20; /* number of characters to display before forcing a
* potential word break point (in the console.) */
const LINE_BREAKABLE = 0x01;
const LINE_BREAK = 0x02;
const LINE_FBREAK = 0x04;
var console = new Object();
console.initialized = false;
/* |this|less functions */
function setStopState(state)
{
var tb = console.ui["stop-button"];
if (state)
{
console.jsds.interruptHook = console.executionHook;
tb.setAttribute("willStop", "true");
}
else
{
console.jsds.interruptHook = null;
tb.removeAttribute("willStop");
}
}
function setProfileState(state)
{
var tb = console.ui["profile-button"];
if (state)
{
console.profiler.enabled = true;
tb.setAttribute("profile", "true");
}
else
{
console.profiler.enabled = false;
tb.removeAttribute("profile");
}
}
function enableDebugCommands()
{
var cmds = console.commandManager.list ("", CMD_NEED_STACK);
for (var i in cmds)
cmds[i].enabled = true;
cmds = console.commandManager.list ("", CMD_NO_STACK);
for (i in cmds)
cmds[i].enabled = false;
}
function disableDebugCommands()
{
var cmds = console.commandManager.list ("", CMD_NEED_STACK);
for (var i in cmds)
cmds[i].enabled = false;
cmds = console.commandManager.list ("", CMD_NO_STACK);
for (i in cmds)
cmds[i].enabled = true;
}
function isURLVenkman (url)
{
return (url.search (/^chrome:\/\/venkman/) == 0 &&
url.search (/test/) == -1);
}
function isURLFiltered (url)
{
return (!url ||
(console.prefs["enableChromeFilter"] &&
(url.search(/^chrome:/) == 0 ||
("componentPath" in console &&
url.indexOf(console.componentPath) == 0))) ||
(url.search (/^chrome:\/\/venkman/) == 0 &&
url.search (/test/) == -1));
}
function toUnicode (msg, charset)
{
try
{
console.ucConverter.charset = charset;
return console.ucConverter.ConvertToUnicode(msg);
}
catch (ex)
{
dd ("caught " + ex + " converting to unicode");
return msg;
}
}
function fromUnicode (msg, charset)
{
try
{
console.ucConverter.charset = charset;
return console.ucConverter.ConvertFromUnicode(msg);
}
catch (ex)
{
dd ("caught " + ex + " converting from unicode");
return msg;
}
}
function displayUsageError (e, details)
{
if (!("isInteractive" in e) || !e.isInteractive)
{
var caller = Components.stack.caller.caller;
if (caller.name == "dispatch")
caller = caller.caller;
var error = new Error (details);
error.fileName = caller.filename;
error.lineNumber = caller.lineNumber;
error.name = caller.name;
display (formatException(error), MT_ERROR);
}
else
{
display (details, MT_ERROR);
}
display (getMsg(MSN_FMT_USAGE, [e.command.name, e.command.usage]), MT_USAGE);
}
function dispatch (text, e, flags)
{
if (!e)
e = new Object();
if (!("inputData" in e))
e.inputData = "";
/* split command from arguments */
var ary = text.match (/(\S+) ?(.*)/);
e.commandText = ary[1];
e.inputData = ary[2] ? stringTrim(ary[2]) : "";
/* list matching commands */
ary = console.commandManager.list (e.commandText, flags);
var rv = null;
var i;
switch (ary.length)
{
case 0:
/* no match, try again */
display (getMsg(MSN_NO_CMDMATCH, e.commandText), MT_ERROR);
break;
case 1:
/* one match, good for you */
var ex;
try
{
rv = dispatchCommand(ary[0], e, flags);
}
catch (ex)
{
display (getMsg(MSN_ERR_INTERNAL_DISPATCH, ary[0].name),
MT_ERROR);
display (formatException(ex), MT_ERROR);
dd (formatException(ex), MT_ERROR);
if (typeof ex == "object" && "stack" in ex)
dd (ex.stack);
}
break;
default:
/* more than one match, show the list */
var str = "";
for (i in ary)
str += (str) ? MSG_COMMASP + ary[i].name : ary[i].name;
display (getMsg (MSN_ERR_AMBIGCOMMAND,
[e.commandText, ary.length, str]), MT_ERROR);
}
return rv;
}
function dispatchCommand (command, e, flags)
{
function callHooks (command, isBefore)
{
var names, hooks;
if (isBefore)
hooks = command.beforeHooks;
else
hooks = command.afterHooks;
for (var h in hooks)
{
if ("dbgDispatch" in console && console.dbgDispatch)
{
dd ("calling " + (isBefore ? "before" : "after") +
" hook " + h);
}
try
{
hooks[h](e);
}
catch (ex)
{
if (e.command.name != "hook-session-display")
{
display (getMsg(MSN_ERR_INTERNAL_HOOK, h), MT_ERROR);
display (formatException(ex), MT_ERROR);
}
else
{
dd (getMsg(MSN_ERR_INTERNAL_HOOK, h));
}
dd ("Caught exception calling " +
(isBefore ? "before" : "after") + " hook " + h);
dd (formatException(ex));
if (typeof ex == "object" && "stack" in ex)
dd (ex.stack);
else
dd (getStackTrace());
}
}
};
e.command = command;
if ((e.command.flags & CMD_NEED_STACK) &&
(!("frames" in console)))
{
/* doc, it hurts when I do /this/... */
display (MSG_ERR_NO_STACK, MT_ERROR);
return null;
}
if (!e.command.enabled)
{
/* disabled command */
display (getMsg(MSN_ERR_DISABLED, e.command.name),
MT_ERROR);
return null;
}
var h, i;
if ("beforeHooks" in e.command)
callHooks (e.command, true);
if (typeof e.command.func == "function")
{
/* dispatch a real function */
if (e.command.usage)
console.commandManager.parseArguments (e);
if ("parseError" in e)
{
displayUsageError (e, e.parseError);
}
else
{
if ("dbgDispatch" in console && console.dbgDispatch)
{
var str = "";
for (i = 0; i < e.command.argNames.length; ++i)
{
var name = e.command.argNames[i];
if (name in e)
str += " " + name + ": " + e[name];
else if (name != ":")
str += " ?" + name;
}
dd (">>> " + e.command.name + str + " <<<");
e.returnValue = e.command.func(e);
/* set console.lastEvent *after* dispatching, so the dispatched
* function actually get's a chance to see the last event. */
console.lastEvent = e;
}
else
{
e.returnValue = e.command.func(e);
}
}
}
else if (typeof e.command.func == "string")
{
/* dispatch an alias (semicolon delimited list of subcommands) */
var commandList = e.command.func.split(";");
for (i = 0; i < commandList.length; ++i)
{
var newEvent = Clone (e);
delete newEvent.command;
commandList[i] = stringTrim(commandList[i]);
dispatch (commandList[i], newEvent, flags);
}
}
else
{
display (getMsg(MSN_ERR_NOTIMPLEMENTED, e.command.name),
MT_ERROR);
return null;
}
if ("afterHooks" in e.command)
callHooks (e.command, false);
return ("returnValue" in e) ? e.returnValue : null;
}
function feedback(e, message, msgtype)
{
if ("isInteractive" in e && e.isInteractive)
display (message, msgtype);
}
function display(message, msgtype)
{
if (typeof message == "undefined")
throw new RequiredParam ("message");
if (typeof message != "string" &&
!(message instanceof Components.interfaces.nsIDOMHTMLElement))
throw new InvalidParam ("message", message);
if ("capturedMsgs" in console)
console.capturedMsgs.push ([message, msgtype]);
dispatchCommand(console.coDisplayHook,
{ message: message, msgtype: msgtype });
}
function evalInDebuggerScope (script, rethrow)
{
try
{
return console.doEval (script);
}
catch (ex)
{
if (rethrow)
throw ex;
display (formatEvalException(ex), MT_ERROR);
return null;
}
}
function evalInTargetScope (script, rethrow)
{
if (!console.frames)
{
display (MSG_ERR_NO_STACK, MT_ERROR);
return null;
}
var rval = new Object();
if (!getCurrentFrame().eval (script, MSG_VAL_CONSOLE, 1, rval))
{
if (rethrow)
throw rval.value;
//dd ("exception: " + dumpObjectTree(rval.value));
display (formatEvalException (rval.value), MT_ERROR);
return null;
}
return ("value" in rval) ? rval.value : null;
}
function formatException (ex)
{
if (ex instanceof BadMojo)
return getMsg (MSN_FMT_BADMOJO,
[ex.errno, ex.message, ex.fileName, ex.lineNumber,
ex.functionName]);
if (ex instanceof Error)
return getMsg (MSN_FMT_JSEXCEPTION, [ex.name, ex.message, ex.fileName,
ex.lineNumber]);
return String(ex);
}
function formatEvalException (ex)
{
if (ex instanceof BadMojo || ex instanceof Error)
return formatException (ex);
else if (ex instanceof jsdIValue)
ex = ex.stringValue;
return getMsg (MSN_EVAL_THREW, String(ex));
}
function init()
{
dd ("init {");
var i;
const WW_CTRID = "@mozilla.org/embedcomp/window-watcher;1";
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
console.windowWatcher =
Components.classes[WW_CTRID].getService(nsIWindowWatcher);
const UC_CTRID = "@mozilla.org/intl/scriptableunicodeconverter";
const nsIUnicodeConverter =
Components.interfaces.nsIScriptableUnicodeConverter;
console.ucConverter =
Components.classes[UC_CTRID].getService(nsIUnicodeConverter);
console.baseWindow = getBaseWindowFromWindow(window);
console.mainWindow = window;
console.dnd = nsDragAndDrop;
console.currentEvalObject = console;
console.files = new Object();
console.pluginState = new Object();
console._statusStack = new Array();
console._lastStackDepth = -1;
initMsgs();
initPrefs();
initCommands();
initJSDURL();
/* Some commonly used commands, cached now, for use with dispatchCommand. */
var cm = console.commandManager;
console.coManagerCreated = cm.commands["hook-script-manager-created"];
console.coManagerDestroyed = cm.commands["hook-script-manager-destroyed"];
console.coInstanceCreated = cm.commands["hook-script-instance-created"];
console.coInstanceSealed = cm.commands["hook-script-instance-sealed"];
console.coInstanceDestroyed = cm.commands["hook-script-instance-destroyed"];
console.coDisplayHook = cm.commands["hook-session-display"];
console.coFindScript = cm.commands["find-script"];
console.commandManager.addHooks (console.hooks);
initMenus();
console.capturedMsgs = new Array();
var ary = console.prefs["initialScripts"].split(/\s*;\s*/);
for (i = 0; i < ary.length; ++i)
{
var url = stringTrim(ary[i]);
if (url)
dispatch ("loadd", { url: ary[i] });
}
dispatch ("hook-venkman-started");
initViews();
initRecords();
initHandlers(); // handlers may notice windows, which need views and records
createMainMenu(document);
createMainToolbar(document);
console.ui = {
"status-text": document.getElementById ("status-text"),
"profile-button": document.getElementById ("maintoolbar:profile-tb"),
"stop-button": document.getElementById ("maintoolbar:stop")
};
disableDebugCommands();
initDebugger();
initProfiler();
// read prefs that have not been explicitly created, such as the layout prefs
console.prefManager.readPrefs();
fetchLaunchCount();
console.sourceText = new HelpText();
console.pushStatus(MSG_STATUS_DEFAULT);
dispatch ("restore-layout default");
var startupMsgs = console.capturedMsgs;
delete console.capturedMsgs;
dispatch ("version");
for (i = 0; i < startupMsgs.length; ++i)
display (startupMsgs[i][0], startupMsgs[i][1]);
display (getMsg(MSN_TIP1_HELP,
console.prefs["sessionView.requireSlash"] ? "/" : ""));
display (MSG_TIP2_HELP);
if (console.prefs["sessionView.requireSlash"])
display (MSG_TIP3_HELP);
if (console.prefs["rememberPrettyprint"])
dispatch ("pprint", { toggle: console.prefs["prettyprint"] });
else
dispatch ("pprint", { toggle: false });
if (MSG_LOCALE_VERSION != __vnk_requiredLocale)
{
display (getMsg(MSN_BAD_LOCALE,
[__vnk_requiredLocale, MSG_LOCALE_VERSION]),
MT_WARN);
}
console.initialized = true;
if (console.prefs["saveSettingsOnExit"])
{
dispatch ("restore-settings",
{settingsFile: console.prefs["settingsFile"]});
}
dispatch ("hook-venkman-started");
dd ("}");
}
function destroy ()
{
if (console.prefs["saveLayoutOnExit"])
dispatch ("save-layout default");
if (console.prefs["saveSettingsOnExit"])
{
dispatch ("save-settings",
{settingsFile: console.prefs["settingsFile"]});
}
delete console.currentEvalObject;
delete console.jsdConsole;
destroyViews();
destroyHandlers();
destroyPrefs();
detachDebugger();
}
function paintHack (i)
{
/* when stopping at a timeout, we don't repaint correctly.
* by jamming a character into this hidden text box, we can force
* a repaint.
*/
for (var w in console.viewManager.windows)
{
var window = console.viewManager.windows[w];
var textbox = window.document.getElementById("paint-hack");
if (textbox)
{
textbox.value = " ";
textbox.value = "";
}
}
if (!i)
i = 0;
if (i < 4)
setTimeout (paintHack, 250, i + 1);
}
function fetchLaunchCount()
{
++console.prefs["startupCount"];
if (!toBool(console.prefs["permitStartupHit"]))
return;
function onLoad ()
{
var ary = String(r.responseText).match(/(\d+)/);
if (ary)
{
display (getMsg(MSN_LAUNCH_COUNT,
[console.prefs["startupCount"], ary[1]]));
}
};
var r = new XMLHttpRequest();
r.onload = onLoad;
r.open ("GET",
__vnk_counter_url + "?local=" + console.prefs["startupCount"] +
"&version=" + __vnk_version);
r.send (null);
}
console.__defineGetter__ ("userAgent", con_ua);
function con_ua ()
{
var ary = navigator.userAgent.match (/;\s*([^;\s]+\s*)\).*\/(\d+)/);
if (ary)
{
return ("Venkman " + __vnk_version + __vnk_versionSuffix +
" [Mozilla " + ary[1] + "/" + ary[2] + "]");
}
return ("Venkman " + __vnk_version + __vnk_versionSuffix + " [" +
navigator.userAgent + "]");
}
console.hooks = new Object();
console.hooks["hook-script-instance-sealed"] =
function hookScriptSealed (e)
{
if (!("componentPath" in console))
{
var ary = e.scriptInstance.url.match (/(.*)venkman-service\.js$/);
if (ary)
{
if (!console.prefs["enableChromeFilter"])
{
dispatch ("debug-instance-on",
{ scriptInstance: e.scriptInstance });
}
console.componentPath = ary[1];
}
}
for (var fbp in console.fbreaks)
{
if (console.fbreaks[fbp].enabled &&
e.scriptInstance.url.indexOf(console.fbreaks[fbp].url) != -1)
{
e.scriptInstance.setBreakpoint(console.fbreaks[fbp].lineNumber,
console.fbreaks[fbp]);
}
}
}
console.hooks["hook-debug-stop"] =
function hookDebugStop (e)
{
var jsdFrame = setCurrentFrameByIndex(0);
var type = console.trapType;
//var frameRec = console.stackView.stack.childData[0];
//console.pushStatus (getMsg(MSN_STATUS_STOPPED, [frameRec.functionName,
// frameRec.location]));
var showHeader = (type != jsdIExecutionHook.TYPE_INTERRUPTED ||
console._lastStackDepth != console.frames.length);
var sourceContext = (type == jsdIExecutionHook.TYPE_INTERRUPTED) ? 0 : 2
displayFrame (jsdFrame, 0, showHeader, sourceContext);
var scriptWrapper = getScriptWrapper(jsdFrame.script);
if (scriptWrapper)
{
dispatchCommand (console.coFindScript,
{ scriptWrapper: scriptWrapper, targetPc: jsdFrame.pc })
}
console._lastStackDepth = console.frames.length;
enableDebugCommands();
//XXX
//paintHack();
}
console.hooks["hook-venkman-query-exit"] =
function hookQueryExit (e)
{
if ("frames" in console)
{
if (confirm(MSG_QUERY_CLOSE))
{
dispatch ("cont");
console.__exitAfterContinue__ = true;
}
e.returnValue = false;
}
}
console.hooks["eval"] =
function hookEval()
{
for (var i = 0; i < $.length; ++i)
$[i].refresh();
}
/* exceptions */
/* keep this list in sync with exceptionMsgNames in venkman-msg.js */
const ERR_NOT_IMPLEMENTED = 0;
const ERR_REQUIRED_PARAM = 1;
const ERR_INVALID_PARAM = 2;
const ERR_SUBSCRIPT_LOAD = 3;
const ERR_NO_DEBUGGER = 4;
const ERR_FAILURE = 5;
const ERR_NO_STACK = 6;
/* venkman exception class */
function BadMojo (errno, params)
{
var msg = getMsg(exceptionMsgNames[errno], params);
dd ("new BadMojo (" + errno + ": " + msg + ") from\n" + getStackTrace());
this.message = msg;
this.errno = errno;
this.fileName = Components.stack.caller.filename;
this.lineNumber = Components.stack.caller.lineNumber;
this.functionName = Components.stack.caller.name;
}
BadMojo.prototype.toString =
function bm_tostring ()
{
return formatException (this);
}
function Failure (reason)
{
if (typeof reason == "undefined")
reason = MSG_ERR_DEFAULT_REASON;
var obj = new BadMojo(ERR_FAILURE, [reason]);
obj.fileName = Components.stack.caller.filename;
obj.lineNumber = Components.stack.caller.lineNumber;
obj.functionName = Components.stack.caller.name;
return obj;
}
function InvalidParam (name, value)
{
var obj = new BadMojo(ERR_INVALID_PARAM, [name, String(value)]);
obj.fileName = Components.stack.caller.filename;
obj.lineNumber = Components.stack.caller.lineNumber;
obj.functionName = Components.stack.caller.name;
return obj;
}
function RequiredParam (name)
{
var obj = new BadMojo(ERR_REQUIRED_PARAM, name);
obj.fileName = Components.stack.caller.filename;
obj.lineNumber = Components.stack.caller.lineNumber;
obj.functionName = Components.stack.caller.name;
return obj;
}
/* console object */
console.display = display;
console.dispatch = dispatch;
console.dispatchCommand = dispatchCommand;
console.evalCount = 1;
console.metaDirectives = new Object();
console.metaDirectives["JSD_LOG"] =
console.metaDirectives["JSD_BREAK"] =
console.metaDirectives["JSD_EVAL"] =
function metaBreak (scriptInstance, line, matchResult)
{
var scriptWrapper = scriptInstance.getScriptWrapperAtLine(line);
if (!scriptWrapper)
{
display (getMsg(MSN_ERR_NO_FUNCTION, [line, scriptInstance.url]),
MT_ERROR);
return;
}
var pc = scriptWrapper.jsdScript.lineToPc(line, PCMAP_SOURCETEXT);
if (scriptWrapper.getBreakpoint(pc))
return;
var sourceLine = scriptWrapper.jsdScript.pcToLine(pc, PCMAP_SOURCETEXT);
var breakpoint = setFutureBreakpoint (scriptWrapper.jsdScript.fileName,
sourceLine);
scriptWrapper.setBreakpoint (pc, breakpoint);
matchResult[2] = stringTrim(matchResult[2]);
switch (matchResult[1])
{
case "JSD_LOG":
breakpoint.conditionEnabled = true;
breakpoint.condition = "return eval(" + matchResult[2].quote() + ")";
breakpoint.resultAction = BREAKPOINT_STOPNEVER;
breakpoint.logResult = true;
break;
case "JSD_BREAK":
if (matchResult[2])
{
breakpoint.conditionEnabled = true;
breakpoint.condition = "return eval(" + matchResult[2].quote() +
")";
breakpoint.resultAction = BREAKPOINT_STOPTRUE;
}
else
{
breakpoint.resultAction = BREAKPOINT_STOPALWAYS;
}
break;
case "JSD_EVAL":
breakpoint.conditionEnabled = true;
breakpoint.condition = "return eval(" + matchResult[2].quote() + ")";
breakpoint.resultAction = BREAKPOINT_STOPNEVER;
break;
}
}
console.__defineGetter__ ("status", con_getstatus);
function con_getstatus ()
{
return console.ui["status-text"].getAttribute ("label");
}
console.__defineSetter__ ("status", con_setstatus);
function con_setstatus (msg)
{
var topMsg = console._statusStack[console._statusStack.length - 1];
if (msg)
{
if ("_statusTimeout" in console)
{
clearTimeout (console._statusTimeout);
delete console._statusTimeout;
}
if (msg != topMsg)
{
console._statusTimeout = setTimeout (con_setstatus,
console.prefs["statusDuration"],
null);
}
}
else
{
msg = topMsg;
}
console.ui["status-text"].setAttribute ("label", msg);
}
console.__defineGetter__ ("pp_stopLine", con_getppline);
function con_getppline ()
{
if (!("frames" in console))
return (void 0);
if (!("_pp_stopLine" in this))
{
var frame = getCurrentFrame();
this._pp_stopLine = frame.script.pcToLine(frame.pc, PCMAP_PRETTYPRINT);
}
return this._pp_stopLine;
}
console.pushStatus =
function con_pushstatus (msg)
{
console._statusStack.push (msg);
console.status = msg;
}
console.popStatus =
function con_popstatus ()
{
console._statusStack.pop();
console.status = console._statusStack[console._statusStack.length - 1];
}
function SourceText (scriptInstance)
{
this.lines = new Array();
this.tabWidth = console.prefs["tabWidth"];
if (scriptInstance instanceof ScriptInstance)
{
this.scriptInstance = scriptInstance;
this.url = scriptInstance.url;
this.jsdURL = JSD_URL_SCHEME + "source?location=" +
encodeURIComponent(this.url) +
"&instance=" + scriptInstance.sequence;
}
else
{
/* assume scriptInstance is a string containing the filename */
this.url = scriptInstance;
this.jsdURL = JSD_URL_SCHEME + "source?location=" +
encodeURIComponent(this.url);
}
this.shortName = abbreviateWord(getFileFromPath (this.url), 30);
}
SourceText.prototype.noteFutureBreakpoint =
function st_notefbreak(line, state)
{
if (!ASSERT(!("scriptInstance" in this),
"Don't call noteFutureBreakpoint on a SourceText with a " +
"scriptInstance, use the scriptManager instead."))
{
return;
}
if (state)
arrayOrFlag (this.lineMap, line - 1, LINE_FBREAK);
else
arrayAndFlag (this.lineMap, line - 1, ~LINE_FBREAK);
}
SourceText.prototype.onMarginClick =
function st_marginclick (e, line)
{
//dd ("onMarginClick");
if (!("scriptInstance" in this))
{
if (getFutureBreakpoint(this.url, line))
{
clearFutureBreakpoint(this.url, line);
}
else
{
setFutureBreakpoint(this.url, line);
//dispatch ("fbreak", { urlPattern: this.url, lineNumber: line });
}
}
else
{
var parentBP = getFutureBreakpoint(this.url, line);
if (parentBP)
{
if (this.scriptInstance.hasBreakpoint(line))
this.scriptInstance.clearBreakpoint(line);
else
clearFutureBreakpoint(this.url, line);
}
else
{
if (this.scriptInstance.hasBreakpoint(line))
{
this.scriptInstance.clearBreakpoint(line);
}
else
{
parentBP = setFutureBreakpoint(this.url, line);
this.scriptInstance.setBreakpoint (line, parentBP);
}
}
}
}
SourceText.prototype.isLoaded = false;
SourceText.prototype.reloadSource =
function st_reloadsrc (cb)
{
function reloadCB (status)
{
if (typeof cb == "function")
cb(status);
}
this.isLoaded = false;
this.lines = new Array();
delete this.markup;
delete this.charset;
this.loadSource(reloadCB);
}
SourceText.prototype.onSourceLoaded =
function st_oncomplete (data, url, status)
{
//dd ("source loaded " + url + ", " + status);
var sourceText = this;
function callall (status)
{
while (sourceText.loadCallbacks.length)
{
var cb = sourceText.loadCallbacks.pop();
cb (status);
}
delete sourceText.loadCallbacks;
};
delete this.isLoading;
if (status != Components.results.NS_OK)
{
dd ("loadSource failed with status " + status + ", " + url);
callall (status);
return;
}
if (!ASSERT(data, "loadSource succeeded but got no data"))
data = "";
var matchResult;
// search for xml charset
if (data.substring(0, 5) == ""));
matchResult = s.match(/encoding\s*=\s*([\"\'])([^\"\'\s]+)\1/i);
if (matchResult)
this.charset = matchResult[2];
}
// kill control characters, except \t, \r, and \n
data = data.replace(/[\x00-\x08]|[\x0B\x0C]|[\x0E-\x1F]/g, "?");
// check for a html style charset declaration
if (!("charset" in this))
{
matchResult =
data.match(/meta\s+http-equiv.*content-type.*charset\s*=\s*([^\;\"\'\s]+)/i);
if (matchResult)
this.charset = matchResult[1];
}
// look for an emacs mode line
matchResult = data.match (/-\*-.*tab-width\:\s*(\d+).*-\*-/);
if (matchResult)
this.tabWidth = matchResult[1];
// replace tabs
data = data.replace(/\x09/g, leftPadString ("", this.tabWidth, " "));
var ary = data.split(/\r\n|\n|\r/m);
if (0)
{
for (var i = 0; i < ary.length; ++i)
{
/*
* The replace() strips control characters, we leave the tabs in
* so we can expand them to a per-file width before actually
* displaying them.
*/
ary[i] = ary[i].replace(/[\x00-\x08]|[\x0A-\x1F]/g, "?");
if (!("charset" in this))
{
matchResult = ary[i].match(charsetRE);
if (matchResult)
this.charset = matchResult[1];
}
}
}
this.lines = ary;
if ("scriptInstance" in this)
{
this.scriptInstance.guessFunctionNames(sourceText);
this.lineMap = this.scriptInstance.lineMap;
}
else
{
this.lineMap = new Array();
for (var fbp in console.fbreaks)
{
var fbreak = console.fbreaks[fbp];
if (fbreak.url == this.url)
arrayOrFlag (this.lineMap, fbreak.lineNumber - 1, LINE_FBREAK);
}
}
this.isLoaded = true;
dispatch ("hook-source-load-complete",
{ sourceText: sourceText, status: status });
callall(status);
}
SourceText.prototype.loadSource =
function st_loadsrc (cb)
{
var sourceText = this;
function onComplete (data, url, status)
{
//dd ("loaded " + url + " with status " + status + "\n" + data);
sourceText.onSourceLoaded (data, url, status);
};
if (this.isLoaded)
{
/* if we're loaded, callback right now, and return. */
cb (Components.results.NS_OK);
return;
}
if ("isLoading" in this)
{
/* if we're in the process of loading, make a note of the callback, and
* return. */
if (typeof cb == "function")
this.loadCallbacks.push (cb);
return;
}
else
this.loadCallbacks = new Array();
if (typeof cb == "function")
this.loadCallbacks.push (cb);
this.isLoading = true;
var ex;
var src;
var url = this.url;
if (url.search (/^javascript:/i) == 0)
{
src = url;
delete this.isLoading;
}
else
{
try
{
loadURLAsync (url, { onComplete: onComplete });
return;
}
catch (ex)
{
display (getMsg(MSN_ERR_SOURCE_LOAD_FAILED, [url, ex]), MT_ERROR);
onComplete (src, url, Components.results.NS_ERROR_FAILURE);
return;
}
}
onComplete (src, url, Components.results.NS_OK);
}
function PPSourceText (scriptWrapper)
{
this.scriptWrapper = scriptWrapper;
this.reloadSource();
this.shortName = scriptWrapper.functionName;
this.jsdURL = JSD_URL_SCHEME + "pprint?scriptWrapper=" + scriptWrapper.tag;
}
PPSourceText.prototype.isLoaded = true;
PPSourceText.prototype.reloadSource =
function ppst_reload (cb)
{
try
{
var jsdScript = this.scriptWrapper.jsdScript;
this.tabWidth = console.prefs["tabWidth"];
this.url = jsdScript.fileName;
var lines = String(jsdScript.functionSource).split("\n");
var lineMap = new Array();
var len = lines.length;
for (var i = 0; i < len; ++i)
{
if (jsdScript.isLineExecutable(i + 1, PCMAP_PRETTYPRINT))
lineMap[i] = LINE_BREAKABLE;
}
for (var b in this.scriptWrapper.breaks)
{
var line = jsdScript.pcToLine(this.scriptWrapper.breaks[b].pc,
PCMAP_PRETTYPRINT);
arrayOrFlag (lineMap, line - 1, LINE_BREAK);
}
this.lines = lines;
this.lineMap = lineMap;
delete this.markup;
if (typeof cb == "function")
cb (Components.results.NS_OK);
}
catch (ex)
{
ASSERT(0, "caught exception reloading pretty printed source " + ex);
if (typeof cb == "function")
cb (Components.results.NS_ERROR_FAILURE);
this.lines = [String(MSG_CANT_PPRINT)];
this.lineMap = [0];
}
}
PPSourceText.prototype.onMarginClick =
function ppst_marginclick (e, line)
{
try
{
var jsdScript = this.scriptWrapper.jsdScript;
var pc = jsdScript.lineToPc(line, PCMAP_PRETTYPRINT);
if (this.scriptWrapper.hasBreakpoint(pc))
this.scriptWrapper.clearBreakpoint(pc);
else
this.scriptWrapper.setBreakpoint(pc);
}
catch (ex)
{
ASSERT(0, "onMarginClick caught exception " + ex);
}
}
function HelpText ()
{
this.tabWidth = console.prefs["tabWidth"];
this.jsdURL = this.url = JSD_URL_SCHEME + "help";
this.shortName = this.url;
this.reloadSource();
}
HelpText.prototype.isLoaded = true;
HelpText.prototype.reloadSource =
function ht_reload (cb)
{
var ary = console.commandManager.list();
var str = "";
for (var c in ary)
{
str += "\n ===\n"
+ ary[c].getDocumentation(formatCommandFlags);
}
this.lines = str.split("\n");
if (typeof cb == "function")
cb (Components.results.NS_OK);
}
PK
/i # content/venkman/venkman-debugger.jsUT !?!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
const JSD_CTRID = "@mozilla.org/js/jsd/debugger-service;1";
const jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
const jsdIExecutionHook = Components.interfaces.jsdIExecutionHook;
const jsdIErrorHook = Components.interfaces.jsdIErrorHook;
const jsdICallHook = Components.interfaces.jsdICallHook;
const jsdIValue = Components.interfaces.jsdIValue;
const jsdIProperty = Components.interfaces.jsdIProperty;
const jsdIScript = Components.interfaces.jsdIScript;
const jsdIStackFrame = Components.interfaces.jsdIStackFrame;
const TYPE_VOID = jsdIValue.TYPE_VOID;
const TYPE_NULL = jsdIValue.TYPE_NULL;
const TYPE_BOOLEAN = jsdIValue.TYPE_BOOLEAN;
const TYPE_INT = jsdIValue.TYPE_INT;
const TYPE_DOUBLE = jsdIValue.TYPE_DOUBLE;
const TYPE_STRING = jsdIValue.TYPE_STRING;
const TYPE_FUNCTION = jsdIValue.TYPE_FUNCTION;
const TYPE_OBJECT = jsdIValue.TYPE_OBJECT;
const PROP_ENUMERATE = jsdIProperty.FLAG_ENUMERATE;
const PROP_READONLY = jsdIProperty.FLAG_READONLY;
const PROP_PERMANENT = jsdIProperty.FLAG_PERMANENT;
const PROP_ALIAS = jsdIProperty.FLAG_ALIAS;
const PROP_ARGUMENT = jsdIProperty.FLAG_ARGUMENT;
const PROP_VARIABLE = jsdIProperty.FLAG_VARIABLE;
const PROP_EXCEPTION = jsdIProperty.FLAG_EXCEPTION;
const PROP_ERROR = jsdIProperty.FLAG_ERROR;
const PROP_HINTED = jsdIProperty.FLAG_HINTED;
const SCRIPT_NODEBUG = jsdIScript.FLAG_DEBUG;
const SCRIPT_NOPROFILE = jsdIScript.FLAG_PROFILE;
const COLLECT_PROFILE_DATA = jsdIDebuggerService.COLLECT_PROFILE_DATA;
const PCMAP_SOURCETEXT = jsdIScript.PCMAP_SOURCETEXT;
const PCMAP_PRETTYPRINT = jsdIScript.PCMAP_PRETTYPRINT;
const RETURN_CONTINUE = jsdIExecutionHook.RETURN_CONTINUE;
const RETURN_CONT_THROW = jsdIExecutionHook.RETURN_CONTINUE_THROW;
const RETURN_VALUE = jsdIExecutionHook.RETURN_RET_WITH_VAL;
const RETURN_THROW = jsdIExecutionHook.RETURN_THROW_WITH_VAL;
const FTYPE_STD = 0;
const FTYPE_SUMMARY = 1;
const FTYPE_ARRAY = 2;
const BREAKPOINT_STOPNEVER = 0;
const BREAKPOINT_STOPALWAYS = 1;
const BREAKPOINT_STOPTRUE = 2;
const BREAKPOINT_EARLYRETURN = 3;
var $ = new Array(); /* array to store results from evals in debug frames */
function compareVersion(maj, min)
{
if (console.jsds.implementationMajor < maj)
return -1;
if (console.jsds.implementationMajor > maj)
return 1;
if (console.jsds.implementationMinor < min)
return -1;
if (console.jsds.implementationMinor > min)
return 1;
return 0;
}
function initDebugger()
{
dd ("initDebugger {");
console.instanceSequence = 0;
console._continueCodeStack = new Array(); /* top of stack is the default */
/* return code for the most */
/* recent debugTrap(). */
console.scriptWrappers = new Object();
console.scriptManagers = new Object();
console.breaks = new Object();
console.fbreaks = new Object();
console.sbreaks = new Object();
/* create the debugger instance */
if (!(JSD_CTRID in Components.classes))
throw new BadMojo (ERR_NO_DEBUGGER);
console.jsds =
Components.classes[JSD_CTRID].getService(jsdIDebuggerService);
console.jsds.on();
if (compareVersion(1, 2) >= 0)
console.jsds.flags = jsdIDebuggerService.DISABLE_OBJECT_TRACE;
console.executionHook = { onExecute: jsdExecutionHook };
console.errorHook = { onError: jsdErrorHook };
console.callHook = { onCall: jsdCallHook };
console.jsdConsole = console.jsds.wrapValue(console);
dispatch ("tmode", {mode: console.prefs["lastThrowMode"]});
dispatch ("emode", {mode: console.prefs["lastErrorMode"]});
var enumer = { enumerateScript: console.scriptHook.onScriptCreated };
console.jsds.scriptHook = console.scriptHook;
console.jsds.enumerateScripts(enumer);
console.jsds.breakpointHook = console.executionHook;
console.jsds.debuggerHook = console.executionHook;
console.jsds.debugHook = console.executionHook;
console.jsds.errorHook = console.errorHook;
console.jsds.flags = jsdIDebuggerService.ENABLE_NATIVE_FRAMES;
dd ("} initDebugger");
}
function detachDebugger()
{
if ("frames" in console)
console.jsds.exitNestedEventLoop();
var b;
for (b in console.breaks)
console.breaks[b].clearBreakpoint();
for (b in console.fbreaks)
console.fbreaks[b].clearFutureBreakpoint();
console.jsds.topLevelHook = null;
console.jsds.functionHook = null;
console.jsds.breakpointHook = null;
console.jsds.debuggerHook = null;
console.jsds.errorHook = null;
console.jsds.scriptHook = null;
console.jsds.interruptHook = null;
console.jsds.clearAllBreakpoints();
console.jsds.GC();
if (!console.jsds.initAtStartup)
console.jsds.off();
}
console.scriptHook = new Object();
console.scriptHook.onScriptCreated =
function sh_created (jsdScript)
{
try
{
jsdScriptCreated(jsdScript);
}
catch (ex)
{
dd ("caught " + dumpObjectTree(ex) + " while creating script.");
}
}
console.scriptHook.onScriptDestroyed =
function sh_destroyed (jsdScript)
{
try
{
jsdScriptDestroyed(jsdScript);
}
catch (ex)
{
dd ("caught " + dumpObjectTree(ex) + " while destroying script.");
}
}
function jsdScriptCreated (jsdScript)
{
var url = jsdScript.fileName;
var manager;
if (!(url in console.scriptManagers))
{
manager = console.scriptManagers[url] = new ScriptManager(url);
//dispatchCommand (console.coManagerCreated, { scriptManager: manager });
}
else
{
manager = console.scriptManagers[url];
}
manager.onScriptCreated(jsdScript);
}
function jsdScriptDestroyed (jsdScript)
{
if (!(jsdScript.tag in console.scriptWrappers))
return;
var scriptWrapper = console.scriptWrappers[jsdScript.tag];
scriptWrapper.scriptManager.onScriptInvalidated(scriptWrapper);
if (scriptWrapper.scriptManager.instances.length == 0 &&
scriptWrapper.scriptManager.transientCount == 0)
{
delete console.scriptManagers[scriptWrapper.scriptManager.url];
//dispatchCommand (console.coManagerDestroyed,
// { scriptManager: scriptWrapper.scriptManager });
}
}
function jsdExecutionHook (frame, type, rv)
{
dd ("execution hook: " + formatFrame(frame));
var hookReturn = jsdIExecutionHook.RETURN_CONTINUE;
if (!console.initialized)
return hookReturn;
if (!ASSERT(!("frames" in console),
"Execution hook called while stopped") ||
frame.isNative ||
!ASSERT(frame.script, "Execution hook called with no script") ||
frame.script.fileName == MSG_VAL_CONSOLE ||
!ASSERT(!(frame.script.flags & SCRIPT_NODEBUG),
"Stopped in a script marked as don't debug") ||
!ASSERT(isURLVenkman(frame.script.fileName) ||
!isURLFiltered(frame.script.fileName),
"stopped in a filtered URL"))
{
return hookReturn;
}
var frames = new Array();
var prevFrame = frame;
var hasDisabledFrame = false;
while (prevFrame)
{
frames.push(prevFrame);
prevFrame = prevFrame.callingFrame;
}
var targetWindow = null;
var wasModal = false;
var cx;
try
{
cx = frame.executionContext;
}
catch (ex)
{
dd ("no context");
cx = null;
}
var targetWasEnabled = true;
var debuggerWasEnabled = console.baseWindow.enabled;
console.baseWindow.enabled = true;
if (!ASSERT(cx, "no cx in execution hook"))
return hookReturn;
var glob = cx.globalObject;
if (!ASSERT(glob, "no glob in execution hook"))
return hookReturn;
console.targetWindow = getBaseWindowFromWindow(glob.getWrappedValue());
targetWasEnabled = console.targetWindow.enabled;
if (console.targetWindow != console.baseWindow)
{
cx.scriptsEnabled = false;
console.targetWindow.enabled = false;
}
try
{
//dd ("debug trap " + formatFrame(frame));
hookReturn = debugTrap(frames, type, rv);
//dd ("debug trap returned " + hookReturn);
}
catch (ex)
{
display (MSG_ERR_INTERNAL_BPT, MT_ERROR);
display (formatException(ex), MT_ERROR);
}
if (console.targetWindow && console.targetWindow != console.baseWindow)
{
console.targetWindow.enabled = targetWasEnabled;
cx.scriptsEnabled = true;
}
console.baseWindow.enabled = debuggerWasEnabled;
delete console.frames;
delete console.targetWindow;
if ("__exitAfterContinue__" in console)
window.close();
return hookReturn;
}
function jsdCallHook (frame, type)
{
if (!console.initialized)
return;
if (type == jsdICallHook.TYPE_FUNCTION_CALL)
{
setStopState(false);
//dd ("Calling: " + frame.functionName);
}
else if (type == jsdICallHook.TYPE_FUNCTION_RETURN)
{
// we're called *before* the returning frame is popped from the
// stack, so we want our depth calculation to be off by one.
var depth = -1;
var prevFrame = frame;
while (prevFrame)
{
depth++;
prevFrame = prevFrame.callingFrame;
}
//dd ("Returning: " + frame.functionName +
// ", target depth: " + console._stepOverDepth +
// ", current depth: " + depth);
if (depth <= console._stepOverDepth)
{
//dd ("step over at target depth of " + depth);
setStopState(true);
console.jsds.functionHook = null;
delete console._stepOverDepth;
}
}
}
function jsdErrorHook (message, fileName, line, pos, flags, exception)
{
if (!console.initialized || isURLFiltered (fileName))
return true;
try
{
var flagstr;
flagstr =
(flags && jsdIErrorHook.REPORT_EXCEPTION) ? "x" : "-";
flagstr +=
(flags && jsdIErrorHook.REPORT_STRICT) ? "s" : "-";
//dd ("===\n" + message + "\n" + fileName + "@" +
// line + ":" + pos + "; " + flagstr);
var msn = (flags & jsdIErrorHook.REPORT_WARNING) ?
MSN_ERPT_WARN : MSN_ERPT_ERROR;
if (console.errorMode != EMODE_IGNORE)
display (getMsg(msn, [message, flagstr, fileName,
line, pos]), MT_ETRACE);
if (console.errorMode == EMODE_BREAK)
return false;
return true;
}
catch (ex)
{
dd ("error in error hook: " + ex);
}
return true;
}
function ScriptManager (url)
{
this.url = url;
this.instances = new Array();
this.transients = new Object();
this.transientCount = 0;
this.disableTransients = isURLFiltered(url);
}
ScriptManager.prototype.onScriptCreated =
function smgr_created (jsdScript)
{
var instance;
if (!ASSERT(jsdScript.isValid, "invalid script created!"))
return;
if (this.instances.length != 0)
instance = this.instances[this.instances.length - 1];
if (!instance || (instance.isSealed && jsdScript.functionName))
{
//dd ("instance created for " + jsdScript.fileName);
instance = new ScriptInstance(this);
instance.sequence = console.instanceSequence++;
this.instances.push(instance);
dispatchCommand (console.coInstanceCreated,
{ scriptInstance: instance });
}
if ("_lastScriptWrapper" in console)
{
if ((console._lastScriptWrapper.scriptManager != this ||
console._lastScriptWrapper.scriptInstance != instance) &&
console._lastScriptWrapper.scriptInstance.scriptCount &&
!console._lastScriptWrapper.scriptInstance.isSealed)
{
console._lastScriptWrapper.scriptInstance.seal();
}
}
var scriptWrapper = new ScriptWrapper(jsdScript);
console._lastScriptWrapper = scriptWrapper;
scriptWrapper.scriptManager = this;
console.scriptWrappers[jsdScript.tag] = scriptWrapper;
scriptWrapper.scriptInstance = instance;
if (!instance.isSealed)
{
//dd ("function created " + formatScript(jsdScript));
instance.onScriptCreated (scriptWrapper);
}
else
{
//dd ("transient created " + formatScript(jsdScript));
++this.transientCount;
if (this.disableTransients)
jsdScript.flags |= SCRIPT_NODEBUG | SCRIPT_NOPROFILE;
this.transients[jsdScript.tag] = scriptWrapper;
scriptWrapper.functionName = MSG_VAL_EVSCRIPT;
//dispatch ("hook-transient-script", { scriptWrapper: scriptWrapper });
}
}
ScriptManager.prototype.onScriptInvalidated =
function smgr_invalidated (scriptWrapper)
{
//dd ("script invalidated");
delete console.scriptWrappers[scriptWrapper.tag];
if (scriptWrapper.tag in this.transients)
{
//dd ("transient destroyed " + formatScript(scriptWrapper.jsdScript));
--this.transientCount;
delete this.transients[scriptWrapper.tag];
//dispatch ("hook-script-invalidated", { scriptWrapper: scriptWrapper });
}
else
{
//dd ("function destroyed " + formatScript(scriptWrapper.jsdScript));
scriptWrapper.scriptInstance.onScriptInvalidated(scriptWrapper);
//dispatch ("hook-script-invalidated", { scriptWrapper: scriptWrapper });
if (scriptWrapper.scriptInstance.scriptCount == 0)
{
var i = arrayIndexOf(this.instances, scriptWrapper.scriptInstance);
arrayRemoveAt(this.instances, i);
dispatchCommand (console.coInstanceDestroyed,
{ scriptInstance: scriptWrapper.scriptInstance });
}
}
}
ScriptManager.prototype.__defineGetter__ ("sourceText", smgr_sourcetext);
function smgr_sourcetext()
{
return this.instances[this.instances.length - 1].sourceText;
}
ScriptManager.prototype.__defineGetter__ ("lineMap", smgr_linemap);
function smgr_linemap()
{
return this.instances[this.instances.length - 1].lineMap;
}
ScriptManager.prototype.getInstanceBySequence =
function smgr_bysequence (seq)
{
for (var i = 0; i < this.instances.length; ++i)
{
if (this.instances[i].sequence == seq)
return this.instances[i];
}
return null;
}
ScriptManager.prototype.isLineExecutable =
function smgr_isexe (line)
{
for (var i in this.instances)
{
if (this.instances[i].isLineExecutable(line))
return true;
}
return false;
}
ScriptManager.prototype.hasBreakpoint =
function smgr_hasbp (line)
{
for (var i in this.instances)
{
if (this.instances[i].hasBreakpoint(line))
return true;
}
return false;
}
ScriptManager.prototype.setBreakpoint =
function smgr_break (line, parentBP, props)
{
var found = false;
for (var i in this.instances)
found |= this.instances[i].setBreakpoint(line, parentBP, props);
return found;
}
ScriptManager.prototype.clearBreakpoint =
function smgr_break (line)
{
var found = false;
for (var i in this.instances)
found |= this.instances[i].clearBreakpoint(line);
return found;
}
ScriptManager.prototype.hasFutureBreakpoint =
function smgr_hasbp (line)
{
var key = this.url + "#" + line;
return (key in console.fbreaks);
}
ScriptManager.prototype.getFutureBreakpoint =
function smgr_getfbp (line)
{
return getFutureBreakpoint (this.url, line);
}
ScriptManager.prototype.noteFutureBreakpoint =
function smgr_fbreak (line, state)
{
for (var i in this.instances)
{
if (this.instances[i]._lineMapInited)
{
if (state)
{
arrayOrFlag (this.instances[i]._lineMap, line - 1, LINE_FBREAK);
}
else
{
arrayAndFlag (this.instances[i]._lineMap, line - 1,
~LINE_FBREAK);
}
}
}
}
function ScriptInstance (manager)
{
this.scriptManager = manager;
this.url = manager.url;
this.creationDate = new Date();
this.topLevel = null;
this.functions = new Object();
this.nestLevel = 0;
this.isSealed = false;
this.scriptCount = 0;
this.breakpointCount = 0;
this.disabledScripts = 0;
this._lineMap = new Array();
this._lineMapInited = false;
}
ScriptInstance.prototype.scanForMetaComments =
function si_scan (start)
{
const CHUNK_SIZE = 500;
const CHUNK_DELAY = 100;
var scriptInstance = this;
var sourceText = this.sourceText;
function onSourceLoaded(result)
{
if (result == Components.results.NS_OK)
scriptInstance.scanForMetaComments();
};
if (!sourceText.isLoaded)
{
sourceText.loadSource(onSourceLoaded);
return;
}
if (typeof start == "undefined")
start = 0;
var end = Math.min (sourceText.lines.length, start + CHUNK_SIZE);
var obj = new Object();
for (var i = start; i < end; ++i)
{
var ary = sourceText.lines[i].match (/\/\/@(\S+)(.*)/);
if (ary && ary[1] in console.metaDirectives && !(ary[1] in obj))
{
try
{
console.metaDirectives[ary[1]](scriptInstance, i + 1, ary);
}
catch (ex)
{
display (getMsg(MSN_ERR_META_FAILED, [ary[1], this.url, i + 1]),
MT_ERROR);
display (formatException (ex), MT_ERROR);
}
}
}
if (i != sourceText.lines.length)
setTimeout (this.scanForMetaComments, CHUNK_DELAY, i);
}
ScriptInstance.prototype.seal =
function si_seal ()
{
this.sealDate = new Date();
this.isSealed = true;
if (isURLFiltered(this.url))
{
this.disabledScripts = 1;
var nada = SCRIPT_NODEBUG | SCRIPT_NOPROFILE;
if (this.topLevel && this.topLevel.isValid)
this.topLevel.jsdScript.flags |= nada;
for (var f in this.functions)
{
if (this.functions[f].jsdScript.isValid)
this.functions[f].jsdScript.flags |= nada;
++this.disabledScripts;
}
}
dispatch ("hook-script-instance-sealed", { scriptInstance: this });
}
ScriptInstance.prototype.onScriptCreated =
function si_created (scriptWrapper)
{
var tag = scriptWrapper.jsdScript.tag;
if (scriptWrapper.functionName)
{
this.functions[tag] = scriptWrapper;
}
else
{
this.topLevel = scriptWrapper;
scriptWrapper.functionName = MSG_VAL_TLSCRIPT;
scriptWrapper.addToLineMap(this._lineMap);
//var dummy = scriptWrapper.sourceText;
this.seal();
}
++this.scriptCount;
}
ScriptInstance.prototype.onScriptInvalidated =
function si_invalidated (scriptWrapper)
{
//dd ("script invalidated");
scriptWrapper.clearBreakpoints();
--this.scriptCount;
}
ScriptInstance.prototype.__defineGetter__ ("sourceText", si_gettext);
function si_gettext ()
{
if (!("_sourceText" in this))
this._sourceText = new SourceText (this);
return this._sourceText;
}
ScriptInstance.prototype.__defineGetter__ ("lineMap", si_linemap);
function si_linemap()
{
if (!this._lineMapInited)
{
if (this.topLevel && this.topLevel.jsdScript.isValid)
this.topLevel.addToLineMap(this._lineMap);
for (var i in this.functions)
{
if (this.functions[i].jsdScript.isValid)
this.functions[i].addToLineMap(this._lineMap);
}
for (var fbp in console.fbreaks)
{
var fbreak = console.fbreaks[fbp];
if (fbreak.url == this.url)
arrayOrFlag (this._lineMap, fbreak.lineNumber - 1, LINE_FBREAK);
}
this._lineMapInited = true;
}
return this._lineMap;
}
ScriptInstance.prototype.isLineExecutable =
function si_isexe (line)
{
if (this.topLevel && this.topLevel.jsdScript.isValid &&
this.topLevel.jsdScript.isLineExecutable (line, PCMAP_SOURCETEXT))
{
return true;
}
for (var f in this.functions)
{
var jsdScript = this.functions[f].jsdScript;
if (line >= jsdScript.baseLineNumber &&
line <= jsdScript.baseLineNumber + jsdScript.lineExtent &&
jsdScript.isLineExecutable (line, PCMAP_SOURCETEXT))
{
return true;
}
}
return false;
}
ScriptInstance.prototype.hasBreakpoint =
function si_hasbp (line)
{
return Boolean (this.getBreakpoint(line));
}
ScriptInstance.prototype.getBreakpoint =
function si_getbp (line)
{
for (var b in console.breaks)
{
if (console.breaks[b].scriptWrapper.scriptInstance == this)
{
if (typeof line == "undefined")
return true;
var jsdScript = console.breaks[b].scriptWrapper.jsdScript;
if (jsdScript.pcToLine(console.breaks[b].pc, PCMAP_SOURCETEXT) ==
line)
{
return console.breaks[b];
}
}
}
return false;
}
ScriptInstance.prototype.setBreakpoint =
function si_setbp (line, parentBP, props)
{
function setBP (scriptWrapper)
{
if (!scriptWrapper.jsdScript.isValid)
return false;
var jsdScript = scriptWrapper.jsdScript;
if (line >= jsdScript.baseLineNumber &&
line <= jsdScript.baseLineNumber + jsdScript.lineExtent &&
(jsdScript.isLineExecutable (line, PCMAP_SOURCETEXT) ||
jsdScript.baseLineNumber == line))
{
var pc = jsdScript.lineToPc(line, PCMAP_SOURCETEXT);
scriptWrapper.setBreakpoint(pc, parentBP, props);
return true;
}
return false;
};
var found;
if (this.topLevel)
found = setBP (this.topLevel);
for (var f in this.functions)
found |= setBP (this.functions[f]);
if (this._lineMapInited && found)
arrayOrFlag(this._lineMap, line - 1, LINE_BREAK);
return found;
}
ScriptInstance.prototype.clearBreakpoint =
function si_setbp (line)
{
var found = false;
function clearBP (scriptWrapper)
{
var jsdScript = scriptWrapper.jsdScript;
if (!jsdScript.isValid)
return;
var pc = jsdScript.lineToPc(line, PCMAP_SOURCETEXT);
if (line >= jsdScript.baseLineNumber &&
line <= jsdScript.baseLineNumber + jsdScript.lineExtent &&
scriptWrapper.hasBreakpoint(pc))
{
found |= scriptWrapper.clearBreakpoint(pc);
}
};
if (this._lineMapInited)
arrayAndFlag(this._lineMap, line - 1, ~LINE_BREAK);
if (this.topLevel)
clearBP (this.topLevel);
for (var f in this.functions)
clearBP (this.functions[f]);
return found;
}
ScriptInstance.prototype.getScriptWrapperAtLine =
function si_getscript (line)
{
var targetScript = null;
var scriptWrapper;
if (this.topLevel)
{
scriptWrapper = this.topLevel;
if (line >= scriptWrapper.jsdScript.baseLineNumber &&
line <= scriptWrapper.jsdScript.baseLineNumber +
scriptWrapper.jsdScript.lineExtent)
{
targetScript = scriptWrapper;
}
}
for (var f in this.functions)
{
scriptWrapper = this.functions[f];
if ((line >= scriptWrapper.jsdScript.baseLineNumber &&
line <= scriptWrapper.jsdScript.baseLineNumber +
scriptWrapper.jsdScript.lineExtent) &&
(!targetScript ||
scriptWrapper.jsdScript.lineExtent <
targetScript.jsdScript.lineExtent))
{
targetScript = scriptWrapper;
}
}
return targetScript;
}
ScriptInstance.prototype.containsScriptTag =
function si_contains (tag)
{
return ((this.topLevel && this.topLevel.tag == tag) ||
(tag in this.functions));
}
ScriptInstance.prototype.guessFunctionNames =
function si_guessnames ()
{
var sourceLines = this._sourceText.lines;
var context = console.prefs["guessContext"];
var pattern = new RegExp (console.prefs["guessPattern"]);
var scanText;
function getSourceContext (end)
{
var startLine = end - context;
if (startLine < 0)
startLine = 0;
var text = "";
for (i = startLine; i <= targetLine; ++i)
text += String(sourceLines[i]);
var pos = text.lastIndexOf ("function");
if (pos != -1)
text = text.substring(0, pos);
return text;
};
for (var i in this.functions)
{
var scriptWrapper = this.functions[i];
if (scriptWrapper.jsdScript.functionName != "anonymous")
continue;
var targetLine = scriptWrapper.jsdScript.baseLineNumber;
if (targetLine > sourceLines.length)
{
dd ("not enough source to guess function at line " + targetLine);
return;
}
scanText = getSourceContext(targetLine);
var ary = scanText.match (pattern);
if (ary)
{
if ("charset" in this._sourceText)
ary[1] = toUnicode(ary[1], this._sourceText.charset);
scriptWrapper.functionName = getMsg(MSN_FMT_GUESSEDNAME, ary[1]);
}
else
{
if ("guessFallback" in console)
{
var name = console.guessFallback(scriptWrapper, scanText);
if (name)
{
scriptWrapper.functionName = getMsg(MSN_FMT_GUESSEDNAME,
name);
}
}
}
}
dispatch ("hook-guess-complete", { scriptInstance: this });
}
function ScriptWrapper (jsdScript)
{
this.jsdScript = jsdScript;
this.tag = jsdScript.tag;
this.functionName = jsdScript.functionName;
this.breakpointCount = 0;
this._lineMap = null;
this.breaks = new Object();
}
ScriptWrapper.prototype.__defineGetter__ ("sourceText", sw_getsource);
function sw_getsource ()
{
if (!("_sourceText" in this))
{
if (!this.jsdScript.isValid)
return null;
this._sourceText = new PPSourceText(this);
}
return this._sourceText;
}
ScriptWrapper.prototype.__defineGetter__ ("lineMap", sw_linemap);
function sw_linemap ()
{
if (!this._lineMap)
this.addToLineMap(this._lineMap);
return this._lineMap;
}
ScriptWrapper.prototype.hasBreakpoint =
function sw_hasbp (pc)
{
var key = this.jsdScript.tag + ":" + pc;
return key in console.breaks;
}
ScriptWrapper.prototype.getBreakpoint =
function sw_hasbp (pc)
{
var key = this.jsdScript.tag + ":" + pc;
if (key in console.breaks)
return console.breaks[key];
return null;
}
ScriptWrapper.prototype.setBreakpoint =
function sw_setbp (pc, parentBP, props)
{
var key = this.jsdScript.tag + ":" + pc;
//dd ("setting breakpoint in " + this.functionName + " " + key);
if (key in console.breaks)
return null;
var brk = new BreakInstance (parentBP, this, pc);
if (props)
brk.setProperties(props);
console.breaks[key] = brk;
this.breaks[key] = brk;
if (parentBP)
{
parentBP.childrenBP[key] = brk;
brk.lineNumber = parentBP.lineNumber;
brk.url = parentBP.url;
}
if ("_sourceText" in this)
{
var line = this.jsdScript.pcToLine(brk.pc, PCMAP_PRETTYPRINT);
arrayOrFlag (this._sourceText.lineMap, line - 1, LINE_BREAK);
}
++this.scriptInstance.breakpointCount;
++this.breakpointCount;
if (this.scriptInstance._lineMapInited)
{
line = this.jsdScript.pcToLine (pc, PCMAP_SOURCETEXT);
arrayOrFlag (this.scriptInstance._lineMap, line - 1, LINE_BREAK);
}
dispatch ("hook-break-set", { breakWrapper: brk });
return brk;
}
ScriptWrapper.prototype.clearBreakpoints =
function sw_clearbps ()
{
var found = false;
for (b in this.breaks)
found |= this.clearBreakpoint(this.breaks[b].pc);
return found;
}
ScriptWrapper.prototype.clearBreakpoint =
function sw_clearbp (pc)
{
var key = this.jsdScript.tag + ":" + pc;
if (!(key in console.breaks))
return false;
var brk = console.breaks[key];
if ("propsWindow" in brk)
brk.propsWindow.close();
delete console.breaks[key];
delete this.breaks[key];
if (brk.parentBP)
delete brk.parentBP.childrenBP[key];
var line;
if ("_sourceText" in this && this.jsdScript.isValid)
{
line = this.jsdScript.pcToLine(brk.pc, PCMAP_PRETTYPRINT);
this._sourceText.lineMap[line - 1] &= ~LINE_BREAK;
}
--this.scriptInstance.breakpointCount;
--this.breakpointCount;
if (this.scriptInstance._lineMapInited)
{
if (this.jsdScript.isValid)
{
line = this.jsdScript.pcToLine (pc, PCMAP_SOURCETEXT);
if (!this.scriptInstance.hasBreakpoint(line))
this.scriptInstance._lineMap[line - 1] &= ~LINE_BREAK;
}
else
{
/* script is gone, no way to find out where the break actually
* was, so we have to redo the whole map. */
this.scriptInstance._lineMapInited = false;
this.scriptInstance._lineMap.length = 0;
var dummy = this.scriptInstance.lineMap;
}
}
dispatch ("hook-break-clear", { breakWrapper: brk });
if (this.jsdScript.isValid)
this.jsdScript.clearBreakpoint (pc);
return true;
}
ScriptWrapper.prototype.addToLineMap =
function sw_addmap (lineMap)
{
var jsdScript = this.jsdScript;
var end = jsdScript.baseLineNumber + jsdScript.lineExtent;
for (var i = jsdScript.baseLineNumber; i < end; ++i)
{
if (jsdScript.isLineExecutable(i, PCMAP_SOURCETEXT))
arrayOrFlag (lineMap, i - 1, LINE_BREAKABLE);
}
for (i in this.breaks)
{
var line = jsdScript.pcToLine(this.breaks[i].pc, PCMAP_SOURCETEXT);
arrayOrFlag (lineMap, line - 1, LINE_BREAK);
}
}
function getScriptWrapper(jsdScript)
{
if (!ASSERT(jsdScript, "getScriptWrapper: null jsdScript"))
return null;
var tag = jsdScript.tag;
if (tag in console.scriptWrappers)
return console.scriptWrappers[tag];
dd ("Can't find a wrapper for " + formatScript(jsdScript));
return null;
}
function BreakInstance (parentBP, scriptWrapper, pc)
{
this._enabled = true;
this.parentBP = parentBP;
this.scriptWrapper = scriptWrapper;
this.pc = pc;
this.url = scriptWrapper.jsdScript.fileName;
this.lineNumber = scriptWrapper.jsdScript.pcToLine (pc, PCMAP_SOURCETEXT);
this.oneTime = false;
this.triggerCount = 0;
scriptWrapper.jsdScript.setBreakpoint (pc);
}
BreakInstance.prototype.__defineGetter__ ("jsdURL", bi_getURL);
function bi_getURL ()
{
return ("x-jsd:break?url=" + encodeURIComponent(this.url) +
"&lineNumber=" + this.lineNumber +
"&conditionEnabled=" + this.conditionEnabled +
"&condition=" + encodeURIComponent(this.condition) +
"&passExceptions=" + this.passExceptions +
"&logResult=" + this.logResult +
"&resultAction=" + this.resultAction +
"&enabled=" + this.enabled);
}
BreakInstance.prototype.getProperties =
function bi_getprops()
{
var rv = new Object();
rv.enabled = this._enabled;
if ("_conditionEnabled" in this)
rv.conditionEnabled = this._conditionEnabled;
if ("_condition" in this)
rv.condition = this._condition;
if ("_passExceptions" in this)
rv.passExceptions = this._passExceptions;
if ("_logResult" in this)
rv.logResult = this._logResult;
if ("_resultAction" in this)
rv.resultAction = this._resultAction;
return rv;
}
BreakInstance.prototype.setProperties =
function bi_setprops(obj)
{
for (var p in obj)
{
if (p.search(/pc|url|lineNumber/) == -1)
this[p] = obj[p];
}
if ("propsWindow" in this)
this.propsWindow.populateFromBreakpoint();
}
BreakInstance.prototype.clearBreakpoint =
function bi_clear()
{
this.scriptWrapper.clearBreakpoint(this.pc);
}
BreakInstance.prototype.__defineGetter__ ("enabled", bi_getEnabled);
function bi_getEnabled ()
{
return this._enabled;
}
BreakInstance.prototype.__defineSetter__ ("enabled", bi_setEnabled);
function bi_setEnabled (state)
{
if (state != this._enabled)
{
this._enabled = state;
if (state)
this.scriptWrapper.jsdScript.setBreakpoint(this.pc);
else
this.scriptWrapper.jsdScript.clearBreakpoint(this.pc);
}
return state;
}
BreakInstance.prototype.__defineGetter__ ("conditionEnabled", bi_getCondEnabled);
function bi_getCondEnabled ()
{
if ("_conditionEnabled" in this)
return this._conditionEnabled;
if (this.parentBP)
return this.parentBP.conditionEnabled;
return false;
}
BreakInstance.prototype.__defineSetter__ ("conditionEnabled", bi_setCondEnabled);
function bi_setCondEnabled (state)
{
if (this.parentBP)
return this.parentBP.conditionEnabled = state;
return this._conditionEnabled = state;
}
BreakInstance.prototype.__defineGetter__ ("condition", bi_getCondition);
function bi_getCondition ()
{
if ("_condition" in this)
return this._condition;
if (this.parentBP)
return this.parentBP.condition;
return "";
}
BreakInstance.prototype.__defineSetter__ ("condition", bi_setCondition);
function bi_setCondition (value)
{
if (this.parentBP)
return this.parentBP.condition = value;
return this._condition = value;
}
BreakInstance.prototype.__defineGetter__ ("passExceptions", bi_getException);
function bi_getException ()
{
if ("_passExceptions" in this)
return this._passExceptions;
if (this.parentBP)
return this.parentBP.passExceptions;
return false;
}
BreakInstance.prototype.__defineSetter__ ("passExceptions", bi_setException);
function bi_setException (state)
{
if (this.parentBP)
return this.parentBP.passExceptions = state;
return this._passExceptions = state;
}
BreakInstance.prototype.__defineGetter__ ("logResult", bi_getLogResult);
function bi_getLogResult ()
{
if ("_logResult" in this)
return this._logResult;
if (this.parentBP)
return this.parentBP.logResult;
return false;
}
BreakInstance.prototype.__defineSetter__ ("logResult", bi_setLogResult);
function bi_setLogResult (state)
{
if (this.parentBP)
return this.parentBP.logResult = state;
return this._logResult = state;
}
BreakInstance.prototype.__defineGetter__ ("resultAction", bi_getResultAction);
function bi_getResultAction ()
{
if ("_resultAction" in this)
return this._resultAction;
if (this.parentBP)
return this.parentBP.resultAction;
return BREAKPOINT_STOPALWAYS;
}
BreakInstance.prototype.__defineSetter__ ("resultAction", bi_setResultAction);
function bi_setResultAction (state)
{
if (this.parentBP)
return this.parentBP.resultAction = state;
return this._resultAction = state;
}
function FutureBreakpoint (url, lineNumber)
{
this.url = url;
this.lineNumber = lineNumber;
this.enabled = true;
this.childrenBP = new Object();
this.conditionEnabled = false;
this.condition = "";
this.passExceptions = false;
this.logResult = false;
this.resultAction = BREAKPOINT_STOPALWAYS;
}
FutureBreakpoint.prototype.__defineGetter__ ("jsdURL", fb_getURL);
function fb_getURL ()
{
return ("x-jsd:fbreak?url=" + encodeURIComponent(this.url) +
"&lineNumber=" + this.lineNumber +
"&conditionEnabled=" + this.conditionEnabled +
"&condition=" + encodeURIComponent(this.condition) +
"&passExceptions=" + this.passExceptions +
"&logResult=" + this.logResult +
"&resultAction=" + this.resultAction +
"&enabled=" + this.enabled);
}
FutureBreakpoint.prototype.getProperties =
function fb_getprops()
{
var rv = new Object();
rv.conditionEnabled = this.conditionEnabled;
rv.condition = this.condition;
rv.passExceptions = this.passExceptions;
rv.logResult = this.logResult;
rv.resultAction = this.resultAction;
return rv;
}
FutureBreakpoint.prototype.setProperties =
function fb_setprops(obj)
{
for (var p in obj)
{
if (p.search(/url|lineNumber|childrenBP/) == -1)
this[p] = obj[p];
}
if ("propsWindow" in this)
this.propsWindow.populateFromBreakpoint();
}
FutureBreakpoint.prototype.clearFutureBreakpoint =
function fb_clear ()
{
clearFutureBreakpoint (this.url, this.lineNumber);
}
FutureBreakpoint.prototype.resetInstances =
function fb_reseti ()
{
for (var url in console.scriptManagers)
{
if (url.indexOf(this.url) != -1)
console.scriptManagers[url].setBreakpoint(this.lineNumber);
}
}
FutureBreakpoint.prototype.clearInstances =
function fb_cleari ()
{
for (var url in console.scriptManagers)
{
if (url.indexOf(this.url) != -1)
console.scriptManagers[url].clearBreakpoint(this.lineNumber);
}
}
function testBreakpoint(currentFrame, rv)
{
var tag = currentFrame.script.tag;
if (!(tag in console.scriptWrappers))
return -1;
var scriptWrapper = console.scriptWrappers[tag];
var breakpoint = scriptWrapper.getBreakpoint(currentFrame.pc);
if (!ASSERT(breakpoint, "can't find breakpoint for " +
formatFrame(currentFrame)))
{
return -1;
}
if (!ASSERT(breakpoint.enabled, "stopped at a disabled breakpoint?"))
return RETURN_CONTINUE;
++breakpoint.triggerCount;
if ("propsWindow" in breakpoint)
breakpoint.propsWindow.onBreakpointTriggered();
if (breakpoint.oneTime)
scriptWrapper.clearBreakpoint(currentFrame.pc);
if (breakpoint.conditionEnabled && breakpoint.condition)
{
var result = new Object();
var script = "var __trigger__ = function (__count__) {" +
breakpoint.condition + "}; __trigger__.apply(this, [" +
breakpoint.triggerCount + "]);";
if (!currentFrame.eval (script,
JSD_URL_SCHEME + "breakpoint-condition",
1, result))
{
/* condition raised an exception */
if (breakpoint.passExceptions)
{
rv.value = result.value;
return RETURN_THROW;
}
display (MSG_ERR_CONDITION_FAILED, MT_ERROR);
display (formatException(result.value.getWrappedValue()), MT_ERROR);
}
else
{
/* condition executed ok */
if (breakpoint.logResult)
{
display (result.value.stringValue, MT_LOG);
}
if (breakpoint.resultAction == BREAKPOINT_EARLYRETURN)
{
rv.value = result.value;
return RETURN_VALUE;
}
if (breakpoint.resultAction == BREAKPOINT_STOPNEVER ||
(breakpoint.resultAction == BREAKPOINT_STOPTRUE &&
!result.value.booleanValue))
{
return RETURN_CONTINUE;
}
}
}
return -1;
}
const EMODE_IGNORE = 0;
const EMODE_TRACE = 1;
const EMODE_BREAK = 2;
const TMODE_IGNORE = 0;
const TMODE_TRACE = 1;
const TMODE_BREAK = 2;
function debugTrap (frames, type, rv)
{
var tn = "";
var retcode = jsdIExecutionHook.RETURN_CONTINUE;
//dd ("debugTrap");
var frame = frames[0];
$ = new Array();
switch (type)
{
case jsdIExecutionHook.TYPE_BREAKPOINT:
var bpResult = testBreakpoint(frame, rv);
if (bpResult != -1)
return bpResult;
tn = MSG_VAL_BREAKPOINT;
break;
case jsdIExecutionHook.TYPE_DEBUG_REQUESTED:
tn = MSG_VAL_DEBUG;
break;
case jsdIExecutionHook.TYPE_DEBUGGER_KEYWORD:
tn = MSG_VAL_DEBUGGER;
break;
case jsdIExecutionHook.TYPE_THROW:
dd (dumpObjectTree(rv));
display (getMsg(MSN_EXCEPTION_TRACE,
[rv.value.stringValue, formatFrame(frame)]),
MT_ETRACE);
if (rv.value.jsClassName == "Error")
display (formatProperty(rv.value.getProperty("message")),
MT_EVAL_OUT);
if (console.throwMode != TMODE_BREAK)
return jsdIExecutionHook.RETURN_CONTINUE_THROW;
console.currentException = rv.value;
retcode = jsdIExecutionHook.RETURN_CONTINUE_THROW;
tn = MSG_VAL_THROW;
break;
case jsdIExecutionHook.TYPE_INTERRUPTED:
if (!frame.script.functionName &&
isURLFiltered(frame.script.fileName))
{
//dd ("filtered url: " + frame.script.fileName);
frame.script.flags |= SCRIPT_NOPROFILE | SCRIPT_NODEBUG;
return retcode;
}
var line;
if (console.prefs["prettyprint"])
line = frame.script.pcToLine (frame.pc, PCMAP_PRETTYPRINT);
else
line = frame.line;
if (console._stepPast ==
frames.length + frame.script.fileName + line)
{
//dd("stepPast: " + console._stepPast);
return retcode;
}
delete console._stepPast;
setStopState(false);
break;
default:
/* don't print stop/cont messages for other types */
}
console.jsds.functionHook = null;
/* set our default return value */
console._continueCodeStack.push (retcode);
if (tn)
display (getMsg(MSN_STOP, tn), MT_STOP);
/* build an array of frames */
console.frames = frames;
console.trapType = type;
try
{
console.jsds.enterNestedEventLoop({onNest: eventLoopNested});
}
catch (ex)
{
dd ("caught " + ex + " while nested");
}
/* execution pauses here until someone calls exitNestedEventLoop() */
clearCurrentFrame();
rv.value = ("currentException" in console) ? console.currentException : null;
delete console.frames;
delete console.trapType;
delete console.currentException;
$ = new Array();
dispatch ("hook-debug-continue");
if (tn)
display (getMsg(MSN_CONT, tn), MT_CONT);
return console._continueCodeStack.pop();
}
function eventLoopNested ()
{
window.focus();
window.getAttention();
dispatch ("hook-debug-stop");
}
function getCurrentFrame()
{
if ("frames" in console)
return console.frames[console._currentFrameIndex];
return null;
}
function getCurrentFrameIndex()
{
if (typeof console._currentFrameIndex == "undefined")
return -1;
return console._currentFrameIndex;
}
function setCurrentFrameByIndex (index)
{
if (!console.frames)
throw new BadMojo (ERR_NO_STACK);
ASSERT (index >= 0 && index < console.frames.length, "index out of range");
console._currentFrameIndex = index;
var cf = console.frames[console._currentFrameIndex];
dispatch ("set-eval-obj", { jsdValue: cf });
console.stopFile = (cf.isNative) ? MSG_URL_NATIVE : cf.script.fileName;
console.stopLine = cf.line;
delete console._pp_stopLine;
return cf;
}
function clearCurrentFrame ()
{
if (!console.frames)
throw new BadMojo (ERR_NO_STACK);
if (console.currentEvalObject instanceof jsdIStackFrame)
dispatch ("set-eval-obj", { jsdValue: console.jsdConsole });
delete console.stopLine;
delete console._pp_stopLine;
delete console.stopFile;
delete console._currentFrameIndex;
}
function formatArguments (v)
{
if (!v)
return "";
var ary = new Array();
var p = new Object();
v.getProperties (p, {});
p = p.value;
for (var i = 0; i < p.length; ++i)
{
if (p[i].flags & jsdIProperty.FLAG_ARGUMENT)
ary.push (getMsg(MSN_FMT_ARGUMENT,
[p[i].name.stringValue,
formatValue(p[i].value, FTYPE_SUMMARY)]));
}
return ary.join (MSG_COMMASP);
}
function formatFlags (flags)
{
var s = "";
if (flags & PROP_ENUMERATE)
s += MSG_VF_ENUMERABLE;
if (flags & PROP_READONLY)
s += MSG_VF_READONLY;
if (flags & PROP_PERMANENT)
s += MSG_VF_PERMANENT;
if (flags & PROP_ALIAS)
s += MSG_VF_ALIAS;
if (flags & PROP_ARGUMENT)
s += MSG_VF_ARGUMENT;
if (flags & PROP_VARIABLE)
s += MSG_VF_VARIABLE;
if (flags & PROP_ERROR)
s += MSG_VF_ERROR;
if (flags & PROP_EXCEPTION)
s += MSG_VF_EXCEPTION;
if (flags & PROP_HINTED)
s += MSG_VF_HINTED;
return s;
}
function formatProperty (p, formatType)
{
if (!p)
throw new BadMojo (ERR_REQUIRED_PARAM, "p");
var s = formatFlags (p.flags);
if (formatType == FTYPE_ARRAY)
{
var rv = formatValue (p.value, FTYPE_ARRAY);
return [p.name.stringValue, rv[1] ? rv[1] : rv[0], rv[2], s];
}
return getMsg(MSN_FMT_PROPERTY, [s, p.name.stringValue,
formatValue(p.value)]);
}
function formatScript (script)
{
if (!script)
throw new BadMojo (ERR_REQUIRED_PARAM, "script");
var functionName;
if (script.tag in console.scriptWrappers)
functionName = console.scriptWrappers[script.tag].functionName;
else
functionName = script.functionName;
return getMsg (MSN_FMT_SCRIPT, [functionName, script.fileName]);
}
function formatFrame (f)
{
if (!f)
throw new BadMojo (ERR_REQUIRED_PARAM, "f");
var url = (f.isNative) ? MSG_URL_NATIVE : f.script.fileName;
return getMsg (MSN_FMT_FRAME,
[f.functionName, formatArguments(f.scope), url, f.line]);
}
function formatValue (v, formatType)
{
if (!v)
throw new BadMojo (ERR_REQUIRED_PARAM, "v");
if (!(v instanceof jsdIValue))
throw new BadMojo (ERR_INVALID_PARAM, "v", String(v));
var type;
var value;
switch (v.jsType)
{
case jsdIValue.TYPE_BOOLEAN:
type = MSG_TYPE_BOOLEAN;
value = String(v.booleanValue);
break;
case jsdIValue.TYPE_DOUBLE:
type = MSG_TYPE_DOUBLE;
value = v.doubleValue;
break;
case jsdIValue.TYPE_INT:
type = MSG_TYPE_INT;
value = v.intValue;
break;
case jsdIValue.TYPE_FUNCTION:
type = MSG_TYPE_FUNCTION;
value = v.jsFunctionName;
break;
case jsdIValue.TYPE_NULL:
type = MSG_TYPE_NULL;
value = MSG_TYPE_NULL;
break;
case jsdIValue.TYPE_OBJECT:
if (formatType == FTYPE_STD)
{
type = MSG_TYPE_OBJECT;
value = getMsg(MSN_FMT_OBJECT, String(v.propertyCount));
}
else
{
if (v.jsClassName)
if (v.jsClassName == "XPCWrappedNative_NoHelper")
type = MSG_CLASS_XPCOBJ;
else
type = v.jsClassName;
else
type = MSG_TYPE_OBJECT;
value = "{" + String(v.propertyCount) + "}";
}
break;
case jsdIValue.TYPE_STRING:
type = MSG_TYPE_STRING;
var strval = v.stringValue;
if (strval.length > console.prefs["maxStringLength"])
strval = getMsg(MSN_FMT_LONGSTR, strval.length);
else
strval = strval.quote()
value = strval;
break;
case jsdIValue.TYPE_VOID:
type = MSG_TYPE_VOID;
value = MSG_TYPE_VOID;
break;
default:
type = MSG_TYPE_UNKNOWN;
value = MSG_TYPE_UNKNOWN;
break;
}
if (formatType == FTYPE_SUMMARY)
return getMsg (MSN_FMT_VALUE_SHORT, [type, value]);
var className;
if (v.jsClassName)
if (v.jsClassName == "XPCWrappedNative_NoHelper")
/* translate this long, unintuitive, and common class name into
* something more palatable. */
className = MSG_CLASS_XPCOBJ;
else
className = v.jsClassName;
if (formatType == FTYPE_ARRAY)
return [type, className, value];
if (className)
return getMsg (MSN_FMT_VALUE_LONG, [type, v.jsClassName, value]);
return getMsg (MSN_FMT_VALUE_MED, [type, value]);
}
function displayCallStack ()
{
for (var i = 0; i < console.frames.length; ++i)
displayFrame (console.frames[i], i);
}
function displayProperties (v)
{
if (!v)
throw new BadMojo (ERR_REQUIRED_PARAM, "v");
if (!(v instanceof jsdIValue))
throw new BadMojo (ERR_INVALID_PARAM, "v", String(v));
var p = new Object();
v.getProperties (p, {});
for (var i in p.value) display(formatProperty (p.value[i]), MT_EVAL_OUT);
}
function displaySourceContext (sourceText, line, contextLines)
{
function onSourceLoaded (status)
{
if (status == Components.results.NS_OK)
displaySourceContext (sourceText, line, contextLines);
}
if (sourceText.isLoaded)
{
for (var i = line - contextLines; i <= line + contextLines; ++i)
{
if (i > 0 && i < sourceText.lines.length)
{
var sourceLine;
if ("charset" in sourceText)
{
sourceLine = toUnicode(sourceText.lines[i - 1],
sourceText.charset);
}
else
{
sourceLine = sourceText.lines[i - 1];
}
display (getMsg(MSN_SOURCE_LINE, [zeroPad (i, 3), sourceLine]),
i == line ? MT_STEP : MT_SOURCE);
}
}
}
else
{
sourceText.loadSource (onSourceLoaded);
}
}
function displayFrame (jsdFrame, idx, showHeader, sourceContext)
{
if (typeof idx == "undefined")
{
for (idx = 0; idx < console.frames.length; ++idx)
if (jsdFrame == console.frames[idx])
break;
if (idx >= console.frames.length)
idx = MSG_VAL_UNKNOWN;
}
if (typeof showHeader == "undefined")
showHeader = true;
if (typeof sourceContext == "undefined")
sourceContext = null;
display(getMsg(MSN_FMT_FRAME_LINE, [idx, formatFrame(jsdFrame)]), MT_OUTPUT);
if (!jsdFrame.isNative && sourceContext != null)
{
var jsdScript = jsdFrame.script;
var scriptWrapper = getScriptWrapper(jsdScript);
if (!ASSERT(scriptWrapper, "Couldn't get a script wrapper"))
return;
if (console.prefs["prettyprint"] && jsdScript.isValid)
{
displaySourceContext (scriptWrapper.sourceText,
jsdScript.pcToLine(jsdFrame.pc,
PCMAP_PRETTYPRINT),
sourceContext);
}
else
{
displaySourceContext (scriptWrapper.scriptInstance.sourceText,
jsdFrame.line, sourceContext);
}
}
}
function getFutureBreakpoint (urlPattern, lineNumber)
{
var key = urlPattern + "#" + lineNumber;
if (key in console.fbreaks)
return console.fbreaks[key];
return null;
}
function setFutureBreakpoint (urlPattern, lineNumber, props)
{
var key = urlPattern + "#" + lineNumber;
if (key in console.fbreaks)
return false;
var url;
for (url in console.scriptManagers)
{
if (url == urlPattern)
console.scriptManagers[url].noteFutureBreakpoint(lineNumber, true);
}
for (url in console.files)
{
if (url == urlPattern)
console.files[url].noteFutureBreakpoint(lineNumber, true);
}
var fbreak = new FutureBreakpoint (urlPattern, lineNumber);
if (props)
fbreak.setProperties(props);
console.fbreaks[key] = fbreak;
dispatch ("hook-fbreak-set", { fbreak: fbreak });
return fbreak;
}
function clearFutureBreakpoint (urlPattern, lineNumber)
{
var key = urlPattern + "#" + lineNumber;
if (!(key in console.fbreaks))
return false;
var i;
var fbreak = console.fbreaks[key];
if ("propsWindow" in fbreak)
fbreak.propsWindow.close();
delete console.fbreaks[key];
for (i in fbreak.childrenBP)
fbreak.childrenBP[i].parentBP = null;
var url;
for (url in console.scriptManagers)
{
if (url.indexOf(urlPattern) != -1)
console.scriptManagers[url].noteFutureBreakpoint(lineNumber, false);
}
for (url in console.files)
{
if (url == urlPattern)
console.files[url].noteFutureBreakpoint(lineNumber, false);
}
dispatch ("hook-fbreak-clear", { fbreak: fbreak });
return true;
}
PK
q.T\O1 1 # content/venkman/venkman-profiler.jsUT %q>!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
function initProfiler ()
{
var prefs =
[
["profile.template.xml", "chrome://venkman/locale/profile.xml.tpl"],
["profile.template.html", "chrome://venkman/locale/profile.html.tpl"],
["profile.template.csv", "chrome://venkman/locale/profile.csv.tpl"],
["profile.template.txt", "chrome://venkman/locale/profile.txt.tpl"],
["profile.ranges.default", "1000000, 5000, 2500, 1000, 750, 500, " +
"250, 100, 75, 50, 25, 10, 7.5, 5, 2.5, 1, 0.75, 0.5, 0.25"]
];
console.prefManager.addPrefs(prefs);
}
function ProfileReport (reportTemplate, file, rangeList, scriptInstanceList)
{
this.reportTemplate = reportTemplate;
this.file = file;
this.rangeList = rangeList;
this.scriptInstanceList = scriptInstanceList;
this.key = "total";
}
console.profiler = new Object();
console.profiler.__defineSetter__ ("enabled", pro_setenable);
function pro_setenable(state)
{
if (state)
console.jsds.flags |= COLLECT_PROFILE_DATA;
else
console.jsds.flags &= ~COLLECT_PROFILE_DATA;
}
console.profiler.__defineGetter__ ("enabled", pro_getenable);
function pro_getenable(state)
{
return Boolean(console.jsds.flags & COLLECT_PROFILE_DATA);
}
console.profiler.summarizeScriptWrapper =
function pro_sumscript (scriptWrapper, key)
{
var ex;
try
{
var jsdScript = scriptWrapper.jsdScript;
if (!jsdScript.isValid)
return null;
var ccount = jsdScript.callCount;
if (!ccount)
return null;
var tot_ms = roundTo(jsdScript.totalExecutionTime, 2);
var min_ms = roundTo(jsdScript.minExecutionTime, 2);
var max_ms = roundTo(jsdScript.maxExecutionTime, 2);
var avg_ms = roundTo(jsdScript.totalExecutionTime / ccount, 2);
var recurse = jsdScript.maxRecurseDepth;
var summary = new Object();
summary.total = tot_ms;
summary.ccount = ccount;
summary.avg = avg_ms;
summary.min = min_ms;
summary.max = max_ms;
summary.recurse = recurse;
summary.url = jsdScript.fileName;
summary.file = getFileFromPath(summary.url);
summary.base = jsdScript.baseLineNumber;
summary.end = summary.base + jsdScript.lineExtent;
summary.fun = scriptWrapper.functionName;
summary.str = getMsg(MSN_FMT_PROFILE_STR,
[summary.fun, summary.base, summary.end, ccount,
(summary.recurse ?
getMsg(MSN_FMT_PROFILE_RECURSE, recurse) : ""),
tot_ms, min_ms, max_ms, avg_ms]);
summary.key = summary[key];
return summary;
}
catch (ex)
{
/* This function is called under duress, and the script representd
* by |s| may get collected at any point. When that happens,
* attempting to access to the profile data will throw this
* exception.
*/
if ("result" in ex &&
ex.result == Components.results.NS_ERROR_NOT_AVAILABLE)
{
display (getMsg(MSN_PROFILE_LOST, formatScript(jsdScript)), MT_WARN);
}
else
{
dd ("rethrow");
dd (dumpObjectTree(ex));
throw ex;
}
}
return null;
}
console.profiler.summarizeScriptInstance =
function pro_suminst (scriptInstance, key)
{
var summaryList = new Array();
var summary;
if (scriptInstance.topLevel)
summary = this.summarizeScriptWrapper (scriptInstance.topLevel, key);
if (summary)
summaryList.push (summary);
for (var f in scriptInstance.functions)
{
summary = this.summarizeScriptWrapper(scriptInstance.functions[f], key);
if (summary)
summaryList.push(summary);
}
return summaryList;
}
console.profiler.generateReportSection =
function pro_rptinst (profileReport, scriptInstance, sectionData)
{
function keyCompare (a, b)
{
if (a.key < b.key)
return 1;
if (a.key > b.key)
return -1;
return 0;
};
function scale(K, x) { return roundTo(K * x, 2); };
const MAX_WIDTH = 90;
var summaryList = this.summarizeScriptInstance (scriptInstance,
profileReport.key);
if (!summaryList.length)
return false;
summaryList = summaryList.sort(keyCompare);
var file = profileReport.file;
var reportTemplate = profileReport.reportTemplate;
var rangeList = profileReport.rangeList ? profileReport.rangeList : [1, 0];
var finalRangeIndex = rangeList.length - 1;
var previousRangeIndex;
var rangeIter = 0;
var rangeIndex = 0;
var K = 1;
var i;
if (typeof summaryList[0].key == "number")
{
for (i = 0; i < rangeList.length; ++i)
rangeList[i] = Number(rangeList[i]);
}
if ("sectionHeader" in reportTemplate)
{
file.write(replaceStrings(reportTemplate.sectionHeader,
sectionData));
}
for (i = 0; i < summaryList.length; ++i)
{
var summary = summaryList[i];
var rangeData;
while (summary.key &&
rangeIndex < finalRangeIndex &&
summary.key < rangeList[rangeIndex])
{
++rangeIndex;
}
if (previousRangeIndex != rangeIndex)
{
if (rangeIter > 0 && ("rangeFooter" in reportTemplate))
{
file.write(replaceStrings(reportTemplate.rangeFooter,
rangeData));
}
var maxRange = (rangeIndex > 0 ?
rangeList[rangeIndex - 1] : summary.key);
var minRange = (rangeIndex < finalRangeIndex ?
rangeList[rangeIndex + 1] : summary.key);
K = MAX_WIDTH / maxRange;
rangeData = {
"\\$range-min" : minRange,
"\\$range-max" : maxRange,
"\\$range-number-prev": rangeIter > 0 ? rangeIter - 1 : 0,
"\\$range-number-next": rangeIter + 1,
"\\$range-number" : rangeIter,
"__proto__" : sectionData
};
if ("rangeHeader" in reportTemplate)
{
file.write(replaceStrings(reportTemplate.rangeHeader,
rangeData));
}
previousRangeIndex = rangeIndex;
++rangeIter;
}
var summaryData = {
"\\$item-number-next": i + 1,
"\\$item-number-prev": i - 1,
"\\$item-number" : i,
"\\$item-name" : summary.url,
"\\$item-summary" : fromUnicode(summary.str, MSG_REPORT_CHARSET),
"\\$item-min-pct" : scale(K, summary.min),
"\\$item-below-pct" : scale(K, summary.avg - summary.min),
"\\$item-above-pct" : scale(K, summary.max - summary.avg),
"\\$max-time" : summary.max,
"\\$min-time" : summary.min,
"\\$avg-time" : summary.avg,
"\\$total-time" : summary.total,
"\\$call-count" : summary.ccount,
"\\$recurse-depth" : summary.recurse,
"\\$function-name" : fromUnicode(summary.fun, MSG_REPORT_CHARSET),
"\\$start-line" : summary.base,
"\\$end-line" : summary.end,
"__proto__" : rangeData
};
if ("itemBody" in reportTemplate)
file.write(replaceStrings(reportTemplate.itemBody, summaryData));
}
if ("rangeFooter" in reportTemplate)
{
/* close the final range */
file.write(replaceStrings(reportTemplate.rangeFooter,
rangeData));
}
if ("sectionFooter" in reportTemplate)
{
file.write(replaceStrings(reportTemplate.sectionFooter,
sectionData));
}
return true;
}
console.profiler.generateReport =
function pro_rptall (profileReport)
{
var profiler = this;
var sectionCount = 0;
function generateReportChunk (i)
{
/* we build the report in chunks, with setTimeouts in between,
* so the UI can come up for air. */
var scriptInstance = profileReport.scriptInstanceList[i];
var url = scriptInstance.url;
var sectionData = {
"\\$section-number-prev": (sectionCount > 0) ? sectionCount - 1 : 0,
"\\$section-number-next": sectionCount + 1,
"\\$section-number" : sectionCount,
"\\$section-link" : (url ? "" + url + "" : MSG_VAL_NA),
"\\$full-url" : url,
"\\$file-name" : getFileFromPath(url),
"__proto__" : reportData
};
var hadData = profiler.generateReportSection (profileReport,
scriptInstance,
sectionData);
if (++i == profileReport.scriptInstanceList.length)
{
if ("reportFooter" in reportTemplate)
file.write(replaceStrings(reportTemplate.reportFooter,
reportData));
if ("onComplete" in profileReport)
profileReport.onComplete(i);
}
else
{
if (hadData)
{
++sectionCount;
console.status = getMsg(MSN_PROFILE_SAVING, [i, last]);
setTimeout (generateReportChunk, 10, i);
}
else
{
generateReportChunk (i);
}
}
};
var reportData = {
"\\$report-charset": MSG_REPORT_CHARSET,
"\\$full-date" : String(Date()),
"\\$user-agent" : navigator.userAgent,
"\\$venkman-agent" : console.userAgent,
"\\$sort-key" : profileReport.key
};
var reportTemplate = profileReport.reportTemplate;
var file = profileReport.file;
if ("reportHeader" in reportTemplate)
file.write(replaceStrings(reportTemplate.reportHeader, reportData));
var length = profileReport.scriptInstanceList.length;
var last = length - 1;
generateReportChunk (0);
}
console.profiler.loadTemplate =
function pro_load (url)
{
var lines = loadURLNow(url);
if (!lines)
return null;
var sections = {
"reportHeader" : /@-section-start/mi,
"sectionHeader" : /@-range-start/mi,
"rangeHeader" : /@-item-start/mi,
"itemBody" : /@-item-end/mi,
"rangeFooter" : /@-range-end/mi,
"sectionFooter" : /@-section-end/mi,
"reportFooter" : 0
};
var reportTemplate = parseSections (lines, sections);
//dd(dumpObjectTree (reportTemplate));
return reportTemplate;
}
PK
k0!G"z "z ! content/venkman/venkman-jsdurl.jsUT JQ@!VDDUx /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The JavaScript Debugger
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation
* Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* Contributor(s):
* Robert Ginda, , original author
*
*/
const JSD_URL_SCHEME = "x-jsd:";
const JSD_URL_PREFIX = /x-jsd:/i;
const JSD_SCHEME_LEN = JSD_URL_SCHEME.length;
const JSD_SERVICE_HELP = "help";
const JSD_SERVICE_SOURCE = "source";
const JSD_SERVICE_PPRINT = "pprint";
const JSD_SERVICE_PPBUFFER = "ppbuffer";
function initJSDURL()
{
var prefs =
[
["services.help.css", "chrome://venkman/skin/venkman-help.css"],
["services.help.template", "chrome://venkman/locale/venkman-help.tpl"],
["services.source.css", "chrome://venkman/skin/venkman-source.css"],
["services.source.colorize", true],
["services.source.colorizeLimit", 1500]
];
console.prefManager.addPrefs(prefs);
}
/*
* x-jsd:[?[=[(&=) ...]]][#anchor]
*
* is one of...
*
* x-jsd:help - Help system
* properties are:
* search - text to search for
* within - bitmap of fields to search within
* 0x01 - search in command names
* 0x02 - search in ui labels
* 0x04 - search in help text
*
* x-jsd:source - Source text
* properties are:
* url - source url
* instance - index of source instance
*
* x-jsd:pprint - Pretty Printed source text
* properties are:
* script - tag of script to pretty print
*
* x-jsd:ppbuffer - URL of a function created internally for pretty printing.
* You may come across this in jsdIScript objects, but it
* should not be used elsewhere.
* properties are:
* type - "function" or "script"
*/
console.parseJSDURL = parseJSDURL;
function parseJSDURL (url)
{
var ary;
if (url.search(JSD_URL_PREFIX) != 0)
return null;
ary = url.substr(JSD_SCHEME_LEN).match(/([^?#]+)(?:\?(.*))?/);
if (!ary)
return null;
var parseResult = new Object();
parseResult.spec = url;
parseResult.service = ary[1].toLowerCase();
var rest = ary[2];
if (rest)
{
ary = rest.match(/([^]+)/);
while (ary)
{
rest = RegExp.rightContext.substr(1);
var assignment = ary[1];
ary = assignment.match(/(.+)=(.*)/);
if (ASSERT(ary, "error parsing ``" + assignment + "'' from " + url))
{
var name = decodeURIComponent(ary[1]);
/* only set the property the first time we see it */
if (arrayHasElementAt(ary, 2) && !(name in parseResult))
parseResult[name] = decodeURIComponent(ary[2]);
}
ary = rest.match(/([^]+)/);
}
}
//dd (dumpObjectTree(parseResult));
return parseResult;
}
console.loadServiceTemplate =
function con_loadservicetpl (name, sections, callback)
{
function onComplete (data, url, status)
{
if (status == Components.results.NS_OK)
{
var tpl = parseSections (data, sections);
for (var p in sections)
{
if (!(p in tpl))
{
display (getMsg (MSN_ERR_NO_SECTION, [sections[p], url]),
MT_ERROR);
callback(name, Components.results.NS_ERROR_FAILURE);
return;
}
}
console.serviceTemplates[name] = tpl;
}
callback(name, status);
};
if (name in console.serviceTemplates)
{
callback(name, Components.results.NS_OK);
return;
}
var prefName = "services." + name + ".template";
if (!(prefName in console.prefs))
{
display (getMsg (MSN_ERR_NO_TEMPLATE, prefName), MT_ERROR);
callback(name, Components.results.NS_ERROR_FILE_NOT_FOUND);
return;
}
var url = console.prefs[prefName];
loadURLAsync (url, { onComplete: onComplete });
}
console.asyncOpenJSDURL = asyncOpenJSDURL;
function asyncOpenJSDURL (channel, streamListener, context)
{
function onTemplateLoaded (name, status)
{
if (status != Components.results.NS_OK)
{
response.start();
response.append(getMsg(MSN_JSDURL_ERRPAGE,
[safeHTML(url),
getMsg(MSN_ERR_JSDURL_TEMPLATE, name)]));
response.end();
}
else
{
tryService();
}
};
function tryService ()
{
var serviceObject = console.services[service];
if ("requiredTemplates" in serviceObject)
{
for (var i = 0; i < serviceObject.requiredTemplates.length; ++i)
{
var def = serviceObject.requiredTemplates[i];
if (!(def[0] in console.serviceTemplates))
{
console.loadServiceTemplate (def[0], def[1],
onTemplateLoaded);
return;
}
}
}
console.services[service](response, parseResult);
};
var url = channel.URI.spec;
var response = new JSDResponse (channel, streamListener, context);
var parseResult = parseJSDURL (url);
if (!parseResult)
{
response.start();
response.append(getMsg(MSN_JSDURL_ERRPAGE, [safeHTML(url),
MSG_ERR_JSDURL_PARSE]));
response.end();
return;
}
var service = parseResult.service.toLowerCase();
if (!(service in console.services))
service = "unknown";
tryService();
}
console.serviceTemplates = new Object();
console.services = new Object();
console.services["unknown"] =
function svc_nosource (response, parsedURL)
{
response.start();
response.append(getMsg(MSN_JSDURL_ERRPAGE, [safeHTML(parsedURL.spec),
MSG_ERR_JSDURL_NOSERVICE]));
response.end();
}
console.services["ppbuffer"] =
function svc_nosource (response)
{
response.start();
response.append(getMsg(MSN_JSDURL_ERRPAGE, [safeHTML(parsedURL.spec),
MSG_ERR_JSDURL_NOSOURCE]));
response.end();
}
console.services["help"] =
function svc_help (response, parsedURL)
{
const CHUNK_DELAY = 100;
const CHUNK_SIZE = 150;
function processHelpChunk (start)
{
var stop = Math.min (commandList.length, start + CHUNK_SIZE);
for (var i = start; i < stop; ++i)
{
command = commandList[i];
if (!("htmlHelp" in command))
{
function replaceBold (str, p1)
{
return "" + p1 + "";
};
function replaceParam (str, p1)
{
return "<" + p1 + ">";
};
function replaceCommand (str, p1)
{
if (p1.indexOf(" ") != -1)
{
var ary = p1.split (" ");
for (var i = 0; i < ary.length; ++i)
{
ary[i] = replaceCommand (null, ary[i]);
}
return ary.join (" ");
}
if (p1 != command.name &&
(p1 in console.commandManager.commands))
{
return ("" + p1 + "");
}
return "" + p1 + "";
};
var htmlUsage = command.usage.replace(/<([^\s>]+)>/g,
replaceParam);
var htmlDesc = command.help.replace(/<([^\s>]+)>/g,
replaceParam);
htmlDesc = htmlDesc.replace (/\*([^\*]+)\*/g, replaceBold);
htmlDesc = htmlDesc.replace (/\|([^\|]+)\|/g, replaceCommand);
// remove trailing access key (non en-US locales) and ...
var trimmedLabel =
command.labelstr.replace(/(\([a-zA-Z]\))?(\.\.\.)?$/, "");
vars = {
"\\$command-name": command.name,
"\\$ui-label-safe": encodeURIComponent(trimmedLabel),
"\\$ui-label": fromUnicode(command.labelstr,
MSG_REPORT_CHARSET),
"\\$params": fromUnicode(htmlUsage, MSG_REPORT_CHARSET),
"\\$key": command.keystr,
"\\$desc": fromUnicode(htmlDesc, MSG_REPORT_CHARSET)
};
command.htmlHelp = replaceStrings (section, vars);
}
response.append(command.htmlHelp);
}
if (i != commandList.length)
{
setTimeout (processHelpChunk, CHUNK_DELAY, i);
}
else
{
response.append(tpl["footer"]);
response.end();
}
};
function compare (a, b)
{
if (parsedURL.within & WITHIN_LABEL)
{
a = a.labelstr.toLowerCase();
b = b.labelstr.toLowerCase();
}
else
{
a = a.name;
b = b.name;
}
if (a == b)
return 0;
if (a > b)
return 1;
return -1;
};
var command;
var commandList = new Array();
var hasSearched;
var tpl = console.serviceTemplates["help"];
var WITHIN_NAME = 0x01;
var WITHIN_LABEL = 0x02;
var WITHIN_DESC = 0x04;
if ("search" in parsedURL)
{
try
{
parsedURL.search = new RegExp (parsedURL.search, "i");
}
catch (ex)
{
response.start();
response.append(getMsg(MSN_JSDURL_ERRPAGE,
[parsedURL.spec, MSG_ERR_JSDURL_SEARCH]));
response.end();
return;
}
dd ("searching for " + parsedURL.search);
if (!("within" in parsedURL) ||
!((parsedURL.within = parseInt(parsedURL.within)) & 0x07))
{
parsedURL.within = WITHIN_NAME;
}
for (var c in console.commandManager.commands)
{
command = console.commandManager.commands[c];
if ((parsedURL.within & WITHIN_NAME) &&
command.name.search(parsedURL.search) != -1)
{
commandList.push (command);
}
else if ((parsedURL.within & WITHIN_LABEL) &&
command.labelstr.search(parsedURL.search) != -1)
{
commandList.push (command);
}
else if ((parsedURL.within & WITHIN_DESC) &&
command.help.search(parsedURL.search) != -1)
{
commandList.push (command);
}
}
hasSearched = commandList.length > 0 ? "true" : "false";
}
else
{
commandList = console.commandManager.list ("", CMD_CONSOLE);
hasSearched = "false";
}
commandList.sort(compare);
response.start();
var vars = {
"\\$css": console.prefs["services.help.css"],
"\\$match-count": commandList.length,
"\\$has-searched": hasSearched,
"\\$report-charset": MSG_REPORT_CHARSET
};
response.append(replaceStrings(tpl["header"], vars));
if (commandList.length == 0)
{
response.append(tpl["nomatch"]);
response.append(tpl["footer"]);
response.end();
}
else
{
var section = tpl["command"];
processHelpChunk(0)
}
}
console.services["help"].requiredTemplates =
[
["help", { "header" : /@-header-end/mi,
"command" : /@-command-end/mi,
"nomatch" : /@-nomatch-end/mi,
"footer" : 0 }
]
];
const OTHER = 0;
const COMMENT = 1;
const STRING1 = 2;
const STRING2 = 3;
const WORD = 4;
const NUMBER = 5;
var keywords = {
"abstract": 1, "boolean": 1, "break": 1, "byte": 1, "case": 1, "catch": 1,
"char": 1, "class": 1, "const": 1, "continue": 1, "debugger": 1,
"default": 1, "delete": 1, "do": 1, "double": 1, "else": 1, "enum": 1,
"export": 1, "export": 1, "extends": 1, "false": 1, "final": 1,
"finally": 1, "float": 1, "for": 1, "function": 1, "goto": 1, "if": 1,
"implements": 1, "import": 1, "in": 1, "instanceof": 1, "int": 1,
"interface": 1, "long": 1, "native": 1, "new": 1, "null": 1,
"package": 1, "private": 1, "protected": 1, "public": 1, "return": 1,
"short": 1, "static": 1, "switch": 1, "synchronized": 1, "this": 1,
"throw": 1, "throws": 1, "transient": 1, "true": 1, "try": 1,
"typeof": 1, "var": 1, "void": 1, "while": 1, "with": 1
};
var specialChars = /[&<>]/g;
var wordStart = /[\w\\\$]/;
var numberStart = /[\d]/;
var otherEnd = /[\w\$\"\']|\\|\/\/|\/\*/;
var wordEnd = /[^\w\$]/;
var string1End = /\'/;
var string2End = /\"/;
var commentEnd = /\*\//;
var numberEnd = /[^\d\.]/;
function escapeSpecial (p1)
{
switch (p1)
{
case "&":
return "&";
case "<":
return "<";
case ">":
return ">";
}
return p1;
};
function escapeSourceLine (line)
{
return { line: line.replace (specialChars, escapeSpecial),
previousState: 0 };
}
function colorizeSourceLine (line, previousState)
{
function closePhrase (phrase)
{
if (!phrase)
{
previousState = OTHER;
return;
}
switch (previousState)
{
case COMMENT:
result += "" + phrase.replace (specialChars, escapeSpecial) +
"";
break;
case STRING1:
case STRING2:
result += "" + phrase.replace (specialChars, escapeSpecial) +
"";
break;
case WORD:
if (phrase in keywords)
result += "" + phrase + "";
else
result += phrase.replace (specialChars, escapeSpecial);
break;
case OTHER:
phrase = phrase.replace (specialChars, escapeSpecial);
/* fall through */
case NUMBER:
result += phrase;
break;
}
};
var result = "";
var pos;
var ch, ch2;
var expr;
while (line.length > 0)
{
/* scan a line of text. |pos| always one *past* the end of the
* phrase we just scanned. */
switch (previousState)
{
case OTHER:
/* look for the end of an uncalssified token, like whitespace
* or an operator. */
pos = line.search (otherEnd);
break;
case WORD:
/* look for the end of something that qualifies as
* an identifier. */
pos = line.search(wordEnd);
while (pos > -1 && line[pos] == "\\")
{
/* if we ended with a \ character, then the slash
* and the character after it are part of this word.
* the characters following may also be part of the
* word. */
pos += 2;
var newPos = line.substr(pos).search(wordEnd);
if (newPos > -1)
pos += newPos;
}
break;
case STRING1:
case STRING2:
/* look for the end of a single or double quoted string. */
if (previousState == STRING1)
{
ch = "'";
expr = string1End;
}
else
{
ch = "\"";
expr = string2End;
}
if (line[0] == ch)
{
pos = 1;
}
else
{
pos = line.search (expr);
if (pos > 0 && line[pos - 1] == "\\")
{
/* arg, the quote we found was escaped, fall back
* to scanning a character at a time. */
var done = false;
for (pos = 0; !done && pos < line.length; ++pos)
{
if (line[pos] == "\\")
++pos;
else if (line[pos] == ch)
done = true;
}
}
else
{
if (pos != -1)
++pos;
}
}
break;
case COMMENT:
/* look for the end of a slash-star comment,
* slash-slash comments are handled down below, because
* we know for sure that it's the last phrase on this line.
*/
pos = line.search (commentEnd);
if (pos != -1)
pos += 2;
break;
case NUMBER:
/* look for the end of a number */
pos = line.search (numberEnd);
break;
}
if (pos == -1)
{
/* couldn't find an end for the current state, close out the
* rest of the line.
*/
closePhrase(line);
line = "";
}
else
{
/* pos has a non -1 value, close out what we found, and move
* along. */
if (previousState == STRING1 || previousState == STRING2)
{
/* strings are a special case because they actually are
* considered to start *after* the leading quote,
* and they end *before* the trailing quote. */
if (pos == 1)
{
/* empty string */
previousState = OTHER;
}
else
{
/* non-empty string, close out the contents of the
* string. */
closePhrase(line.substr (0, pos - 1));
previousState = OTHER;
}
/* close the trailing quote. */
result += line[pos - 1];
}
else
{
/* non-string phrase, close the whole deal. */
closePhrase(line.substr (0, pos));
previousState = OTHER;
}
if (pos)
line = line.substr (pos);
}
if (line)
{
/* figure out what the next token looks like. */
ch = line[0];
ch2 = (line.length > 1) ? line[1] : "";
if (ch.search (wordStart) == 0)
{
previousState = WORD;
}
else if (ch == "'")
{
result += "'";
line = line.substr(1);
previousState = STRING1;
}
else if (ch == "\"")
{
result += "\"";
line = line.substr(1);
previousState = STRING2;
}
else if (ch == "/" && ch2 == "*")
{
previousState = COMMENT;
}
else if (ch == "/" && ch2 == "/")
{
/* slash-slash comment, the last thing on this line. */
previousState = COMMENT;
closePhrase(line);
previousState = OTHER;
line = "";
}
else if (ch.search (numberStart) == 0)
{
previousState = NUMBER;
}
}
}
return { previousState: previousState, line: result };
}
console.respondWithSourceText =
function con_respondsourcetext (response, sourceText)
{
const CHUNK_DELAY = 50;
const CHUNK_SIZE = 250;
var sourceLines = sourceText.lines;
var resultSource;
var tenSpaces = " ";
var maxDigits;
var previousState = 0;
var mungeLine;
if (console.prefs["services.source.colorize"] &&
sourceLines.length <= console.prefs["services.source.colorizeLimit"])
{
mungeLine = colorizeSourceLine;
}
else
{
mungeLine = escapeSourceLine;
}
function processSourceChunk (start)
{
dd ("processSourceChunk " + start + " {");
var stop = Math.min (sourceLines.length, start + CHUNK_SIZE);
for (var i = start; i < stop; ++i)
{
var padding;
if (i != 999)
{
padding =
tenSpaces.substr(0, maxDigits -
Math.floor(Math.log(i + 1) / Math.LN10));
}
else
{
/* at exactly 1000, a rounding error gets us. */
padding = tenSpaces.substr(0, maxDigits - 3);
}
var isExecutable;
var marginContent;
if ("lineMap" in sourceText && i in sourceText.lineMap)
{
if (sourceText.lineMap[i] & LINE_BREAKABLE)
{
isExecutable = "t";
marginContent = " - ";
}
else
{
isExecutable = "f";
marginContent = " ";
}
}
else
{
isExecutable = "f";
marginContent = " ";
}
var o = mungeLine(sourceLines[i], previousState);
var line = o.line;
previousState = o.previousState;
resultSource += "" +
marginContent + "" +
"" + padding + (i + 1) +
" " + line + "\n";
}
if (i != sourceLines.length)
{
setTimeout (processSourceChunk, CHUNK_DELAY, i);
}
else
{
resultSource += "";
//resultSource += "