зеркало из https://github.com/mozilla/pjs.git
Add debugger contribution from Christopher Oliver.
This commit is contained in:
Родитель
0167f0416d
Коммит
e33e06b0e8
|
@ -16,6 +16,8 @@ Requires Ant version 1.2
|
|||
|
||||
<property name="src.dir" value="."/>
|
||||
<property name="src.examples" value="${src.dir}/examples"/>
|
||||
<property name="src.debugger"
|
||||
value="${src.dir}/org/mozilla/javascript/tools/debugger"/>
|
||||
|
||||
<property name="build.dir" value="./build"/>
|
||||
<property name="build.dest" value="${build.dir}/classes"/>
|
||||
|
@ -35,6 +37,8 @@ Requires Ant version 1.2
|
|||
<property name="dist.docsrc.dir" value="${src.dir}/docs"/>
|
||||
<available file="${cvs.javasrc.dir}/org" property="in-cvs-tree"/>
|
||||
<available classname="com.ibm.bsf.BSFEngine" property="bsf.present"/>
|
||||
<available file="${src.debugger}/AbstractCellEditor.java"
|
||||
property="swing-ex-available"/>
|
||||
</target>
|
||||
|
||||
<target name="init" depends="properties">
|
||||
|
@ -50,7 +54,55 @@ Requires Ant version 1.2
|
|||
<mkdir dir="${dist.apidocs}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile-from-cvs" if="in-cvs-tree" depends="prepare">
|
||||
<target name="get-swing-ex" unless="swing-ex-available">
|
||||
<!-- Download source from Sun's site, unzip it, remove
|
||||
the files we don't need, and change the package
|
||||
-->
|
||||
<get src="http://java.sun.com/products/jfc/tsc/articles/treetable2/downloads/src.zip" dest="${build.dir}/swingExSrc.zip"/>
|
||||
<unzip src="${build.dir}/swingExSrc.zip" dest="${src.debugger}"/>
|
||||
<delete file="${src.debugger}/FileSystemModel2.java" />
|
||||
<delete file="${src.debugger}/MergeSort.java" />
|
||||
<delete file="${src.debugger}/TreeTableExample2.java" />
|
||||
<replace file="${src.debugger}/AbstractCellEditor.java">
|
||||
<replacetoken>import java.awt.Component;</replacetoken>
|
||||
<replacevalue>
|
||||
package org.mozilla.javascript.tools.debugger;
|
||||
import java.awt.Component;
|
||||
</replacevalue>
|
||||
</replace>
|
||||
<replace file="${src.debugger}/AbstractTreeTableModel.java">
|
||||
<replacetoken>import javax.swing.tree.*;</replacetoken>
|
||||
<replacevalue>
|
||||
package org.mozilla.javascript.tools.debugger;
|
||||
import javax.swing.tree.*;
|
||||
</replacevalue>
|
||||
</replace>
|
||||
<replace file="${src.debugger}/JTreeTable.java">
|
||||
<replacetoken>import javax.swing.*;</replacetoken>
|
||||
<replacevalue>
|
||||
package org.mozilla.javascript.tools.debugger;
|
||||
import javax.swing.*;
|
||||
</replacevalue>
|
||||
</replace>
|
||||
<replace file="${src.debugger}/TreeTableModel.java">
|
||||
<replacetoken>import javax.swing.tree.TreeModel;</replacetoken>
|
||||
<replacevalue>
|
||||
package org.mozilla.javascript.tools.debugger;
|
||||
import javax.swing.tree.TreeModel;
|
||||
</replacevalue>
|
||||
</replace>
|
||||
<replace file="${src.debugger}/TreeTableModelAdapter.java">
|
||||
<replacetoken>import javax.swing.JTree;</replacetoken>
|
||||
<replacevalue>
|
||||
package org.mozilla.javascript.tools.debugger;
|
||||
import javax.swing.JTree;
|
||||
</replacevalue>
|
||||
</replace>
|
||||
</target>
|
||||
|
||||
<target name="compile-from-cvs"
|
||||
if="in-cvs-tree"
|
||||
depends="prepare,get-swing-ex">
|
||||
<javac srcdir="${cvs.javasrc.dir}"
|
||||
destdir="${build.dest}"
|
||||
includes="org/**/*.java"
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,211 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino JavaScript Debugger code, released
|
||||
* November 21, 2000.
|
||||
*
|
||||
* The Initial Developer of the Original Code is See Beyond Corporation.
|
||||
|
||||
* Portions created by See Beyond are
|
||||
* Copyright (C) 2000 See Beyond Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Christopher Oliver
|
||||
*
|
||||
* 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 NPL, 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 NPL or the GPL.
|
||||
*/
|
||||
package org.mozilla.javascript.tools.shell;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.util.*;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.Segment;
|
||||
|
||||
|
||||
public class JSConsole extends JFrame implements ActionListener {
|
||||
|
||||
private File CWD;
|
||||
private JFileChooser dlg;
|
||||
private ConsoleTextArea consoleTextArea;
|
||||
|
||||
public String chooseFile() {
|
||||
if(CWD == null) {
|
||||
String dir = System.getProperty("user.dir");
|
||||
if(dir != null) {
|
||||
CWD = new File(dir);
|
||||
}
|
||||
}
|
||||
if(CWD != null) {
|
||||
dlg.setCurrentDirectory(CWD);
|
||||
}
|
||||
dlg.setDialogTitle("Select a file to load");
|
||||
int returnVal = dlg.showOpenDialog(this);
|
||||
if(returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
String result = dlg.getSelectedFile().getPath();
|
||||
CWD = dlg.getSelectedFile().getParentFile();
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
JSConsole console = new JSConsole(args);
|
||||
}
|
||||
|
||||
public void createFileChooser() {
|
||||
dlg = new JFileChooser();
|
||||
javax.swing.filechooser.FileFilter filter =
|
||||
new javax.swing.filechooser.FileFilter() {
|
||||
public boolean accept(File f) {
|
||||
if(f.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
String name = f.getName();
|
||||
int i = name.lastIndexOf('.');
|
||||
if(i > 0 && i < name.length() -1) {
|
||||
String ext = name.substring(i + 1).toLowerCase();
|
||||
if(ext.equals("js")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return "JavaScript Files (*.js)";
|
||||
}
|
||||
};
|
||||
dlg.addChoosableFileFilter(filter);
|
||||
|
||||
}
|
||||
|
||||
public JSConsole(String[] args) {
|
||||
super("Rhino JavaScript Console");
|
||||
JMenuBar menubar = new JMenuBar();
|
||||
createFileChooser();
|
||||
String[] fileItems = {"Load...", "Exit"};
|
||||
String[] fileCmds = {"Load", "Exit"};
|
||||
char[] fileShortCuts = {'L', 'X'};
|
||||
String[] editItems = {"Cut", "Copy", "Paste"};
|
||||
char[] editShortCuts = {'T', 'C', 'P'};
|
||||
String[] plafItems = {"Metal", "Windows", "Motif"};
|
||||
boolean [] plafState = {true, false, false};
|
||||
JMenu fileMenu = new JMenu("File");
|
||||
fileMenu.setMnemonic('F');
|
||||
JMenu editMenu = new JMenu("Edit");
|
||||
editMenu.setMnemonic('E');
|
||||
JMenu plafMenu = new JMenu("Platform");
|
||||
plafMenu.setMnemonic('P');
|
||||
for(int i = 0; i < fileItems.length; ++i) {
|
||||
JMenuItem item = new JMenuItem(fileItems[i],
|
||||
fileShortCuts[i]);
|
||||
item.setActionCommand(fileCmds[i]);
|
||||
item.addActionListener(this);
|
||||
fileMenu.add(item);
|
||||
}
|
||||
for(int i = 0; i < editItems.length; ++i) {
|
||||
JMenuItem item = new JMenuItem(editItems[i],
|
||||
editShortCuts[i]);
|
||||
item.addActionListener(this);
|
||||
editMenu.add(item);
|
||||
}
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
for(int i = 0; i < plafItems.length; ++i) {
|
||||
JRadioButtonMenuItem item = new JRadioButtonMenuItem(plafItems[i],
|
||||
plafState[i]);
|
||||
group.add(item);
|
||||
item.addActionListener(this);
|
||||
plafMenu.add(item);
|
||||
}
|
||||
menubar.add(fileMenu);
|
||||
menubar.add(editMenu);
|
||||
menubar.add(plafMenu);
|
||||
setJMenuBar(menubar);
|
||||
consoleTextArea = new ConsoleTextArea(args);
|
||||
JScrollPane scroller = new JScrollPane(consoleTextArea);
|
||||
setContentPane(scroller);
|
||||
consoleTextArea.setRows(24);
|
||||
consoleTextArea.setColumns(80);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
pack();
|
||||
setVisible(true);
|
||||
// System.setIn(consoleTextArea.getIn());
|
||||
// System.setOut(consoleTextArea.getOut());
|
||||
// System.setErr(consoleTextArea.getErr());
|
||||
Main.setIn(consoleTextArea.getIn());
|
||||
Main.setOut(consoleTextArea.getOut());
|
||||
Main.setErr(consoleTextArea.getErr());
|
||||
Main.main(args);
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String cmd = e.getActionCommand();
|
||||
String plaf_name = null;
|
||||
if(cmd.equals("Load")) {
|
||||
String f = chooseFile();
|
||||
if(f != null) {
|
||||
f = f.replace('\\', '/');
|
||||
consoleTextArea.eval("load(\"" + f + "\");");
|
||||
}
|
||||
} else if(cmd.equals("Exit")) {
|
||||
System.exit(0);
|
||||
} else if(cmd.equals("Cut")) {
|
||||
consoleTextArea.cut();
|
||||
} else if(cmd.equals("Copy")) {
|
||||
consoleTextArea.copy();
|
||||
} else if(cmd.equals("Paste")) {
|
||||
consoleTextArea.paste();
|
||||
} else {
|
||||
if(cmd.equals("Metal")) {
|
||||
plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel";
|
||||
} else if(cmd.equals("Windows")) {
|
||||
plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
|
||||
} else if(cmd.equals("Motif")) {
|
||||
plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
|
||||
}
|
||||
if(plaf_name != null) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(plaf_name);
|
||||
SwingUtilities.updateComponentTreeUI(this);
|
||||
consoleTextArea.postUpdateUI();
|
||||
// updateComponentTreeUI seems to mess up the file
|
||||
// chooser dialog, so just create a new one
|
||||
createFileChooser();
|
||||
} catch(Exception exc) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
exc.getMessage(),
|
||||
"Platform",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,418 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino JavaScript Debugger code, released
|
||||
* November 21, 2000.
|
||||
*
|
||||
* The Initial Developer of the Original Code is See Beyond Corporation.
|
||||
|
||||
* Portions created by See Beyond are
|
||||
* Copyright (C) 2000 See Beyond Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Christopher Oliver
|
||||
*
|
||||
* 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 NPL, 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 NPL or the GPL.
|
||||
*/
|
||||
|
||||
package org.mozilla.javascript.tools.debugger;
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.tools.shell.Global;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class VariableModel extends AbstractTreeTableModel
|
||||
implements TreeTableModel {
|
||||
|
||||
// Names of the columns.
|
||||
//static protected String[] cNames = {"Name", "Type", "Value"};
|
||||
static protected String[] cNames = { " Name", " Value"};
|
||||
|
||||
// Types of the columns.
|
||||
//static protected Class[] cTypes = {TreeTableModel.class, String.class, String.class};
|
||||
static protected Class[] cTypes = {TreeTableModel.class, String.class};
|
||||
|
||||
public VariableModel(Scriptable scope) {
|
||||
super(scope == null ? null : new VariableNode(scope, "this"));
|
||||
}
|
||||
|
||||
//
|
||||
// Some convenience methods.
|
||||
//
|
||||
|
||||
protected Object getObject(Object node) {
|
||||
VariableNode varNode = ((VariableNode)node);
|
||||
if(varNode == null) return null;
|
||||
return varNode.getObject();
|
||||
}
|
||||
|
||||
protected Object[] getChildren(Object node) {
|
||||
VariableNode varNode = ((VariableNode)node);
|
||||
return varNode.getChildren();
|
||||
}
|
||||
|
||||
//
|
||||
// The TreeModel interface
|
||||
//
|
||||
|
||||
public int getChildCount(Object node) {
|
||||
Object[] children = getChildren(node);
|
||||
return (children == null) ? 0 : children.length;
|
||||
}
|
||||
|
||||
public Object getChild(Object node, int i) {
|
||||
return getChildren(node)[i];
|
||||
}
|
||||
|
||||
// The superclass's implementation would work, but this is more efficient.
|
||||
public boolean isLeaf(Object node) {
|
||||
if(node == null) return true;
|
||||
VariableNode varNode = (VariableNode)node;
|
||||
Object[] children = varNode.getChildren();
|
||||
if(children != null && children.length > 0) {
|
||||
return false;
|
||||
}
|
||||
//Object value = getObject(node);
|
||||
//if(value != null && value instanceof Scriptable) {
|
||||
//if(value == Undefined.instance ||
|
||||
//value == ScriptableObject.NOT_FOUND) {
|
||||
//return true;
|
||||
//}
|
||||
//Scriptable scrip = (Scriptable)value;
|
||||
//Scriptable proto = scrip.getPrototype();
|
||||
//if(proto != null &&
|
||||
//proto != ScriptableObject.getObjectPrototype(scrip)) {
|
||||
//return false;
|
||||
//}
|
||||
//}
|
||||
// if(value == null) return true;
|
||||
// if (value == Undefined.instance)
|
||||
// return true;
|
||||
// if (value == null)
|
||||
// return true;
|
||||
// if (value instanceof String)
|
||||
// return true;
|
||||
// if (value instanceof Number)
|
||||
// return true;
|
||||
// if (value instanceof Boolean)
|
||||
// return true;
|
||||
// if(value instanceof Scriptable) {
|
||||
// //Scriptable scrip = (Scriptable)value;
|
||||
//if(scrip.has(0, scrip)) {
|
||||
//return false;
|
||||
//}
|
||||
//if(ScriptableObject.getPropertyIds(scrip).length > 0) {
|
||||
//return false;
|
||||
//}
|
||||
//return true;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(Object node, int column) {
|
||||
return column == 0 || column == 2;
|
||||
}
|
||||
|
||||
//
|
||||
// The TreeTableNode interface.
|
||||
//
|
||||
|
||||
public int getColumnCount() {
|
||||
return cNames.length;
|
||||
}
|
||||
|
||||
public String getColumnName(int column) {
|
||||
return cNames[column];
|
||||
}
|
||||
|
||||
public Class getColumnClass(int column) {
|
||||
return cTypes[column];
|
||||
}
|
||||
|
||||
public Object getValueAt(Object node, int column) {
|
||||
Object value = getObject(node);
|
||||
try {
|
||||
switch(column) {
|
||||
case 0: // Name
|
||||
VariableNode varNode = (VariableNode)node;
|
||||
String name = "";
|
||||
if(varNode.name != null) {
|
||||
return name + varNode.name;
|
||||
}
|
||||
return name + "[" + varNode.index + "]";
|
||||
case -1: // Type
|
||||
if(value == Undefined.instance || value == ScriptableObject.NOT_FOUND) {
|
||||
return "undefined";
|
||||
}
|
||||
if (value == null)
|
||||
return "object";
|
||||
if (value instanceof Scriptable)
|
||||
return (value instanceof Function) ? "function" : "object";
|
||||
if (value instanceof String)
|
||||
return "string";
|
||||
if (value instanceof Number)
|
||||
return "number";
|
||||
if (value instanceof Boolean)
|
||||
return "boolean";
|
||||
return value.getClass().getName();
|
||||
case 1: // value
|
||||
if(value == Undefined.instance || value == ScriptableObject.NOT_FOUND) {
|
||||
return "undefined";
|
||||
}
|
||||
if(value instanceof Scriptable) {
|
||||
try {
|
||||
Context cx = Context.enter();
|
||||
String result;
|
||||
try {
|
||||
result = ScriptRuntime.toString(value);
|
||||
} catch(Exception exc) {
|
||||
result = value.toString();
|
||||
} finally {
|
||||
cx.exit();
|
||||
}
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int len = result.length();
|
||||
for(int i = 0; i < len; i++) {
|
||||
char ch = result.charAt(i);
|
||||
if(Character.isISOControl(ch)) {
|
||||
ch = ' ';
|
||||
}
|
||||
buf.append(ch);
|
||||
}
|
||||
return buf.toString();
|
||||
} catch(Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(value == null) {
|
||||
return "null";
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
catch (Exception exc) {
|
||||
//exc.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setScope(Scriptable scope) {
|
||||
//System.out.println("setScope: " + scope);
|
||||
VariableNode rootVar = (VariableNode)root;
|
||||
rootVar.scope = scope;
|
||||
fireTreeNodesChanged(this,
|
||||
new Object[]{root},
|
||||
null, new Object[]{root});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class VariableNode {
|
||||
Scriptable scope;
|
||||
String name;
|
||||
int index;
|
||||
|
||||
public VariableNode(Scriptable scope, String name) {
|
||||
this.scope = scope;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public VariableNode(Scriptable scope, int index) {
|
||||
this.scope = scope;
|
||||
this.name = null;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the the string to be used to display this leaf in the JTree.
|
||||
*/
|
||||
public String toString() {
|
||||
return (name != null ? name : "[" + index + "]");
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
try {
|
||||
if(scope == null) return null;
|
||||
if(name != null) {
|
||||
if(name.equals("this")) {
|
||||
return scope;
|
||||
}
|
||||
Object result;
|
||||
if(name.equals("__proto__")) {
|
||||
result = scope.getPrototype();
|
||||
} else if(name.equals("__parent__")) {
|
||||
result = scope.getParentScope();
|
||||
} else {
|
||||
result = scope.get(name, scope);
|
||||
}
|
||||
if(result == ScriptableObject.NOT_FOUND) {
|
||||
result = Undefined.instance;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Object result = scope.get(index, scope);
|
||||
if(result == ScriptableObject.NOT_FOUND) {
|
||||
result = Undefined.instance;
|
||||
}
|
||||
return result;
|
||||
} catch(Exception exc) {
|
||||
return "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
Object[] children;
|
||||
|
||||
/**
|
||||
* Loads the children, caching the results in the children ivar.
|
||||
*/
|
||||
static final Object[] empty = new Object[0];
|
||||
static Scriptable builtin[];
|
||||
protected Object[] getChildren() {
|
||||
if(children != null) return children;
|
||||
try {
|
||||
Object value = getObject();
|
||||
if(value == null) return children = empty;
|
||||
if(value == ScriptableObject.NOT_FOUND ||
|
||||
value == Undefined.instance) {
|
||||
return children = empty;
|
||||
}
|
||||
if(value instanceof Scriptable) {
|
||||
Scriptable scrip = (Scriptable)value;
|
||||
Scriptable proto = scrip.getPrototype();
|
||||
Scriptable parent = scrip.getParentScope();
|
||||
if(scrip instanceof NativeCall) {
|
||||
parent = proto = null;
|
||||
} else if(parent instanceof NativeCall) {
|
||||
parent = null;
|
||||
}
|
||||
if(proto != null) {
|
||||
if(builtin == null) {
|
||||
builtin = new Scriptable[6];
|
||||
builtin[0] =
|
||||
ScriptableObject.getObjectPrototype(scrip);
|
||||
builtin[1] =
|
||||
ScriptableObject.getFunctionPrototype(scrip);
|
||||
builtin[2] =
|
||||
ScriptableObject.getClassPrototype(scrip,
|
||||
"String");
|
||||
builtin[3] =
|
||||
ScriptableObject.getClassPrototype(scrip,
|
||||
"Boolean");
|
||||
builtin[4] =
|
||||
ScriptableObject.getClassPrototype(scrip,
|
||||
"Array");
|
||||
builtin[5] =
|
||||
ScriptableObject.getClassPrototype(scrip,
|
||||
"Number");
|
||||
}
|
||||
for(int i = 0; i < builtin.length; i++) {
|
||||
if(proto == builtin[i]) {
|
||||
proto = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(scrip.has(0, scrip)) {
|
||||
int len = 0;
|
||||
try {
|
||||
Scriptable start = scrip;
|
||||
Scriptable obj = start;
|
||||
Object result = Undefined.instance;
|
||||
do {
|
||||
if(obj.has("length", start)) {
|
||||
result = obj.get("length", start);
|
||||
if (result != Scriptable.NOT_FOUND)
|
||||
break;
|
||||
}
|
||||
obj = obj.getPrototype();
|
||||
} while (obj != null);
|
||||
if(result instanceof Number) {
|
||||
len = ((Number)result).intValue();
|
||||
}
|
||||
} catch(Exception exc) {
|
||||
}
|
||||
if(parent != null) {
|
||||
len++;
|
||||
}
|
||||
if(proto != null) {
|
||||
len++;
|
||||
}
|
||||
children = new VariableNode[len];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
if(proto != null) {
|
||||
children[i++] = new VariableNode(scrip, "__proto__");
|
||||
j++;
|
||||
}
|
||||
if(parent != null) {
|
||||
children[i++] = new VariableNode(scrip, "__parent__");
|
||||
j++;
|
||||
}
|
||||
for(; i < len; i++) {
|
||||
children[i] = new VariableNode(scrip, i-j);
|
||||
}
|
||||
} else {
|
||||
int len = 0;
|
||||
Hashtable t = new Hashtable();
|
||||
Object[] ids = scrip.getIds();
|
||||
if(proto != null) t.put("__proto__", "__proto__");
|
||||
if(parent != null) t.put("__parent__", "__parent__");
|
||||
if(ids.length > 0) {
|
||||
for(int j = 0; j < ids.length; j++) {
|
||||
t.put(ids[j], ids[j]);
|
||||
}
|
||||
}
|
||||
ids = new Object[t.size()];
|
||||
Enumeration e = t.keys();
|
||||
int j = 0;
|
||||
while(e.hasMoreElements()) {
|
||||
ids[j++] = e.nextElement().toString();
|
||||
}
|
||||
if(ids != null && ids.length > 0) {
|
||||
java.util.Arrays.sort(ids, new java.util.Comparator() {
|
||||
public int compare(Object l, Object r) {
|
||||
return l.toString().compareToIgnoreCase(r.toString());
|
||||
|
||||
}
|
||||
});
|
||||
len = ids.length;
|
||||
}
|
||||
children = new VariableNode[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
Object id = ids[i];
|
||||
////System.out.println("id is " + id);
|
||||
children[i] =
|
||||
new VariableNode(scrip, id.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino JavaScript Debugger code, released
|
||||
* November 21, 2000.
|
||||
*
|
||||
* The Initial Developer of the Original Code is See Beyond Corporation.
|
||||
|
||||
* Portions created by See Beyond are
|
||||
* Copyright (C) 2000 See Beyond Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Christopher Oliver
|
||||
*
|
||||
* 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 NPL, 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 NPL or the GPL.
|
||||
*/
|
||||
package org.mozilla.javascript.tools.shell;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.util.*;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.Segment;
|
||||
|
||||
class ConsoleWrite implements Runnable {
|
||||
private ConsoleTextArea textArea;
|
||||
private String str;
|
||||
|
||||
public ConsoleWrite(ConsoleTextArea textArea, String str) {
|
||||
this.textArea = textArea;
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
textArea.write(str);
|
||||
}
|
||||
};
|
||||
|
||||
class ConsoleWriter extends java.io.OutputStream {
|
||||
|
||||
private ConsoleTextArea textArea;
|
||||
private StringBuffer buffer;
|
||||
|
||||
public ConsoleWriter(ConsoleTextArea textArea) {
|
||||
this.textArea = textArea;
|
||||
buffer = new StringBuffer();
|
||||
}
|
||||
|
||||
public synchronized void write(int ch) {
|
||||
buffer.append((char)ch);
|
||||
if(ch == '\n') {
|
||||
flushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void write (char[] data, int off, int len) {
|
||||
for(int i = off; i < len; i++) {
|
||||
buffer.append(data[i]);
|
||||
if(data[i] == '\n') {
|
||||
flushBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void flush() {
|
||||
if (buffer.length() > 0) {
|
||||
flushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
public void close () {
|
||||
flush();
|
||||
}
|
||||
|
||||
private void flushBuffer() {
|
||||
String str = buffer.toString();
|
||||
buffer.setLength(0);
|
||||
SwingUtilities.invokeLater(new ConsoleWrite(textArea, str));
|
||||
}
|
||||
};
|
||||
|
||||
public class ConsoleTextArea extends JTextArea implements KeyListener,
|
||||
DocumentListener {
|
||||
private ConsoleWriter console1;
|
||||
private ConsoleWriter console2;
|
||||
private PrintStream out;
|
||||
private PrintStream err;
|
||||
private PrintWriter inPipe;
|
||||
private PipedInputStream in;
|
||||
private java.util.Vector history;
|
||||
private int historyIndex = -1;
|
||||
private int outputMark = 0;
|
||||
|
||||
public void select(int start, int end) {
|
||||
requestFocus();
|
||||
super.select(start, end);
|
||||
}
|
||||
|
||||
public ConsoleTextArea(String[] argv) {
|
||||
super();
|
||||
history = new java.util.Vector();
|
||||
console1 = new ConsoleWriter(this);
|
||||
console2 = new ConsoleWriter(this);
|
||||
out = new PrintStream(console1);
|
||||
err = new PrintStream(console2);
|
||||
PipedOutputStream outPipe = new PipedOutputStream();
|
||||
inPipe = new PrintWriter(outPipe);
|
||||
in = new PipedInputStream();
|
||||
try {
|
||||
outPipe.connect(in);
|
||||
} catch(IOException exc) {
|
||||
exc.printStackTrace();
|
||||
}
|
||||
getDocument().addDocumentListener(this);
|
||||
addKeyListener(this);
|
||||
setLineWrap(true);
|
||||
setFont(new Font("Monospaced", 0, 12));
|
||||
}
|
||||
|
||||
|
||||
synchronized void returnPressed() {
|
||||
Document doc = getDocument();
|
||||
int len = doc.getLength();
|
||||
Segment segment = new Segment();
|
||||
try {
|
||||
doc.getText(outputMark, len - outputMark, segment);
|
||||
} catch(javax.swing.text.BadLocationException ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
if(segment.count > 0) {
|
||||
history.addElement(segment.toString());
|
||||
}
|
||||
historyIndex = history.size();
|
||||
inPipe.write(segment.array, segment.offset, segment.count);
|
||||
append("\n");
|
||||
outputMark = doc.getLength();
|
||||
inPipe.write("\n");
|
||||
inPipe.flush();
|
||||
console1.flush();
|
||||
}
|
||||
|
||||
public void eval(String str) {
|
||||
inPipe.write(str);
|
||||
inPipe.write("\n");
|
||||
inPipe.flush();
|
||||
console1.flush();
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
int code = e.getKeyCode();
|
||||
if(code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT) {
|
||||
if(outputMark == getCaretPosition()) {
|
||||
e.consume();
|
||||
}
|
||||
} else if(code == KeyEvent.VK_HOME) {
|
||||
int caretPos = getCaretPosition();
|
||||
if(caretPos == outputMark) {
|
||||
e.consume();
|
||||
} else if(caretPos > outputMark) {
|
||||
if(!e.isControlDown()) {
|
||||
if(e.isShiftDown()) {
|
||||
moveCaretPosition(outputMark);
|
||||
} else {
|
||||
setCaretPosition(outputMark);
|
||||
}
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
} else if(code == KeyEvent.VK_ENTER) {
|
||||
returnPressed();
|
||||
e.consume();
|
||||
} else if(code == KeyEvent.VK_UP) {
|
||||
historyIndex--;
|
||||
if(historyIndex >= 0) {
|
||||
if(historyIndex >= history.size()) {
|
||||
historyIndex = history.size() -1;
|
||||
}
|
||||
if(historyIndex >= 0) {
|
||||
String str = (String)history.elementAt(historyIndex);
|
||||
int len = getDocument().getLength();
|
||||
replaceRange(str, outputMark, len);
|
||||
int caretPos = outputMark + str.length();
|
||||
select(caretPos, caretPos);
|
||||
} else {
|
||||
historyIndex++;
|
||||
}
|
||||
} else {
|
||||
historyIndex++;
|
||||
}
|
||||
e.consume();
|
||||
} else if(code == KeyEvent.VK_DOWN) {
|
||||
int caretPos = outputMark;
|
||||
if(history.size() > 0) {
|
||||
historyIndex++;
|
||||
if(historyIndex < 0) {historyIndex = 0;}
|
||||
int len = getDocument().getLength();
|
||||
if(historyIndex < history.size()) {
|
||||
String str = (String)history.elementAt(historyIndex);
|
||||
replaceRange(str, outputMark, len);
|
||||
caretPos = outputMark + str.length();
|
||||
} else {
|
||||
historyIndex = history.size();
|
||||
replaceRange("", outputMark, len);
|
||||
}
|
||||
}
|
||||
select(caretPos, caretPos);
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent e) {
|
||||
int keyChar = e.getKeyChar();
|
||||
if(keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */) {
|
||||
if(outputMark == getCaretPosition()) {
|
||||
e.consume();
|
||||
}
|
||||
} else if(getCaretPosition() < outputMark) {
|
||||
setCaretPosition(outputMark);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
public synchronized void write(String str) {
|
||||
insert(str, outputMark);
|
||||
int len = str.length();
|
||||
outputMark += len;
|
||||
select(outputMark, outputMark);
|
||||
}
|
||||
|
||||
public synchronized void insertUpdate(DocumentEvent e) {
|
||||
int len = e.getLength();
|
||||
int off = e.getOffset();
|
||||
if(outputMark > off) {
|
||||
outputMark += len;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeUpdate(DocumentEvent e) {
|
||||
int len = e.getLength();
|
||||
int off = e.getOffset();
|
||||
if(outputMark > off) {
|
||||
if(outputMark >= off + len) {
|
||||
outputMark -= len;
|
||||
} else {
|
||||
outputMark = off;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void postUpdateUI() {
|
||||
// this attempts to cleanup the damage done by updateComponentTreeUI
|
||||
requestFocus();
|
||||
setCaret(getCaret());
|
||||
select(outputMark, outputMark);
|
||||
}
|
||||
|
||||
public synchronized void changedUpdate(DocumentEvent e) {
|
||||
}
|
||||
|
||||
|
||||
public InputStream getIn() {
|
||||
return in;
|
||||
}
|
||||
|
||||
public PrintStream getOut() {
|
||||
return out;
|
||||
}
|
||||
|
||||
public PrintStream getErr() {
|
||||
return err;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,211 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Rhino JavaScript Debugger code, released
|
||||
* November 21, 2000.
|
||||
*
|
||||
* The Initial Developer of the Original Code is See Beyond Corporation.
|
||||
|
||||
* Portions created by See Beyond are
|
||||
* Copyright (C) 2000 See Beyond Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Christopher Oliver
|
||||
*
|
||||
* 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 NPL, 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 NPL or the GPL.
|
||||
*/
|
||||
package org.mozilla.javascript.tools.shell;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import java.util.*;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.Segment;
|
||||
|
||||
|
||||
public class JSConsole extends JFrame implements ActionListener {
|
||||
|
||||
private File CWD;
|
||||
private JFileChooser dlg;
|
||||
private ConsoleTextArea consoleTextArea;
|
||||
|
||||
public String chooseFile() {
|
||||
if(CWD == null) {
|
||||
String dir = System.getProperty("user.dir");
|
||||
if(dir != null) {
|
||||
CWD = new File(dir);
|
||||
}
|
||||
}
|
||||
if(CWD != null) {
|
||||
dlg.setCurrentDirectory(CWD);
|
||||
}
|
||||
dlg.setDialogTitle("Select a file to load");
|
||||
int returnVal = dlg.showOpenDialog(this);
|
||||
if(returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
String result = dlg.getSelectedFile().getPath();
|
||||
CWD = dlg.getSelectedFile().getParentFile();
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
JSConsole console = new JSConsole(args);
|
||||
}
|
||||
|
||||
public void createFileChooser() {
|
||||
dlg = new JFileChooser();
|
||||
javax.swing.filechooser.FileFilter filter =
|
||||
new javax.swing.filechooser.FileFilter() {
|
||||
public boolean accept(File f) {
|
||||
if(f.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
String name = f.getName();
|
||||
int i = name.lastIndexOf('.');
|
||||
if(i > 0 && i < name.length() -1) {
|
||||
String ext = name.substring(i + 1).toLowerCase();
|
||||
if(ext.equals("js")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return "JavaScript Files (*.js)";
|
||||
}
|
||||
};
|
||||
dlg.addChoosableFileFilter(filter);
|
||||
|
||||
}
|
||||
|
||||
public JSConsole(String[] args) {
|
||||
super("Rhino JavaScript Console");
|
||||
JMenuBar menubar = new JMenuBar();
|
||||
createFileChooser();
|
||||
String[] fileItems = {"Load...", "Exit"};
|
||||
String[] fileCmds = {"Load", "Exit"};
|
||||
char[] fileShortCuts = {'L', 'X'};
|
||||
String[] editItems = {"Cut", "Copy", "Paste"};
|
||||
char[] editShortCuts = {'T', 'C', 'P'};
|
||||
String[] plafItems = {"Metal", "Windows", "Motif"};
|
||||
boolean [] plafState = {true, false, false};
|
||||
JMenu fileMenu = new JMenu("File");
|
||||
fileMenu.setMnemonic('F');
|
||||
JMenu editMenu = new JMenu("Edit");
|
||||
editMenu.setMnemonic('E');
|
||||
JMenu plafMenu = new JMenu("Platform");
|
||||
plafMenu.setMnemonic('P');
|
||||
for(int i = 0; i < fileItems.length; ++i) {
|
||||
JMenuItem item = new JMenuItem(fileItems[i],
|
||||
fileShortCuts[i]);
|
||||
item.setActionCommand(fileCmds[i]);
|
||||
item.addActionListener(this);
|
||||
fileMenu.add(item);
|
||||
}
|
||||
for(int i = 0; i < editItems.length; ++i) {
|
||||
JMenuItem item = new JMenuItem(editItems[i],
|
||||
editShortCuts[i]);
|
||||
item.addActionListener(this);
|
||||
editMenu.add(item);
|
||||
}
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
for(int i = 0; i < plafItems.length; ++i) {
|
||||
JRadioButtonMenuItem item = new JRadioButtonMenuItem(plafItems[i],
|
||||
plafState[i]);
|
||||
group.add(item);
|
||||
item.addActionListener(this);
|
||||
plafMenu.add(item);
|
||||
}
|
||||
menubar.add(fileMenu);
|
||||
menubar.add(editMenu);
|
||||
menubar.add(plafMenu);
|
||||
setJMenuBar(menubar);
|
||||
consoleTextArea = new ConsoleTextArea(args);
|
||||
JScrollPane scroller = new JScrollPane(consoleTextArea);
|
||||
setContentPane(scroller);
|
||||
consoleTextArea.setRows(24);
|
||||
consoleTextArea.setColumns(80);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
pack();
|
||||
setVisible(true);
|
||||
// System.setIn(consoleTextArea.getIn());
|
||||
// System.setOut(consoleTextArea.getOut());
|
||||
// System.setErr(consoleTextArea.getErr());
|
||||
Main.setIn(consoleTextArea.getIn());
|
||||
Main.setOut(consoleTextArea.getOut());
|
||||
Main.setErr(consoleTextArea.getErr());
|
||||
Main.main(args);
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String cmd = e.getActionCommand();
|
||||
String plaf_name = null;
|
||||
if(cmd.equals("Load")) {
|
||||
String f = chooseFile();
|
||||
if(f != null) {
|
||||
f = f.replace('\\', '/');
|
||||
consoleTextArea.eval("load(\"" + f + "\");");
|
||||
}
|
||||
} else if(cmd.equals("Exit")) {
|
||||
System.exit(0);
|
||||
} else if(cmd.equals("Cut")) {
|
||||
consoleTextArea.cut();
|
||||
} else if(cmd.equals("Copy")) {
|
||||
consoleTextArea.copy();
|
||||
} else if(cmd.equals("Paste")) {
|
||||
consoleTextArea.paste();
|
||||
} else {
|
||||
if(cmd.equals("Metal")) {
|
||||
plaf_name = "javax.swing.plaf.metal.MetalLookAndFeel";
|
||||
} else if(cmd.equals("Windows")) {
|
||||
plaf_name = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
|
||||
} else if(cmd.equals("Motif")) {
|
||||
plaf_name = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
|
||||
}
|
||||
if(plaf_name != null) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(plaf_name);
|
||||
SwingUtilities.updateComponentTreeUI(this);
|
||||
consoleTextArea.postUpdateUI();
|
||||
// updateComponentTreeUI seems to mess up the file
|
||||
// chooser dialog, so just create a new one
|
||||
createFileChooser();
|
||||
} catch(Exception exc) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
exc.getMessage(),
|
||||
"Platform",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
Загрузка…
Ссылка в новой задаче