001: /*
002: * Copyright (c) 2002-2008 Gargoyle Software Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: * 2. Redistributions in binary form must reproduce the above copyright notice,
010: * this list of conditions and the following disclaimer in the documentation
011: * and/or other materials provided with the distribution.
012: * 3. The end-user documentation included with the redistribution, if any, must
013: * include the following acknowledgment:
014: *
015: * "This product includes software developed by Gargoyle Software Inc.
016: * (http://www.GargoyleSoftware.com/)."
017: *
018: * Alternately, this acknowledgment may appear in the software itself, if
019: * and wherever such third-party acknowledgments normally appear.
020: * 4. The name "Gargoyle Software" must not be used to endorse or promote
021: * products derived from this software without prior written permission.
022: * For written permission, please contact info@GargoyleSoftware.com.
023: * 5. Products derived from this software may not be called "HtmlUnit", nor may
024: * "HtmlUnit" appear in their name, without prior written permission of
025: * Gargoyle Software Inc.
026: *
027: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
028: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
029: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
030: * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
031: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
032: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
033: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
036: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: */
038: package com.gargoylesoftware.htmlunit.javascript.host;
039:
040: import org.apache.commons.logging.Log;
041: import org.apache.commons.logging.LogFactory;
042: import org.mozilla.javascript.BaseFunction;
043: import org.mozilla.javascript.Context;
044: import org.mozilla.javascript.Function;
045: import org.mozilla.javascript.JavaScriptException;
046: import org.mozilla.javascript.Scriptable;
047:
048: import com.gargoylesoftware.htmlunit.html.DomNode;
049: import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
050:
051: /**
052: * Allows to wrap event handler code as Function object.
053: *
054: * @version $Revision: 2132 $
055: * @author Marc Guillemot
056: */
057: public class EventHandler extends BaseFunction {
058: private static final long serialVersionUID = 3257850965406068787L;
059:
060: private final DomNode node_;
061: private final String eventName_;
062: private final String jsSnippet_;
063: private Function realFunction_;
064:
065: /**
066: * Builds a function that will execute the javascript code provided
067: * @param node the element for which the event is build
068: * @param eventName the event for which this handler is created
069: * @param jsSnippet the javascript code
070: */
071: public EventHandler(final DomNode node, final String eventName,
072: final String jsSnippet) {
073: node_ = node;
074: eventName_ = eventName;
075:
076: final String functionSignature;
077: if (node.getPage().getWebClient().getBrowserVersion().isIE()) {
078: functionSignature = "function()";
079: } else {
080: functionSignature = "function(event)";
081: }
082: jsSnippet_ = functionSignature + " {" + jsSnippet + "\n}";
083: }
084:
085: /**
086: * {@inheritDoc}
087: */
088: public Object call(final Context cx, final Scriptable scope,
089: final Scriptable this Obj, final Object[] args)
090: throws JavaScriptException {
091:
092: // the js object to which this event is attached has to be the scope
093: final SimpleScriptable jsObj = (SimpleScriptable) node_
094: .getScriptObject();
095: // compile "just in time"
096: if (realFunction_ == null) {
097: realFunction_ = cx.compileFunction(jsObj, jsSnippet_,
098: eventName_ + " event for " + node_, 1, null);
099: }
100:
101: final Object result = realFunction_.call(cx, scope, this Obj,
102: args);
103:
104: return result;
105: }
106:
107: /**
108: * @see org.mozilla.javascript.ScriptableObject#getDefaultValue(java.lang.Class)
109: * @param typeHint the type hint
110: * @return the js code of the function declaration
111: */
112: public Object getDefaultValue(final Class typeHint) {
113: return jsSnippet_;
114: }
115:
116: /**
117: * {@inheritDoc}
118: */
119: public Object get(final String name, final Scriptable start) {
120: // quick and dirty
121: if ("toString".equals(name)) {
122: return new BaseFunction() {
123: private static final long serialVersionUID = 3761409724511435061L;
124:
125: public Object call(final Context cx,
126: final Scriptable scope,
127: final Scriptable this Obj, final Object[] args) {
128: return jsSnippet_;
129: }
130: };
131: }
132:
133: return super .get(name, start);
134: }
135:
136: /**
137: * Return the log
138: * @return The log.
139: */
140: protected final Log getLog() {
141: return LogFactory.getLog(getClass());
142: }
143: }
|