зеркало из https://github.com/mozilla/gecko-dev.git
1159 строки
32 KiB
JavaScript
1159 строки
32 KiB
JavaScript
/* -*- 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, <rginda@netscape.com>, original author
|
|
*
|
|
*/
|
|
|
|
const CMD_CONSOLE = 0x01; // command is available via the console
|
|
const CMD_NEED_STACK = 0x02; // command only works if we're stopped
|
|
const CMD_NO_STACK = 0x04; // command only works if we're *not* stopped
|
|
const CMD_NO_HELP = 0x08; // don't whine if there is no help for this command
|
|
|
|
function initCommands(commandObject)
|
|
{
|
|
console.commandManager = new CommandManager();
|
|
|
|
CommandManager.contextFunction = getCommandContext;
|
|
|
|
var cmdary =
|
|
[/* "real" commands */
|
|
["break", cmdBreak, CMD_CONSOLE],
|
|
["bp-props", cmdBPProps, 0],
|
|
["chrome-filter", cmdChromeFilter, CMD_CONSOLE],
|
|
["clear", cmdClear, CMD_CONSOLE],
|
|
["clear-all", cmdClearAll, CMD_CONSOLE],
|
|
["clear-profile", cmdClearProfile, CMD_CONSOLE],
|
|
["clear-script", cmdClearScript, 0],
|
|
["close", cmdClose, CMD_CONSOLE],
|
|
["commands", cmdCommands, CMD_CONSOLE],
|
|
["cont", cmdCont, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["emode", cmdEMode, CMD_CONSOLE],
|
|
["eval", cmdEval, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["evald", cmdEvald, CMD_CONSOLE],
|
|
["fbreak", cmdFBreak, CMD_CONSOLE],
|
|
["find-bp", cmdFindBp, 0],
|
|
["find-creator", cmdFindCreatorOrCtor, 0],
|
|
["find-ctor", cmdFindCreatorOrCtor, 0],
|
|
["find-file", cmdFindFile, CMD_CONSOLE],
|
|
["find-frame", cmdFindFrame, CMD_NEED_STACK],
|
|
["find-url", cmdFindURL, CMD_CONSOLE],
|
|
["find-url-soft", cmdFindURL, 0],
|
|
["find-script", cmdFindScript, 0],
|
|
["finish", cmdFinish, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["focus-input", cmdFocusInput, 0],
|
|
["frame", cmdFrame, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["help", cmdHelp, CMD_CONSOLE],
|
|
["loadd", cmdLoadd, CMD_CONSOLE],
|
|
["next", cmdNext, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["open-dialog", cmdOpenDialog, CMD_CONSOLE],
|
|
["open-url", cmdOpenURL, 0],
|
|
["pprint", cmdPPrint, CMD_CONSOLE],
|
|
["pref", cmdPref, CMD_CONSOLE],
|
|
["profile", cmdProfile, CMD_CONSOLE],
|
|
["props", cmdProps, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["propsd", cmdPropsd, CMD_CONSOLE],
|
|
["quit", cmdQuit, CMD_CONSOLE],
|
|
["reload", cmdReload, CMD_CONSOLE],
|
|
["save-source", cmdSaveSource, CMD_CONSOLE],
|
|
["save-profile", cmdSaveProfile, CMD_CONSOLE],
|
|
["scope", cmdScope, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["startup-init", cmdStartupInit, CMD_CONSOLE],
|
|
["step", cmdStep, CMD_CONSOLE | CMD_NEED_STACK],
|
|
["stop", cmdStop, CMD_CONSOLE | CMD_NO_STACK],
|
|
["tmode", cmdTMode, CMD_CONSOLE],
|
|
["version", cmdVersion, CMD_CONSOLE],
|
|
["where", cmdWhere, CMD_CONSOLE | CMD_NEED_STACK],
|
|
|
|
/* aliases */
|
|
["profile-tb", "profile toggle", CMD_CONSOLE],
|
|
["this", "props this", CMD_CONSOLE],
|
|
["toggle-chrome", "chrome-filter toggle", 0],
|
|
["toggle-ias", "startup-init toggle", 0],
|
|
["toggle-profile", "profile toggle", 0],
|
|
["em-cycle", "emode cycle", 0],
|
|
["em-ignore", "emode ignore", 0],
|
|
["em-trace", "emode trace", 0],
|
|
["em-break", "emode break", 0],
|
|
["tm-cycle", "tmode cycle", 0],
|
|
["tm-ignore", "tmode ignore", 0],
|
|
["tm-trace", "tmode trace", 0],
|
|
["tm-break", "tmode break", 0]
|
|
];
|
|
|
|
defineVenkmanCommands (cmdary);
|
|
|
|
console.commandManager.argTypes.__aliasTypes__ (["index", "breakpointIndex",
|
|
"lineNumber"], "int");
|
|
console.commandManager.argTypes.__aliasTypes__ (["scriptText", "windowFlags",
|
|
"expression", "prefValue"],
|
|
"rest");
|
|
}
|
|
|
|
/**
|
|
* Defines commands stored in |cmdary| on the venkman command manager. Expects
|
|
* to find "properly named" strings for the commands via getMsg().
|
|
*/
|
|
function defineVenkmanCommands (cmdary)
|
|
{
|
|
var cm = console.commandManager;
|
|
var len = cmdary.length;
|
|
for (var i = 0; i < len; ++i)
|
|
{
|
|
var name = cmdary[i][0];
|
|
var func = cmdary[i][1];
|
|
var flags = cmdary[i][2];
|
|
var usage = getMsg("cmd." + name + ".params", null, "");
|
|
|
|
var helpDefault;
|
|
var labelDefault = name;
|
|
var aliasFor;
|
|
if (flags & CMD_NO_HELP)
|
|
helpDefault = MSG_NO_HELP;
|
|
|
|
if (typeof func == "string")
|
|
{
|
|
var ary = func.match(/(\S+)/);
|
|
if (ary)
|
|
aliasFor = ary[1];
|
|
helpDefault = getMsg (MSN_DEFAULT_ALIAS_HELP, func);
|
|
labelDefault = getMsg ("cmd." + aliasFor + ".label", null, name);
|
|
}
|
|
|
|
var label = getMsg("cmd." + name + ".label", null, labelDefault);
|
|
var help = getMsg("cmd." + name + ".help", null, helpDefault);
|
|
var command = new CommandRecord (name, func, usage, help, label, flags);
|
|
cm.addCommand(command);
|
|
|
|
var key = getMsg ("cmd." + name + ".key", null, "");
|
|
if (key)
|
|
cm.setKey("dynamicKeys", command, key);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Used as CommandManager.contextFunction.
|
|
*/
|
|
function getCommandContext (id, cx)
|
|
{
|
|
switch (id)
|
|
{
|
|
case "popup:project":
|
|
cx = console.projectView.getContext(cx);
|
|
break;
|
|
|
|
case "popup:source":
|
|
cx = console.sourceView.getContext(cx);
|
|
break;
|
|
|
|
case "popup:script":
|
|
cx = console.scriptsView.getContext(cx);
|
|
break;
|
|
|
|
case "popup:stack":
|
|
cx = console.stackView.getContext(cx);
|
|
break;
|
|
|
|
default:
|
|
dd ("getCommandContext: unknown id '" + id + "'");
|
|
|
|
case "mainmenu:file-popup":
|
|
case "mainmenu:view-popup":
|
|
case "mainmenu:debug-popup":
|
|
case "mainmenu:profile-popup":
|
|
case "popup:console":
|
|
cx = {
|
|
commandManager: console.commandManager,
|
|
contextSource: "default"
|
|
};
|
|
break;
|
|
}
|
|
|
|
if (typeof cx == "object")
|
|
{
|
|
cx.commandManager = console.commandManager;
|
|
if (!("contextSource" in cx))
|
|
cx.contextSource = id;
|
|
if ("dbgContexts" in console && console.dbgContexts)
|
|
dd ("context '" + id + "'\n" + dumpObjectTree(cx));
|
|
}
|
|
|
|
return cx;
|
|
}
|
|
|
|
/**
|
|
* Used as a callback for CommandRecord.getDocumentation() to format the command
|
|
* flags for the "Notes:" field.
|
|
*/
|
|
function formatCommandFlags (f)
|
|
{
|
|
var ary = new Array();
|
|
if (f & CMD_CONSOLE)
|
|
ary.push(MSG_NOTE_CONSOLE);
|
|
if (f & CMD_NEED_STACK)
|
|
ary.push(MSG_NOTE_NEEDSTACK);
|
|
if (f & CMD_NO_STACK)
|
|
ary.push(MSG_NOTE_NOSTACK);
|
|
|
|
return ary.length ? ary.join ("\n") : MSG_VAL_NA;
|
|
}
|
|
|
|
/********************************************************************************
|
|
* Command implementations from here on down...
|
|
*******************************************************************************/
|
|
|
|
function cmdBreak (e)
|
|
{
|
|
var i;
|
|
var bpr;
|
|
|
|
if (!e.fileName)
|
|
{ /* if no input data, just list the breakpoints */
|
|
var bplist = console.breakpoints.childData;
|
|
|
|
if (bplist.length == 0)
|
|
{
|
|
display (MSG_NO_BREAKPOINTS_SET);
|
|
return true;
|
|
}
|
|
|
|
display (getMsg(MSN_BP_HEADER, bplist.length));
|
|
for (i = 0; i < bplist.length; ++i)
|
|
{
|
|
bpr = bplist[i];
|
|
feedback (e, getMsg(MSN_BP_LINE, [i, bpr.fileName, bpr.line,
|
|
bpr.scriptMatches]));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
var matchingFiles = matchFileName (e.fileName);
|
|
if (matchingFiles.length == 0)
|
|
{
|
|
feedback (e, getMsg(MSN_ERR_BP_NOSCRIPT, e.fileName), MT_ERROR);
|
|
return false;
|
|
}
|
|
|
|
for (i in matchingFiles)
|
|
{
|
|
bpr = setBreakpoint (matchingFiles[i], e.lineNumber);
|
|
if (bpr)
|
|
feedback (e, getMsg(MSN_BP_CREATED, [bpr.fileName, bpr.line,
|
|
bpr.scriptMatches]));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdBPProps (e)
|
|
{
|
|
dd ("command bp-props");
|
|
}
|
|
|
|
function cmdChromeFilter (e)
|
|
{
|
|
var currentState = console.prefs["enableChromeFilter"];
|
|
|
|
if (e.toggle != null)
|
|
{
|
|
if (e.toggle == "toggle")
|
|
e.toggle = !currentState;
|
|
|
|
if (e.toggle != currentState)
|
|
{
|
|
if (e.toggle)
|
|
console.jsds.insertFilter (console.chromeFilter, null);
|
|
else
|
|
console.jsds.removeFilter (console.chromeFilter);
|
|
}
|
|
|
|
console.scriptsView.freeze();
|
|
for (var container in console.scripts)
|
|
{
|
|
if (console.scripts[container].fileName.indexOf("chrome:") == 0)
|
|
{
|
|
var rec = console.scripts[container];
|
|
var scriptList = console.scriptsView.childData;
|
|
if (e.toggle)
|
|
{
|
|
/* filter is on, remove chrome file from scripts view */
|
|
if ("parentRecord" in rec)
|
|
{
|
|
//dd ("remove index " + rec.childIndex + ", " +
|
|
// rec.fileName);
|
|
scriptList.removeChildAtIndex(rec.childIndex);
|
|
}
|
|
else
|
|
dd ("record already seems to out of the tree");
|
|
}
|
|
else
|
|
{
|
|
/* filter is off, add chrome file to scripts view */
|
|
if (!("parentRecord" in rec))
|
|
{
|
|
//dd ("cmdChromeFilter: append " +
|
|
// tov_formatRecord(rec, ""));
|
|
scriptList.appendChild(rec);
|
|
}
|
|
else
|
|
dd ("record already seems to be in the tree");
|
|
}
|
|
}
|
|
}
|
|
console.scriptsView.thaw();
|
|
|
|
currentState =
|
|
console.enableChromeFilter =
|
|
console.prefs["enableChromeFilter"] = e.toggle;
|
|
}
|
|
|
|
feedback (e, getMsg(MSN_CHROME_FILTER,
|
|
currentState ? MSG_VAL_ON : MSG_VAL_OFF));
|
|
}
|
|
|
|
function cmdClear (e)
|
|
{
|
|
if ("breakpointIndexList" in e && e.breakpointIndexList.length > 0)
|
|
{
|
|
var ev = new Object();
|
|
if ("isInteractive" in e)
|
|
ev.isInteractive = true;
|
|
e.breakpointIndexList.sort();
|
|
for (var i = e.breakpointIndexList.length - 1; i >= 0 ; --i)
|
|
{
|
|
ev.breakpointIndex = e.breakpointIndexList[i];
|
|
cmdClear(ev);
|
|
}
|
|
return;
|
|
}
|
|
|
|
var bpr = clearBreakpointByNumber (e.breakpointIndex);
|
|
if (bpr)
|
|
feedback (e, getMsg(MSN_BP_CLEARED, [bpr.fileName, bpr.line,
|
|
bpr.scriptMatches]));
|
|
}
|
|
|
|
function cmdClearAll(e)
|
|
{
|
|
for (var i = console.breakpoints.childData.length - 1; i >= 0; --i)
|
|
clearBreakpointByNumber (i);
|
|
}
|
|
|
|
function cmdClearProfile(e)
|
|
{
|
|
if ("scriptRecList" in e)
|
|
{
|
|
for (var i = 0; i < e.scriptRecList.length; ++i)
|
|
e.scriptRecList[i].script.clearProfileData();
|
|
}
|
|
else if ("scriptRec" in e)
|
|
{
|
|
e.scriptRec.script.clearProfileData();
|
|
}
|
|
else
|
|
{
|
|
console.jsds.clearProfileData();
|
|
}
|
|
|
|
feedback (e, MSG_PROFILE_CLEARED);
|
|
}
|
|
|
|
function cmdClearScript (e)
|
|
{
|
|
var i;
|
|
|
|
if ("scriptRecList" in e)
|
|
{
|
|
for (i = 0; i < e.scriptRecList.length; ++i)
|
|
cmdClearScript ({scriptRec: e.scriptRecList[i]});
|
|
return true;
|
|
}
|
|
|
|
/* walk backwards so as not to disturb the indicies */
|
|
for (i = console.breakpoints.childData.length - 1; i >= 0; --i)
|
|
{
|
|
var bpr = console.breakpoints.childData[i];
|
|
if (bpr.hasScriptRecord(e.scriptRec))
|
|
clearBreakpointByNumber (i);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdClose()
|
|
{
|
|
window.close();
|
|
}
|
|
|
|
function cmdCommands (e)
|
|
{
|
|
display (MSG_TIP_HELP);
|
|
var names = console.commandManager.listNames(e.pattern, CMD_CONSOLE);
|
|
names = names.join(MSG_COMMASP);
|
|
|
|
if (e.pattern)
|
|
display (getMsg(MSN_CMDMATCH, [e.pattern, "[" + names + "]"]));
|
|
else
|
|
display (getMsg(MSN_CMDMATCH_ALL, "[" + names + "]"));
|
|
return true;
|
|
}
|
|
|
|
function cmdCont (e)
|
|
{
|
|
disableDebugCommands();
|
|
console.stackView.saveState();
|
|
console.jsds.exitNestedEventLoop();
|
|
}
|
|
|
|
function cmdEMode (e)
|
|
{
|
|
if (e.mode != null)
|
|
{
|
|
e.mode = e.mode.toLowerCase();
|
|
|
|
if (e.mode == "cycle")
|
|
{
|
|
switch (console.errorMode)
|
|
{
|
|
case EMODE_IGNORE:
|
|
e.mode = "trace";
|
|
break;
|
|
case EMODE_TRACE:
|
|
e.mode = "break";
|
|
break;
|
|
case EMODE_BREAK:
|
|
e.mode = "ignore";
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (e.mode)
|
|
{
|
|
case "ignore":
|
|
console.errorMode = EMODE_IGNORE;
|
|
break;
|
|
case "trace":
|
|
console.errorMode = EMODE_TRACE;
|
|
break;
|
|
case "break":
|
|
console.errorMode = EMODE_BREAK;
|
|
break;
|
|
default:
|
|
display (getMsg(MSN_ERR_INVALID_PARAM, ["mode", e.mode]),
|
|
MT_ERROR);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
switch (console.errorMode)
|
|
{
|
|
case EMODE_IGNORE:
|
|
display (MSG_EMODE_IGNORE);
|
|
break;
|
|
case EMODE_TRACE:
|
|
display (MSG_EMODE_TRACE);
|
|
break;
|
|
case EMODE_BREAK:
|
|
display (MSG_EMODE_BREAK);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdEval (e)
|
|
{
|
|
display (e.scriptText, MT_FEVAL_IN);
|
|
var rv = evalInTargetScope (e.scriptText);
|
|
if (typeof rv != "undefined")
|
|
{
|
|
if (rv != null)
|
|
{
|
|
refreshValues();
|
|
var l = $.length;
|
|
$[l] = rv;
|
|
|
|
display (getMsg(MSN_FMT_TMP_ASSIGN, [l, formatValue (rv)]),
|
|
MT_FEVAL_OUT);
|
|
}
|
|
else
|
|
dd ("evalInTargetScope returned null");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function cmdEvald (e)
|
|
{
|
|
display (e.scriptText, MT_EVAL_IN);
|
|
var rv = evalInDebuggerScope (e.scriptText);
|
|
if (typeof rv != "undefined")
|
|
display (String(rv), MT_EVAL_OUT);
|
|
return true;
|
|
}
|
|
|
|
function cmdFBreak(e)
|
|
{
|
|
if (!e.fileName)
|
|
{ /* if no input data, just list the breakpoints */
|
|
var bplist = console.breakpoints.childData;
|
|
|
|
if (bplist.length == 0)
|
|
{
|
|
display (MSG_NO_FBREAKS_SET);
|
|
return true;
|
|
}
|
|
|
|
display (getMsg(MSN_FBP_HEADER, bplist.length));
|
|
for (var i = 0; i < bplist.length; ++i)
|
|
{
|
|
var bpr = bplist[i];
|
|
if (bpr.scriptMatches == 0)
|
|
display (getMsg(MSN_FBP_LINE, [i, bpr.fileName, bpr.line]));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (setFutureBreakpoint (e.fileName, e.lineNumber))
|
|
feedback (e, getMsg(MSN_FBP_CREATED, [e.fileName, e.lineNumber]));
|
|
return true;
|
|
}
|
|
|
|
function cmdFinish (e)
|
|
{
|
|
if (console.frames.length == 1)
|
|
return cmdCont();
|
|
|
|
console._stepOverLevel = 1;
|
|
setStopState(false);
|
|
console.jsds.functionHook = console._callHook;
|
|
disableDebugCommands()
|
|
console.stackView.saveState();
|
|
console.jsds.exitNestedEventLoop();
|
|
return true;
|
|
}
|
|
|
|
function cmdFindBp (e)
|
|
{
|
|
return dispatch ("find-url", {url: e.breakpointRec.fileName,
|
|
rangeStart: e.breakpointRec.line,
|
|
rangeEnd: e.breakpointRec.line});
|
|
}
|
|
|
|
function cmdFindCreatorOrCtor (e)
|
|
{
|
|
var objVal = e.jsdValue.objectValue;
|
|
if (!objVal)
|
|
{
|
|
display (MSG_NOT_AN_OBJECT, MT_ERROR);
|
|
return false;
|
|
}
|
|
|
|
var name = e.command.name;
|
|
var url;
|
|
var line;
|
|
if (name == "find-creator")
|
|
{
|
|
url = objVal.creatorURL;
|
|
line = objVal.creatorLine;
|
|
}
|
|
else
|
|
{
|
|
url = objVal.constructorURL;
|
|
line = objVal.constructorLine;
|
|
}
|
|
|
|
return dispatch ("find-url",
|
|
{url: url, rangeStart: line - 1, rangeEnd: line - 1});
|
|
}
|
|
|
|
function cmdFindURL (e)
|
|
{
|
|
if (!e.url)
|
|
{
|
|
console.sourceView.displaySourceText(null);
|
|
return null;
|
|
}
|
|
|
|
var sourceText;
|
|
|
|
if (e.url.indexOf("x-jsd:") == 0)
|
|
{
|
|
if (e.url == "x-jsd:help")
|
|
{
|
|
dispatch ("help");
|
|
return e.url;
|
|
}
|
|
|
|
display (getMsg(MSN_ERR_INVALID_PARAM, ["url", e.url]), MT_ERROR);
|
|
return null;
|
|
}
|
|
|
|
if (e.url in console.scripts)
|
|
sourceText = console.scripts[e.url].sourceText;
|
|
else if (e.url in console.files)
|
|
sourceText = console.files[e.url];
|
|
else
|
|
sourceText = console.files[e.url] = new SourceText (null, e.url);
|
|
|
|
console.sourceView.details = null;
|
|
console.highlightFile = e.url;
|
|
var line = 1;
|
|
delete console.highlightStart;
|
|
delete console.highlightEnd;
|
|
if ("rangeStart" in e && e.rangeStart != null)
|
|
{
|
|
line = e.rangeStart;
|
|
if (e.rangeEnd != null)
|
|
{
|
|
console.highlightStart = e.rangeStart - 1;
|
|
console.highlightEnd = e.rangeEnd - 1;
|
|
}
|
|
}
|
|
|
|
if ("lineNumber" in e && e.lineNumber != null)
|
|
line = e.lineNumber;
|
|
|
|
console.sourceView.displaySourceText(sourceText);
|
|
console.sourceView.tree.invalidate();
|
|
if ("command" in e && e.command.name == "find-url-soft")
|
|
console.sourceView.softScrollTo (line);
|
|
else
|
|
console.sourceView.scrollTo (line - 2, -1);
|
|
return e.url;
|
|
}
|
|
|
|
function cmdFindFile (e)
|
|
{
|
|
if (!e.fileName || e.fileName == "?")
|
|
{
|
|
var rv = pickOpen(MSG_OPEN_FILE, "$all");
|
|
if (rv.reason == PICK_CANCEL)
|
|
return null;
|
|
e.fileName = rv.file;
|
|
}
|
|
|
|
return dispatch ("find-url", {url: getURLSpecFromFile (e.fileName)});
|
|
}
|
|
|
|
function cmdFindFrame (e)
|
|
{
|
|
var frame = e.frameRec.frame;
|
|
|
|
displayFrame (frame, e.frameRec.childIndex, true);
|
|
|
|
if (frame.isNative)
|
|
return true;
|
|
|
|
var scriptContainer = console.scripts[frame.script.fileName];
|
|
if (!scriptContainer)
|
|
{
|
|
dd ("frame from unknown source");
|
|
return false;
|
|
}
|
|
var scriptRecord =
|
|
scriptContainer.locateChildByScript (frame.script);
|
|
if (!scriptRecord)
|
|
{
|
|
dd ("frame with unknown script");
|
|
return false;
|
|
}
|
|
|
|
return cmdFindScript ({scriptRec: scriptRecord});
|
|
}
|
|
|
|
function cmdFindScript (e)
|
|
{
|
|
var rv;
|
|
|
|
if (console.sourceView.prettyPrint)
|
|
{
|
|
delete console.highlightFile;
|
|
delete console.highlightStart;
|
|
delete console.highlightEnd;
|
|
console.sourceView.displaySourceText(e.scriptRec.sourceText);
|
|
rv = e.scriptRec.script.fileName;
|
|
}
|
|
else
|
|
{
|
|
rv = dispatch("find-url", {url: e.scriptRec.parentRecord.fileName,
|
|
rangeStart: e.scriptRec.baseLineNumber,
|
|
rangeEnd: e.scriptRec.baseLineNumber +
|
|
e.scriptRec.lineExtent - 1});
|
|
}
|
|
|
|
console.sourceView.details = e.scriptRec;
|
|
|
|
return rv;
|
|
}
|
|
|
|
function cmdFocusInput (e)
|
|
{
|
|
console.ui["sl-input"].focus();
|
|
}
|
|
|
|
function cmdFrame (e)
|
|
{
|
|
if (e.frameIndex != null)
|
|
setCurrentFrameByIndex(e.frameIndex);
|
|
else
|
|
e.frameIndex = getCurrentFrameIndex();
|
|
|
|
dispatch ("find-frame",
|
|
{frameRec: console.stackView.stack.childData[e.frameIndex]});
|
|
return true;
|
|
}
|
|
|
|
function cmdHelp (e)
|
|
{
|
|
var ary;
|
|
if (!e.pattern)
|
|
{
|
|
console.sourceView.displaySourceText(console.sourceText);
|
|
}
|
|
else
|
|
{
|
|
ary = console.commandManager.list (e.pattern, CMD_CONSOLE);
|
|
|
|
if (ary.length == 0)
|
|
{
|
|
display (getMsg(MSN_ERR_NO_COMMAND, e.pattern), MT_ERROR);
|
|
return false;
|
|
}
|
|
|
|
for (var i in ary)
|
|
{
|
|
display (getMsg(MSN_FMT_USAGE, [ary[i].name, ary[i].usage]),
|
|
MT_USAGE);
|
|
display (ary[i].help, MT_HELP);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdLoadd (e)
|
|
{
|
|
var ex;
|
|
|
|
if (!("_loader" in console))
|
|
{
|
|
const LOADER_CTRID = "@mozilla.org/moz/jssubscript-loader;1";
|
|
const mozIJSSubScriptLoader =
|
|
Components.interfaces.mozIJSSubScriptLoader;
|
|
|
|
var cls;
|
|
if ((cls = Components.classes[LOADER_CTRID]))
|
|
console._loader = cls.createInstance(mozIJSSubScriptLoader);
|
|
}
|
|
|
|
var obj = ("scope" in e) ? e.scope : null;
|
|
try
|
|
{
|
|
var rvStr;
|
|
var rv = rvStr = console._loader.loadSubScript(e.url, obj);
|
|
if (typeof rv == "function")
|
|
rvStr = MSG_TYPE_FUNCTION;
|
|
display(getMsg(MSN_SUBSCRIPT_LOADED, [e.url, rvStr]), MT_INFO);
|
|
return rv;
|
|
}
|
|
catch (ex)
|
|
{
|
|
display (getMsg(MSN_ERR_SCRIPTLOAD, e.url));
|
|
display (formatException(ex), MT_ERROR);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function cmdNext ()
|
|
{
|
|
console._stepOverLevel = 0;
|
|
dispatch ("step");
|
|
console.jsds.functionHook = console._callHook;
|
|
return true;
|
|
}
|
|
|
|
function cmdOpenDialog (e)
|
|
{
|
|
return openDialog (e.url, e.windowName, e.windowFlags);
|
|
}
|
|
|
|
function cmdOpenURL (e)
|
|
{
|
|
var url = prompt (MSG_OPEN_URL);
|
|
if (url)
|
|
return dispatch ("find-url",{url: url});
|
|
|
|
return null;
|
|
}
|
|
|
|
function cmdPPrint (e)
|
|
{
|
|
setPrettyPrintState(!console.sourceView.prettyPrint);
|
|
return true;
|
|
}
|
|
|
|
function cmdPref (e)
|
|
{
|
|
if (e.prefName)
|
|
{
|
|
if (e.prefName[0] == "-")
|
|
{
|
|
console.prefs.prefBranch.clearUserPref(e.prefName.substr(1));
|
|
return true;
|
|
}
|
|
|
|
if (!(e.prefName in console.prefs))
|
|
{
|
|
display (getMsg(MSN_ERR_INVALID_PARAM, ["prefName", e.prefName]),
|
|
MT_ERROR);
|
|
return false;
|
|
}
|
|
|
|
if (e.prefValue)
|
|
console.prefs[e.prefName] = e.prefValue;
|
|
else
|
|
e.prefValue = console.prefs[e.prefName];
|
|
|
|
display (getMsg(MSN_FMT_PREFVALUE, [e.prefName, e.prefValue]));
|
|
}
|
|
else
|
|
{
|
|
for (var i in console.prefs.prefNames)
|
|
{
|
|
var name = console.prefs.prefNames[i];
|
|
display (getMsg(MSN_FMT_PREFVALUE, [name, console.prefs[name]]));
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdProfile(e)
|
|
{
|
|
if (e.toggle && e.toggle == "toggle")
|
|
e.toggle = !(console.jsds.flags & COLLECT_PROFILE_DATA);
|
|
|
|
if (e.toggle != null)
|
|
setProfileState(e.toggle);
|
|
else
|
|
e.toggle = console.jsds.flags & COLLECT_PROFILE_DATA;
|
|
|
|
feedback (e, getMsg(MSN_PROFILE_STATE,
|
|
[e.toggle ? MSG_VAL_ON : MSG_VAL_OFF]));
|
|
}
|
|
|
|
function cmdProps (e, forceDebuggerScope)
|
|
{
|
|
var v;
|
|
|
|
if (forceDebuggerScope)
|
|
v = evalInDebuggerScope (e.scriptText);
|
|
else
|
|
v = evalInTargetScope (e.scriptText);
|
|
|
|
if (!(v instanceof jsdIValue) || v.jsType != jsdIValue.TYPE_OBJECT)
|
|
{
|
|
var str = (v instanceof jsdIValue) ? formatValue(v) : String(v)
|
|
display (getMsg(MSN_ERR_INVALID_PARAM, [MSG_VAL_EXPR, str]),
|
|
MT_ERROR);
|
|
return false;
|
|
}
|
|
|
|
display (getMsg(forceDebuggerScope ? MSN_PROPSD_HEADER : MSN_PROPS_HEADER,
|
|
e.scriptText));
|
|
displayProperties(v);
|
|
return true;
|
|
}
|
|
|
|
function cmdPropsd (e)
|
|
{
|
|
return cmdProps (e, true);
|
|
}
|
|
|
|
function cmdQuit()
|
|
{
|
|
goQuitApplication();
|
|
}
|
|
|
|
function cmdReload ()
|
|
{
|
|
if (!("childData" in console.sourceView))
|
|
return false;
|
|
|
|
console.sourceView.childData.reloadSource();
|
|
return true;
|
|
}
|
|
|
|
function cmdSaveSource (e)
|
|
{
|
|
if (!e.targetFile || e.targetFile == "?")
|
|
{
|
|
var fileName = console.sourceView.childData.fileName;
|
|
if (fileName.search(/^\w+:/) < 0)
|
|
{
|
|
var shortName = getFileFromPath(fileName);
|
|
if (fileName != shortName)
|
|
fileName = shortName;
|
|
else
|
|
fileName = "";
|
|
}
|
|
else
|
|
fileName = "";
|
|
|
|
var rv = pickSaveAs(MSG_SAVE_SOURCE, "$all $text *.js", fileName);
|
|
if (rv.reason == PICK_CANCEL)
|
|
return null;
|
|
e.targetFile = rv.file;
|
|
}
|
|
|
|
var file = fopen (e.targetFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE);
|
|
var lines = console.sourceView.childData.lines;
|
|
for (var i = 0; i < lines.length; ++i)
|
|
file.write(lines[i] + "\n");
|
|
file.close();
|
|
|
|
return file.localFile.path;
|
|
}
|
|
|
|
function cmdSaveProfile (e)
|
|
{
|
|
function writeHeaderCSV(file)
|
|
{
|
|
file.write ("# path, file, function, start-line, end-line, " +
|
|
"call-count, recurse-depth, total-time, min-time, " +
|
|
"max-time, avg-time\n");
|
|
};
|
|
|
|
function writeSummaryCSV(file, summary)
|
|
{
|
|
for (var i = 0; i < summary.length; ++i)
|
|
{
|
|
var r = summary[i];
|
|
file.write (r.path + ", " + r.file + ", " + r.fun + ", " + r.base +
|
|
", " + r.end + ", " + r.ccount + ", " + r.recurse +
|
|
", " + r.total + ", " + r.min + ", " + r.max +
|
|
", " + r.avg +"\n");
|
|
}
|
|
};
|
|
|
|
function writeSummaryText(file, summary, fileName)
|
|
{
|
|
file.write ((fileName ? fileName : "** all files **") + "\n");
|
|
for (var i = 0; i < summary.length; ++i)
|
|
file.write ("\t" + summary[i].str + "\n");
|
|
};
|
|
|
|
if (!e.targetFile || e.targetFile == "?")
|
|
{
|
|
var rv = pickSaveAs(MSG_SAVE_PROFILE, "$html *.csv $text $all");
|
|
if (rv.reason == PICK_CANCEL)
|
|
return null;
|
|
e.targetFile = rv.file;
|
|
}
|
|
|
|
var file = fopen (e.targetFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE);
|
|
var ary = file.localFile.path.match(/(csv|html?)$/i);
|
|
var writeHeader = null;
|
|
var writeSummary = writeSummaryText;
|
|
var writeFooter = null;
|
|
if (ary)
|
|
{
|
|
var ext = ary[1].toLowerCase();
|
|
if (ext == "csv")
|
|
{
|
|
writeHeader = writeHeaderCSV;
|
|
writeSummary = writeSummaryCSV;
|
|
}
|
|
else
|
|
{
|
|
writeHeader = writeHeaderHTML;
|
|
writeSummary = writeSummaryHTML;
|
|
writeFooter = writeFooterHTML;
|
|
}
|
|
}
|
|
|
|
if (writeHeader)
|
|
writeHeader(file);
|
|
|
|
var i;
|
|
|
|
if ("urlList" in e && e.urlList.length > 0 ||
|
|
"url" in e && e.url && (e.urlList = [e.url]))
|
|
{
|
|
for (i = 0; i < e.urlList.length; ++i)
|
|
writeSummary(file, console.getProfileSummary(e.urlList[i]),
|
|
e.urlList[i]);
|
|
}
|
|
else
|
|
{
|
|
var scriptURLs = keys(console.scripts).sort();
|
|
for (i = 0; i < scriptURLs.length; ++i)
|
|
{
|
|
var fileName = console.scripts[scriptURLs[i]].fileName;
|
|
writeSummary(file, console.getProfileSummary(fileName), fileName);
|
|
}
|
|
}
|
|
|
|
if (writeFooter)
|
|
writeFooter(file);
|
|
|
|
display (getMsg(MSN_PROFILE_SAVED, getURLSpecFromFile(file.localFile)));
|
|
file.close();
|
|
return file.localFile;
|
|
}
|
|
|
|
|
|
function cmdScope ()
|
|
{
|
|
if (getCurrentFrame().scope.propertyCount == 0)
|
|
display (getMsg (MSN_NO_PROPERTIES, MSG_WORD_SCOPE));
|
|
else
|
|
displayProperties (getCurrentFrame().scope);
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdStartupInit (e)
|
|
{
|
|
if (e.toggle != null)
|
|
{
|
|
if (e.toggle == "toggle")
|
|
console.jsds.initAtStartup = !console.jsds.initAtStartup;
|
|
else
|
|
console.jsds.initAtStartup = e.toggle;
|
|
}
|
|
|
|
display (getMsg(MSN_IASMODE,
|
|
console.jsds.initAtStartup ? MSG_VAL_ON : MSG_VAL_OFF));
|
|
return true;
|
|
}
|
|
|
|
function cmdStep()
|
|
{
|
|
setStopState(true);
|
|
var topFrame = console.frames[0];
|
|
console._stepPast = topFrame.script.fileName;
|
|
if (console.sourceView.prettyPrint)
|
|
{
|
|
console._stepPast +=
|
|
topFrame.script.pcToLine(topFrame.pc, PCMAP_PRETTYPRINT);
|
|
}
|
|
else
|
|
{
|
|
console._stepPast += topFrame.line;
|
|
}
|
|
disableDebugCommands()
|
|
console.stackView.saveState();
|
|
console.jsds.exitNestedEventLoop();
|
|
return true;
|
|
}
|
|
|
|
function cmdStop (e)
|
|
{
|
|
if (console.jsds.interruptHook)
|
|
setStopState(false);
|
|
else
|
|
setStopState(true);
|
|
}
|
|
|
|
function cmdTMode (e)
|
|
{
|
|
if (e.mode != null)
|
|
{
|
|
e.mode = e.mode.toLowerCase();
|
|
|
|
if (e.mode == "cycle")
|
|
{
|
|
switch (console.throwMode)
|
|
{
|
|
case TMODE_IGNORE:
|
|
e.mode = "trace";
|
|
break;
|
|
case TMODE_TRACE:
|
|
e.mode = "break";
|
|
break;
|
|
case TMODE_BREAK:
|
|
e.mode = "ignore";
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (e.mode.toLowerCase())
|
|
{
|
|
case "ignore":
|
|
console.jsds.throwHook = null;
|
|
console.throwMode = TMODE_IGNORE;
|
|
break;
|
|
case "trace":
|
|
console.jsds.throwHook = console._executionHook;
|
|
console.throwMode = TMODE_TRACE;
|
|
break;
|
|
case "break":
|
|
console.jsds.throwHook = console._executionHook;
|
|
console.throwMode = TMODE_BREAK;
|
|
break;
|
|
default:
|
|
display (getMsg(MSN_ERR_INVALID_PARAM, ["mode", e.mode]),
|
|
MT_ERROR);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
switch (console.throwMode)
|
|
{
|
|
case EMODE_IGNORE:
|
|
display (MSG_TMODE_IGNORE);
|
|
break;
|
|
case EMODE_TRACE:
|
|
display (MSG_TMODE_TRACE);
|
|
break;
|
|
case EMODE_BREAK:
|
|
display (MSG_TMODE_BREAK);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function cmdVersion ()
|
|
{
|
|
display(MSG_HELLO, MT_HELLO);
|
|
display(getMsg(MSN_VERSION, console.version), MT_HELLO);
|
|
}
|
|
|
|
function cmdWhere ()
|
|
{
|
|
displayCallStack();
|
|
return true;
|
|
}
|
|
|