📄 javascript.java
字号:
package com.meterware.httpunit.javascript;/******************************************************************************************************************** * $Id: JavaScript.java,v 1.63 2004/12/02 03:43:20 russgold Exp $ * * Copyright (c) 2002-2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/import com.meterware.httpunit.*;import com.meterware.httpunit.scripting.*;import java.lang.reflect.InvocationTargetException;import java.util.ArrayList;import java.io.IOException;import java.net.URL;import org.mozilla.javascript.*;import org.xml.sax.SAXException;/** * This class is the Rhino-compatible implementation of the JavaScript DOM objects. * * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a> **/public class JavaScript { private final static Object[] NO_ARGS = new Object[0]; private static boolean _throwExceptionsOnError = true; private static ArrayList _errorMessages = new ArrayList(); static boolean isThrowExceptionsOnError() { return _throwExceptionsOnError; } static void setThrowExceptionsOnError( boolean throwExceptionsOnError ) { _throwExceptionsOnError = throwExceptionsOnError; } static void clearErrorMessages() { _errorMessages.clear(); } static String[] getErrorMessages() { return (String[]) _errorMessages.toArray( new String[ _errorMessages.size() ] ); } /** * Initiates JavaScript execution for the specified web response. */ static void run( WebResponse response ) throws IllegalAccessException, InstantiationException, InvocationTargetException, ClassDefinitionException, NotAFunctionException, PropertyException, SAXException, JavaScriptException { Context context = Context.enter(); Scriptable scope = context.initStandardObjects( null ); initHTMLObjects( scope ); Window w = (Window) context.newObject( scope, "Window" ); w.initialize( null, response.getScriptableObject() ); } /** * Runs the onload event for the specified web response. */ public static void load( WebResponse response ) throws ClassDefinitionException, InstantiationException, IllegalAccessException, InvocationTargetException, PropertyException, JavaScriptException, SAXException, NotAFunctionException { if (!(response.getScriptableObject().getScriptEngine() instanceof JavaScriptEngine)) run( response ); response.getScriptableObject().load(); } private static void initHTMLObjects( Scriptable scope ) throws IllegalAccessException, InstantiationException, InvocationTargetException, ClassDefinitionException, PropertyException { ScriptableObject.defineClass( scope, Window.class ); ScriptableObject.defineClass( scope, Document.class ); ScriptableObject.defineClass( scope, Style.class ); ScriptableObject.defineClass( scope, Location.class ); ScriptableObject.defineClass( scope, Navigator.class ); ScriptableObject.defineClass( scope, Screen.class ); ScriptableObject.defineClass( scope, Link.class ); ScriptableObject.defineClass( scope, Form.class ); ScriptableObject.defineClass( scope, Control.class ); ScriptableObject.defineClass( scope, Link.class ); ScriptableObject.defineClass( scope, Image.class ); ScriptableObject.defineClass( scope, Options.class ); ScriptableObject.defineClass( scope, Option.class ); ScriptableObject.defineClass( scope, ElementArray.class ); ScriptableObject.defineClass( scope, HTMLElement.class ); } abstract static class JavaScriptEngine extends ScriptableObject implements ScriptingEngine { protected ScriptableDelegate _scriptable; protected JavaScriptEngine _parent; public boolean supportsScriptLanguage( String language ) { return language == null || language.toLowerCase().startsWith( "javascript" ); } public String executeScript( String language, String script ) { if (!supportsScriptLanguage( language )) return ""; try { script = script.trim(); if (script.startsWith( "<!--" )) { script = withoutFirstLine( script ); if (script.endsWith( "-->" )) script = script.substring( 0, script.lastIndexOf( "-->" )); } Context.getCurrentContext().evaluateString( this, script, "httpunit", 0, null ); StringBuffer buffer = getDocumentWriteBuffer(); return buffer.toString(); } catch (Exception e) { handleScriptException( e, "Script '" + script + "'" ); return ""; } finally { discardDocumentWriteBuffer(); } } protected StringBuffer getDocumentWriteBuffer() { throw new IllegalStateException( "may not run executeScript() from " + getClass() ); } protected void discardDocumentWriteBuffer() { throw new IllegalStateException( "may not run executeScript() from " + getClass() ); } private String withoutFirstLine( String script ) { for (int i=0; i < script.length(); i++) { if (isLineTerminator( script.charAt(i) )) return script.substring( i ).trim(); } return ""; } private boolean isLineTerminator( char c ) { return c == 0x0A || c == 0x0D; } public boolean performEvent( String eventScript ) { try { final Context context = Context.getCurrentContext(); context.setOptimizationLevel( -1 ); Function f = context.compileFunction( this, "function x() { " + eventScript + "}", "httpunit", 0, null ); Object result = f.call( context, this, this, NO_ARGS ); return (result instanceof Boolean) ? ((Boolean) result).booleanValue() : true; } catch (Exception e) { handleScriptException( e, "Event '" + eventScript + "'" ); return false; } } /** * Evaluates the specified string as JavaScript. Will return null if the script has no return value. */ public String evaluateScriptExpression( String urlString ) { try { Object result = Context.getCurrentContext().evaluateString( this, urlString, "httpunit", 0, null ); return (result == null || result instanceof Undefined) ? null : result.toString(); } catch (Exception e) { handleScriptException( e, "URL '" + urlString + "'" ); return null; } } private void handleScriptException( Exception e, String badScript ) { final String errorMessage = badScript + " failed: " + e; if (!(e instanceof EcmaError) && !(e instanceof EvaluatorException)) { e.printStackTrace(); throw new RuntimeException( errorMessage ); } else if (isThrowExceptionsOnError()) { e.printStackTrace(); throw new ScriptException( errorMessage ); } else { _errorMessages.add( errorMessage ); } } void initialize( JavaScriptEngine parent, ScriptableDelegate scriptable ) throws SAXException, PropertyException, JavaScriptException, NotAFunctionException { _scriptable = scriptable; _scriptable.setScriptEngine( this ); _parent = parent; if (parent != null) setParentScope( parent ); } String getName() { return _scriptable instanceof NamedDelegate ? ((NamedDelegate) _scriptable).getName() : ""; } String getID() { return _scriptable instanceof IdentifiedDelegate ? ((IdentifiedDelegate) _scriptable).getID() : ""; } public boolean has( String propertyName, Scriptable scriptable ) { return super.has( propertyName, scriptable ) || (_scriptable != null && _scriptable.get( propertyName ) != null); } public Object get( String propertyName, Scriptable scriptable ) { Object result = super.get( propertyName, scriptable ); if (result != NOT_FOUND) return result; if (_scriptable == null) return NOT_FOUND; return convertIfNeeded( _scriptable.get( propertyName ) ); } public Object get( int i, Scriptable scriptable ) { Object result = super.get( i, scriptable ); if (result != NOT_FOUND) return result; if (_scriptable == null) return NOT_FOUND; return convertIfNeeded( _scriptable.get( i ) ); } private Object convertIfNeeded( final Object property ) { if (property == null) return NOT_FOUND; if (property instanceof ScriptableDelegate[]) return toScriptable( (ScriptableDelegate[]) property ); if (!(property instanceof ScriptableDelegate)) return property; return toScriptable( (ScriptableDelegate) property ); } private Object toScriptable( ScriptableDelegate[] list ) { Object[] delegates = new Object[ list.length ]; for (int i = 0; i < delegates.length; i++) { delegates[i] = toScriptable( list[i] ); } return Context.getCurrentContext().newArray( this, delegates ); } public void put( String propertyName, Scriptable scriptable, Object value ) { if (_scriptable == null || _scriptable.get( propertyName ) == null) { super.put( propertyName, scriptable, value ); } else { _scriptable.set( propertyName, value ); } } public String toString() { return (_scriptable == null ? "prototype " : "") + getClassName(); } public ScriptingEngine newScriptingEngine( ScriptableDelegate child ) { try { return (ScriptingEngine) toScriptable( child ); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException( e.toString() ); } } public void clearCaches() { } protected static String toStringIfNotUndefined( Object object ) { return (object == null || Undefined.instance.equals( object )) ? null : object.toString(); } /** * Converts a scriptable delegate obtained from a subobject into the appropriate Rhino-compatible Scriptable. **/ final Object toScriptable( ScriptableDelegate delegate ) { if (delegate == null) { return NOT_FOUND; } else if (delegate.getScriptEngine() instanceof Scriptable) { return (Scriptable) delegate.getScriptEngine(); } else { try { JavaScriptEngine element = (JavaScriptEngine) Context.getCurrentContext().newObject( this, getScriptableClassName( delegate ) ); element.initialize( this, delegate ); return element; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RhinoException( e ); } } } private String getScriptableClassName( ScriptableDelegate delegate ) { if (delegate instanceof WebResponse.Scriptable) return "Window"; if (delegate instanceof HTMLPage.Scriptable) return "Document"; if (delegate instanceof WebForm.Scriptable) return "Form"; if (delegate instanceof WebLink.Scriptable) return "Link"; if (delegate instanceof WebImage.Scriptable) return "Image"; if (delegate instanceof SelectionOptions) return "Options"; if (delegate instanceof SelectionOption) return "Option"; if (delegate instanceof Input) return "Control"; if (delegate instanceof DocumentElement) return "HTMLElement"; throw new IllegalArgumentException( "Unknown ScriptableDelegate class: " + delegate.getClass() ); } protected ElementArray toElementArray( ScriptableDelegate[] scriptables ) { JavaScriptEngine[] elements = new JavaScriptEngine[ scriptables.length ]; for (int i = 0; i < elements.length; i++) { elements[ i ] = (JavaScriptEngine) toScriptable( scriptables[ i ] ); } ElementArray result = ElementArray.newElementArray( this ); result.initialize( elements ); return result; } } static public class Window extends JavaScriptEngine { private Document _document; private Navigator _navigator; private Location _location; private Screen _screen; private ElementArray _frames; public String getClassName() { return "Window"; } public Window jsGet_window() { return this; } public Window jsGet_self() { return this; } public Document jsGet_document() { if (_document == null) { _document = (Document) toScriptable( getDelegate().getDocument() ); } return _document; } public Scriptable jsGet_frames() throws SAXException, PropertyException, JavaScriptException, NotAFunctionException { if (_frames == null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -