1Index: toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java 2=================================================================== 3--- toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java (revision 1) 4+++ misc/build/rhino1_7R3/toolsrc/org/mozilla/javascript/tools/debugger/GuiCallback.java (working copy) 5@@ -56,6 +56,11 @@ 6 String threadTitle, 7 String alertMessage); 8 9+ /** 10+ * Called when the interrupt loop has been exited. 11+ */ 12+ void exitInterrupt(); 13+ 14 /** 15 * Returns whether the current thread is the GUI's event thread. 16 * This information is required to avoid blocking the event thread 17Index: toolsrc/org/mozilla/javascript/tools/debugger/Main.java 18=================================================================== 19--- toolsrc/org/mozilla/javascript/tools/debugger/Main.java (revision 1) 20+++ misc/build/rhino1_7R3/toolsrc/org/mozilla/javascript/tools/debugger/Main.java (working copy) 21@@ -44,6 +44,8 @@ 22 import java.io.InputStream; 23 import java.io.PrintStream; 24 25+import java.net.URL; 26+ 27 import javax.swing.JFrame; 28 29 import org.mozilla.javascript.*; 30@@ -161,7 +163,7 @@ 31 * Console window. 32 */ 33 public InputStream getIn() { 34- return debugGui.getConsole().getIn(); 35+ return null;//return debugGui.getConsole().getIn(); 36 } 37 38 /** 39@@ -169,7 +171,7 @@ 40 * Console window. 41 */ 42 public PrintStream getOut() { 43- return debugGui.getConsole().getOut(); 44+ return null;//return debugGui.getConsole().getOut(); 45 } 46 47 /** 48@@ -177,7 +179,7 @@ 49 * Console window. 50 */ 51 public PrintStream getErr() { 52- return debugGui.getConsole().getErr(); 53+ return null;//return debugGui.getConsole().getErr(); 54 } 55 56 /** 57@@ -437,4 +439,39 @@ 58 return scope; 59 } 60 } 61+ 62+ // shortcut methods 63+ 64+ public void addWindowListener(java.awt.event.WindowListener l) { 65+ debugGui.addWindowListener(l); 66+ } 67+ 68+ public void highlighLineInScriptWindow(URL url, int lineNum) { 69+ debugGui.highlighLineInScriptWindow(url, lineNum); 70+ } 71+ 72+ public Object runScriptWindow(URL scriptUrl) throws Exception 73+ { 74+ return debugGui.runScriptWindow(scriptUrl); 75+ } 76+ 77+ public void openFile(URL scriptUrl, Scriptable scope, Runnable closeCallback) { 78+ debugGui.openFile(scriptUrl, scope, closeCallback); 79+ } 80+ 81+ public void toFront() { 82+ debugGui.toFront(); 83+ } 84+ 85+ public void showScriptWindow(URL url) { 86+ debugGui.showScriptWindow(url); 87+ } 88+ 89+ public boolean isModified(URL url) { 90+ return debugGui.isModified(url); 91+ } 92+ 93+ public String getText(URL url) { 94+ return debugGui.getText(url); 95+ } 96 } 97Index: toolsrc/org/mozilla/javascript/tools/debugger/Dim.java 98=================================================================== 99--- toolsrc/org/mozilla/javascript/tools/debugger/Dim.java (revision 1) 100+++ misc/build/rhino1_7R3/toolsrc/org/mozilla/javascript/tools/debugger/Dim.java (working copy) 101@@ -69,6 +69,7 @@ 102 private static final int IPROXY_OBJECT_TO_STRING = 5; 103 private static final int IPROXY_OBJECT_PROPERTY = 6; 104 private static final int IPROXY_OBJECT_IDS = 7; 105+ private static final int IPROXY_EVAL_SCRIPT_WITH_RETURN = 8; 106 107 /** 108 * Interface to the debugger GUI. 109@@ -433,7 +434,7 @@ 110 */ 111 private String getNormalizedUrl(DebuggableScript fnOrScript) { 112 String url = fnOrScript.getSourceName(); 113- if (url == null) { url = "<stdin>"; } 114+ if (url == null) { url = "document"; } 115 else { 116 // Not to produce window for eval from different lines, 117 // strip line numbers, i.e. replace all #[0-9]+\(eval\) by 118@@ -622,6 +623,17 @@ 119 } 120 121 /** 122+ * Evaluates the given script with scope and return value. 123+ */ 124+ public Object evalScriptWithReturn(final String url, final String text, Scriptable scope) { 125+ DimIProxy action = new DimIProxy(this, IPROXY_EVAL_SCRIPT_WITH_RETURN); 126+ action.url = url; 127+ action.text = text; 128+ action.scope = scope; 129+ return contextFactory.call(action); 130+ } 131+ 132+ /** 133 * Converts the given script object to a string. 134 */ 135 public String objectToString(Object object) { 136@@ -869,6 +881,7 @@ 137 interruptedContextData = null; 138 eventThreadMonitor.notifyAll(); 139 } 140+ callback.exitInterrupt(); 141 } 142 143 } 144@@ -966,6 +979,11 @@ 145 private Object[] objectArrayResult; 146 147 /** 148+ * The Scriptable as arguments. 149+ */ 150+ private Scriptable scope; 151+ 152+ /** 153 * Creates a new DimIProxy. 154 */ 155 private DimIProxy(Dim dim, int type) { 156@@ -1021,6 +1039,9 @@ 157 objectArrayResult = dim.getObjectIdsImpl(cx, object); 158 break; 159 160+ case IPROXY_EVAL_SCRIPT_WITH_RETURN: 161+ return cx.evaluateString(this.scope, text, url, 1, null); 162+ 163 default: 164 throw Kit.codeBug(); 165 } 166Index: toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java 167=================================================================== 168--- toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java (revision 1) 169+++ misc/build/rhino1_7R3/toolsrc/org/mozilla/javascript/tools/debugger/SwingGui.java (working copy) 170@@ -68,6 +68,8 @@ 171 import java.awt.Toolkit; 172 import java.awt.event.*; 173 174+import java.net.URL; 175+ 176 import java.util.List; 177 import java.util.ArrayList; 178 import java.util.Arrays; 179@@ -84,6 +86,7 @@ 180 import java.lang.reflect.Method; 181 182 import org.mozilla.javascript.Kit; 183+import org.mozilla.javascript.Scriptable; 184 import org.mozilla.javascript.SecurityUtilities; 185 186 import org.mozilla.javascript.tools.shell.ConsoleTextArea; 187@@ -178,6 +181,16 @@ 188 */ 189 private EventQueue awtEventQueue; 190 191+ private boolean sourceEditingEnabled = true; 192+ 193+ public boolean isSourceEditingEnabled() { 194+ return sourceEditingEnabled; 195+ } 196+ 197+ public void setSourceEditingEnabled(boolean b) { 198+ sourceEditingEnabled = b; 199+ } 200+ 201 /** 202 * Creates a new SwingGui. 203 */ 204@@ -218,13 +231,13 @@ 205 super.setVisible(b); 206 if (b) { 207 // this needs to be done after the window is visible 208- console.consoleTextArea.requestFocus(); 209+ // console.consoleTextArea.requestFocus(); 210 context.split.setDividerLocation(0.5); 211 try { 212- console.setMaximum(true); 213- console.setSelected(true); 214- console.show(); 215- console.consoleTextArea.requestFocus(); 216+ // console.setMaximum(true); 217+ // console.setSelected(true); 218+ // console.show(); 219+ // console.consoleTextArea.requestFocus(); 220 } catch (Exception exc) { 221 } 222 } 223@@ -320,7 +333,7 @@ 224 desk = new JDesktopPane(); 225 desk.setPreferredSize(new Dimension(600, 300)); 226 desk.setMinimumSize(new Dimension(150, 50)); 227- desk.add(console = new JSInternalConsole("JavaScript Console")); 228+ // desk.add(console = new JSInternalConsole("JavaScript Console")); 229 context = new ContextWindow(this); 230 context.setPreferredSize(new Dimension(600, 120)); 231 context.setMinimumSize(new Dimension(50, 50)); 232@@ -540,7 +553,7 @@ 233 if (line != -1) { 234 currentWindow = w; 235 } 236- menubar.addFile(url); 237+ // menubar.addFile(url); 238 w.setVisible(true); 239 240 if (activate) { 241@@ -800,9 +813,17 @@ 242 proxy.alertMessage = alertMessage; 243 SwingUtilities.invokeLater(proxy); 244 } 245+ setSourceEditingEnabled(false); 246 } 247 248 /** 249+ * Called when the interrupt loop has been exited. 250+ */ 251+ public void exitInterrupt() { 252+ setSourceEditingEnabled(true); 253+ } 254+ 255+ /** 256 * Returns whether the current thread is the GUI event thread. 257 */ 258 public boolean isGuiEventThread() { 259@@ -879,6 +900,14 @@ 260 new Thread(proxy).start(); 261 } 262 } 263+ } else if (cmd.equals("Run")) { 264+ FileWindow w = (FileWindow)getSelectedFrame(); 265+ if (w != null) 266+ w.load(); 267+ } else if (cmd.equals("Save")) { 268+ FileWindow w = (FileWindow)getSelectedFrame(); 269+ if (w != null) 270+ w.save(); 271 } else if (cmd.equals("More Windows...")) { 272 MoreWindows dlg = new MoreWindows(this, fileWindows, 273 "Window", "Files"); 274@@ -972,6 +1001,120 @@ 275 dim.setReturnValue(returnValue); 276 } 277 } 278+ 279+ private String getFileName(URL url) { 280+ if (url.getProtocol().startsWith("vnd.sun.star.")) 281+ return url.toString(); 282+ return url.getPath(); 283+ } 284+ 285+ public void openFile(URL scriptUrl, Scriptable scope, Runnable closeCallback) { 286+ if (scope == null) { 287+ MessageDialogWrapper.showMessageDialog(this, 288+ "Can't compile scripts: no scope available", 289+ "Open", JOptionPane.ERROR_MESSAGE); 290+ } else { 291+ if (scriptUrl != null) { 292+ try 293+ { 294+ InputStreamReader reader = new InputStreamReader(scriptUrl.openStream()); 295+ String fileName = getFileName(scriptUrl); 296+ officeScripts.addScript( fileName, scriptUrl, scope, closeCallback ); 297+ RunProxy proxy = new RunProxy(this, RunProxy.OPEN_FILE); 298+ proxy.fileName = fileName; 299+ proxy.text = Kit.readReader(reader); 300+ new Thread(proxy).start(); 301+ } 302+ catch ( IOException e ) 303+ { 304+ MessageDialogWrapper.showMessageDialog(this, 305+ "Can't open stream for script: " + e.toString(), 306+ "Open", JOptionPane.ERROR_MESSAGE); 307+ } 308+ } 309+ } 310+ split1.setDividerLocation(1.0); 311+ } 312+ 313+ // patched Office specific interface 314+ OfficeScriptInfo officeScripts = new OfficeScriptInfo(); 315+ 316+ void removeScript(String url) { 317+ officeScripts.deleteScript(url); 318+ } 319+ 320+ public void showScriptWindow(URL url) { 321+ String key = getFileName(url); 322+ FileWindow w = (FileWindow)getFileWindow(key); 323+ if (w != null) 324+ { 325+ desk.getDesktopManager().deiconifyFrame(w); 326+ desk.getDesktopManager().activateFrame(w); 327+ w.show(); 328+ w.toFront(); 329+ } 330+ } 331+ 332+ public void highlighLineInScriptWindow(URL url, int lineNum) { 333+ String key = getFileName(url); 334+ FileWindow w = (FileWindow)getFileWindow(key); 335+ if (w != null) 336+ { 337+ showFileWindow(key, lineNum); 338+ } 339+ } 340+ 341+ public Object runScriptWindow(URL scriptUrl) throws Exception 342+ { 343+ String key = getFileName(scriptUrl); 344+ FileWindow w = (FileWindow)getFileWindow(key); 345+ Object result = null; 346+ w.toFront(); 347+ if (w != null) 348+ { 349+ Scriptable scope = officeScripts.getScriptScope(key); 350+ if (scope == null) 351+ { 352+ MessageDialogWrapper.showMessageDialog(this, "Can't load scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE); 353+ } 354+ else 355+ { 356+ String url = w.getUrl(); 357+ if (url != null) 358+ { 359+ if (officeScripts.isScriptRunning(key)) 360+ { 361+ return result; 362+ } 363+ officeScripts.setScriptRunning(key, true); 364+ try { 365+ result = dim.evalScriptWithReturn(url, w.textArea.getText(), scope); 366+ } catch (Exception exc) { 367+ exc.printStackTrace(); 368+ throw exc; 369+ } finally { 370+ officeScripts.setScriptRunning(key, false); 371+ } 372+ } 373+ } 374+ } 375+ return result; 376+ } 377+ 378+ public boolean isModified(URL url) 379+ { 380+ String key = getFileName(url); 381+ FileWindow w = (FileWindow)getFileWindow(key); 382+ return w.isModified(); 383+ } 384+ 385+ public String getText(URL url) 386+ { 387+ String key = getFileName(url); 388+ FileWindow w = (FileWindow)getFileWindow(key); 389+ return w.getText(); 390+ } 391+ 392 } 393 394 /** 395@@ -1590,7 +1733,9 @@ 396 case KeyEvent.VK_ENTER: 397 case KeyEvent.VK_DELETE: 398 case KeyEvent.VK_TAB: 399- e.consume(); 400+ if (! w.isEditable()) { 401+ e.consume(); 402+ } 403 break; 404 } 405 } 406@@ -1599,14 +1744,18 @@ 407 * Called when a key is typed. 408 */ 409 public void keyTyped(KeyEvent e) { 410- e.consume(); 411+ if (! w.isEditable()) { 412+ e.consume(); 413+ } 414 } 415 416 /** 417 * Called when a key is released. 418 */ 419 public void keyReleased(KeyEvent e) { 420- e.consume(); 421+ if (! w.isEditable()) { 422+ e.consume(); 423+ } 424 } 425 } 426 427@@ -2089,7 +2238,7 @@ 428 /** 429 * An internal frame for script files. 430 */ 431-class FileWindow extends JInternalFrame implements ActionListener { 432+class FileWindow extends JInternalFrame implements ActionListener, DocumentListener { 433 434 /** 435 * Serializable magic number. 436@@ -2126,6 +2275,7 @@ 437 */ 438 int currentPos; 439 440+ boolean isModified = false; 441 /** 442 * Loads the file. 443 */ 444@@ -2134,11 +2284,62 @@ 445 if (url != null) { 446 RunProxy proxy = new RunProxy(debugGui, RunProxy.LOAD_FILE); 447 proxy.fileName = url; 448- proxy.text = sourceInfo.source(); 449+ proxy.text = textArea.getText(); 450+ proxy.scope = debugGui.officeScripts.getScriptScope(url); 451 new Thread(proxy).start(); 452 } 453 } 454 455+ void save() { 456+ String url = getUrl(); 457+ if (url != null) { 458+ OutputStream os = null; 459+ try { 460+ if (url.startsWith("vnd.sun.star")) 461+ { 462+ URL scriptUrl = debugGui.officeScripts.getScriptUrl(url); 463+ if ( scriptUrl == null ) 464+ { 465+ throw new IOException("Can't optain stream for " + url); 466+ } 467+ os = scriptUrl.openConnection().getOutputStream(); 468+ } 469+ else 470+ { 471+ os = new FileOutputStream(url); 472+ } 473+ String s = textArea.getText(); 474+ os.write(s.getBytes(), 0, s.length()); 475+ 476+ this.isModified = false; 477+ } catch (IOException ioe) { 478+ MessageDialogWrapper.showMessageDialog(this, 479+ "Error saving file: " + ioe.getMessage(), 480+ "Error", JOptionPane.ERROR_MESSAGE); 481+ } 482+ finally 483+ { 484+ if ( os != null ) 485+ { 486+ try 487+ { 488+ os.close(); 489+ os = null; 490+ } 491+ catch( IOException ioe ) 492+ { 493+ System.err.println("Error closing stream: " + ioe.getMessage() ); 494+ ioe.printStackTrace(); 495+ } 496+ } 497+ } 498+ } 499+ } 500+ 501+ public boolean isEditable() { 502+ return debugGui.isSourceEditingEnabled(); 503+ } 504+ 505 /** 506 * Returns the offset position for the given line. 507 */ 508@@ -2214,7 +2415,16 @@ 509 pack(); 510 updateText(sourceInfo); 511 textArea.select(0); 512+ addInternalFrameListener( new InternalFrameAdapter() { 513+ public void internalFrameClosed(InternalFrameEvent e) { 514+ getDebugGui().removeScript( getUrl() ); 515+ } 516+ } ); 517 } 518+ 519+ public SwingGui getDebugGui() { 520+ return debugGui; 521+ } 522 523 /** 524 * Updates the tool tip contents. 525@@ -2249,7 +2459,10 @@ 526 this.sourceInfo = sourceInfo; 527 String newText = sourceInfo.source(); 528 if (!textArea.getText().equals(newText)) { 529+ textArea.getDocument().removeDocumentListener(this); 530 textArea.setText(newText); 531+ this.isModified = false; 532+ textArea.getDocument().addDocumentListener(this); 533 int pos = 0; 534 if (currentPos != -1) { 535 pos = currentPos; 536@@ -2260,6 +2473,31 @@ 537 fileHeader.repaint(); 538 } 539 540+ /* Implementation of DocumentListener interface */ 541+ public void insertUpdate(DocumentEvent e) { 542+ doChanged(e); 543+ } 544+ 545+ public void removeUpdate(DocumentEvent e) { 546+ doChanged(e); 547+ } 548+ 549+ public void changedUpdate(DocumentEvent e) { 550+ doChanged(e); 551+ } 552+ 553+ public void doChanged(DocumentEvent e) { 554+ this.isModified = true; 555+ } 556+ 557+ public boolean isModified() { 558+ return this.isModified; 559+ } 560+ 561+ public String getText() { 562+ return textArea.getText(); 563+ } 564+ 565 /** 566 * Sets the cursor position. 567 */ 568@@ -2295,11 +2533,11 @@ 569 public void actionPerformed(ActionEvent e) { 570 String cmd = e.getActionCommand(); 571 if (cmd.equals("Cut")) { 572- // textArea.cut(); 573+ textArea.cut(); 574 } else if (cmd.equals("Copy")) { 575 textArea.copy(); 576 } else if (cmd.equals("Paste")) { 577- // textArea.paste(); 578+ textArea.paste(); 579 } 580 } 581 } 582@@ -2920,7 +3158,7 @@ 583 */ 584 public ContextWindow(final SwingGui debugGui) { 585 this.debugGui = debugGui; 586- enabled = false; 587+ enabled = true; 588 JPanel left = new JPanel(); 589 JToolBar t1 = new JToolBar(); 590 t1.setName("Variables"); 591@@ -3161,6 +3399,10 @@ 592 public void enableUpdate() { 593 enabled = true; 594 } 595+ 596+ public boolean isEnabled() { 597+ return enabled; 598+ } 599 600 // ActionListener 601 602@@ -3249,8 +3491,10 @@ 603 Menubar(SwingGui debugGui) { 604 super(); 605 this.debugGui = debugGui; 606- String[] fileItems = {"Open...", "Run...", "", "Exit"}; 607- String[] fileCmds = {"Open", "Load", "", "Exit"}; 608+ // String[] fileItems = {"Open...", "Run...", "", "Exit"}; 609+ // String[] fileCmds = {"Open", "Load", "", "Exit"}; 610+ String[] fileItems = {"Run", "Save", "", "Exit"}; 611+ String[] fileCmds = {"Run", "Save", "", "Exit"}; 612 char[] fileShortCuts = {'0', 'N', 0, 'X'}; 613 int[] fileAccelerators = {KeyEvent.VK_O, 614 KeyEvent.VK_N, 615@@ -3299,6 +3543,8 @@ 616 editShortCuts[i]); 617 item.addActionListener(this); 618 editMenu.add(item); 619+ if (i < 3) 620+ runOnlyItems.add(item); 621 } 622 for (int i = 0; i < plafItems.length; ++i) { 623 JMenuItem item = new JMenuItem(plafItems[i], 624@@ -3348,9 +3594,9 @@ 625 item.addActionListener(this); 626 windowMenu.add(item = new JMenuItem("Tile", 'T')); 627 item.addActionListener(this); 628- windowMenu.addSeparator(); 629- windowMenu.add(item = new JMenuItem("Console", 'C')); 630- item.addActionListener(this); 631+ // windowMenu.addSeparator(); 632+ // windowMenu.add(item = new JMenuItem("Console", 'C')); 633+ // item.addActionListener(this); 634 add(windowMenu); 635 636 updateEnabled(false); 637@@ -3530,6 +3776,11 @@ 638 * interruption, if any. 639 */ 640 String alertMessage; 641+ 642+ /** 643+ * The arguments for evaluation. 644+ */ 645+ Scriptable scope; 646 647 /** 648 * Creates a new RunProxy. 649@@ -3556,7 +3807,10 @@ 650 651 case LOAD_FILE: 652 try { 653- debugGui.dim.evalScript(fileName, text); 654+ if (scope != null) 655+ debugGui.dim.evalScriptWithReturn(fileName, text, scope); 656+ else 657+ debugGui.dim.evalScript(fileName, text); 658 } catch (RuntimeException ex) { 659 MessageDialogWrapper.showMessageDialog( 660 debugGui, ex.getMessage(), "Run error for "+fileName, 661Index: toolsrc/org/mozilla/javascript/tools/debugger/OfficeScriptInfo.java 662=================================================================== 663--- toolsrc/org/mozilla/javascript/tools/debugger/OfficeScriptInfo.java (revision 2) 664+++ misc/build/rhino1_7R3/toolsrc/org/mozilla/javascript/tools/debugger/OfficeScriptInfo.java (working copy) 665@@ -1 +1,124 @@ 666-dummy 667+/************************************************************** 668+ * 669+ * Licensed to the Apache Software Foundation (ASF) under one 670+ * or more contributor license agreements. See the NOTICE file 671+ * distributed with this work for additional information 672+ * regarding copyright ownership. The ASF licenses this file 673+ * to you under the Apache License, Version 2.0 (the 674+ * "License"); you may not use this file except in compliance 675+ * with the License. You may obtain a copy of the License at 676+ * 677+ * http://www.apache.org/licenses/LICENSE-2.0 678+ * 679+ * Unless required by applicable law or agreed to in writing, 680+ * software distributed under the License is distributed on an 681+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 682+ * KIND, either express or implied. See the License for the 683+ * specific language governing permissions and limitations 684+ * under the License. 685+ * 686+ *************************************************************/ 687+ 688+ 689+package org.mozilla.javascript.tools.debugger; 690+import java.net.URL; 691+import java.util.Hashtable; 692+import org.mozilla.javascript.Scriptable; 693+ 694+public class OfficeScriptInfo 695+{ 696+ private Hashtable<String, SFScriptInfo> loadedSFScripts = new Hashtable<String, SFScriptInfo>(); 697+ 698+ public void addScript( URL url, Scriptable scope, Runnable closeCallback ) 699+ { 700+ addScript( url.toString(), url, scope, closeCallback ); 701+ } 702+ 703+ public void addScript( String key, URL url, Scriptable scope, Runnable closeCallback ) 704+ { 705+ SFScriptInfo si = (SFScriptInfo)loadedSFScripts.get( key ); 706+ if ( si == null ) 707+ { 708+ si = new SFScriptInfo(); 709+ si.url = url; 710+ si.scope = scope; 711+ si.closeCallback = closeCallback; 712+ loadedSFScripts.put( key, si ); 713+ } 714+ } 715+ 716+ public void deleteScript( String key ) 717+ { 718+ SFScriptInfo info = (SFScriptInfo)loadedSFScripts.remove( key ); 719+ if ( info != null ) 720+ { 721+ if ( info.closeCallback != null ) 722+ { 723+ System.out.println("** In removeSFScriptInfo have callback for " + key ); 724+ info.closeCallback.run(); // really need to do this in separate thread???? 725+ } 726+ } 727+ } 728+ 729+ public Scriptable getScriptScope( String key ) 730+ { 731+ Scriptable result = null; 732+ SFScriptInfo info = (SFScriptInfo)loadedSFScripts.get( key ); 733+ if ( info != null ) 734+ { 735+ result = info.scope; 736+ } 737+ return result; 738+ } 739+ 740+ public URL getScriptUrl( String key ) 741+ { 742+ URL result = null; 743+ SFScriptInfo info = (SFScriptInfo)loadedSFScripts.get( key ); 744+ if ( info != null ) 745+ { 746+ result = info.url; 747+ } 748+ return result; 749+ } 750+ public boolean hasScript( String key ) 751+ { 752+ boolean result = true; 753+ SFScriptInfo info = (SFScriptInfo)loadedSFScripts.get( key ); 754+ if ( info == null ) 755+ { 756+ result = false; 757+ } 758+ return result; 759+ } 760+ 761+ public void setScriptRunning( String key, boolean running ) 762+ { 763+ SFScriptInfo info = (SFScriptInfo)loadedSFScripts.get( key ); 764+ if ( info != null ) 765+ { 766+ info.isExecuting = running; 767+ } 768+ } 769+ 770+ public boolean isScriptRunning( String key ) 771+ { 772+ boolean result = false; 773+ SFScriptInfo info = (SFScriptInfo)loadedSFScripts.get( key ); 774+ if ( info != null ) 775+ { 776+ result = info.isExecuting; 777+ } 778+ return result; 779+ } 780+ 781+ 782+ 783+ class SFScriptInfo 784+ { 785+ Scriptable scope; 786+ boolean isExecuting; 787+ URL url; 788+ Runnable closeCallback; 789+ } 790+} 791Index: toolsrc/build.xml 792=================================================================== 793--- toolsrc/build.xml (revision 1) 794+++ misc/build/rhino1_7R3/toolsrc/build.xml (working copy) 795@@ -40,6 +40,24 @@ 796 --> 797 <project name="toolsrc" default="compile" basedir=".."> 798 799+ <condition property="boot_refID" value="macPath" else="nonMacPath"> 800+ <and> 801+ <os family="mac"/> 802+ <os family="unix"/> 803+ </and> 804+ </condition> 805+ <path id="macPath" location="${java.home}/../Classes/classes.jar"/> 806+ <!-- rhino.jar from OpenJDK breaks build --> 807+ <path id="nonMacPath"> 808+ <fileset dir="${java.home}/"> 809+ <include name="jre/lib/*.jar"/> 810+ <include name="lib/*.jar"/> 811+ <exclude name="jre/lib/rhino.jar"/> 812+ <exclude name="lib/rhino.jar"/> 813+ </fileset> 814+ </path> 815+ <path id="my.bootstrap.classpath" refID="${boot_refID}"/> 816+ 817 <target name="properties"> 818 <property file="build.properties"/> 819 </target> 820Index: src/org/mozilla/javascript/DefiningClassLoader.java 821=================================================================== 822--- src/org/mozilla/javascript/DefiningClassLoader.java (revision 1) 823+++ misc/build/rhino1_7R3/src/org/mozilla/javascript/DefiningClassLoader.java (working copy) 824@@ -39,6 +39,8 @@ 825 826 package org.mozilla.javascript; 827 828+import java.lang.reflect.Method; 829+import java.lang.reflect.InvocationTargetException; 830 /** 831 * Load generated classes. 832 * 833@@ -48,13 +50,33 @@ 834 implements GeneratedClassLoader 835 { 836 public DefiningClassLoader() { 837- this.parentLoader = getClass().getClassLoader(); 838+ this.parentLoader = getClass().getClassLoader(); 839+ init(); 840 } 841 842 public DefiningClassLoader(ClassLoader parentLoader) { 843- this.parentLoader = parentLoader; 844+ this.parentLoader = parentLoader; 845+ init(); 846 } 847 848+ private void init() { 849+ this.contextLoader = null; 850+ if (method_getContextClassLoader != null) { 851+ try { 852+ this.contextLoader = (ClassLoader) 853+ method_getContextClassLoader.invoke( 854+ Thread.currentThread(), 855+ ScriptRuntime.emptyArgs); 856+ } catch (IllegalAccessException ex) { 857+ } catch (InvocationTargetException ex) { 858+ } catch (SecurityException ex) { 859+ } 860+ if (this.contextLoader == this.parentLoader) { 861+ this.contextLoader = null; 862+ } 863+ } 864+ } 865+ 866 public Class<?> defineClass(String name, byte[] data) { 867 // Use our own protection domain for the generated classes. 868 // TODO: we might want to use a separate protection domain for classes 869@@ -73,10 +95,14 @@ 870 { 871 Class<?> cl = findLoadedClass(name); 872 if (cl == null) { 873- if (parentLoader != null) { 874- cl = parentLoader.loadClass(name); 875+ if (contextLoader == null) { 876+ cl = loadFromParent(name); 877 } else { 878- cl = findSystemClass(name); 879+ try { 880+ cl = loadFromParent(name); 881+ } catch (ClassNotFoundException ex) { 882+ cl = contextLoader.loadClass(name); 883+ } 884 } 885 } 886 if (resolve) { 887@@ -85,5 +111,36 @@ 888 return cl; 889 } 890 891+ private Class loadFromParent(String name) 892+ throws ClassNotFoundException 893+ { 894+ if (parentLoader != null) { 895+ return parentLoader.loadClass(name); 896+ } else { 897+ return findSystemClass(name); 898+ } 899+ } 900+ 901 private final ClassLoader parentLoader; 902+ 903+ private ClassLoader contextLoader; 904+ 905+ // We'd like to use "Thread.getContextClassLoader", but 906+ // that's only available on Java2. 907+ private static Method method_getContextClassLoader; 908+ 909+ static { 910+ try { 911+ // Don't use "Thread.class": that performs the lookup 912+ // in the class initializer, which doesn't allow us to 913+ // catch possible security exceptions. 914+ Class threadClass = Class.forName("java.lang.Thread"); 915+ method_getContextClassLoader = 916+ threadClass.getDeclaredMethod("getContextClassLoader", 917+ new Class[0]); 918+ } catch (ClassNotFoundException e) { 919+ } catch (NoSuchMethodException e) { 920+ } catch (SecurityException e) { 921+ } 922+ } 923 } 924