You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by ms...@apache.org on 2007/07/04 21:27:48 UTC
svn commit: r553306 - in /tapestry/tapestry4/trunk/tapestry-framework/src:
descriptor/META-INF/ java/org/apache/tapestry/
java/org/apache/tapestry/dojo/html/ java/org/apache/tapestry/event/
java/org/apache/tapestry/html/ java/org/apache/tapestry/util/i...
Author: mschulte
Date: Wed Jul 4 12:27:47 2007
New Revision: 553306
URL: http://svn.apache.org/viewvc?view=rev&rev=553306
Log:
Better fix for TAPESTRY-1202
Added:
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java
Removed:
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/io/JSONAdaptor.java
Modified:
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script
tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml Wed Jul 4 12:27:47 2007
@@ -94,7 +94,6 @@
<adaptor object="service:SerializableAdaptor"/>
<adaptor object="instance:ShortAdaptor"/>
<adaptor object="instance:StringAdaptor"/>
- <adaptor object="instance:JSONAdaptor"/>
</contribution>
</module>
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script Wed Jul 4 12:27:47 2007
@@ -17,25 +17,18 @@
<if expression="events">
<foreach expression="events" key="event">
tapestry.cleanConnect(dojo.byId("${clientId}"), "${event[0]}", "event${event[1]}");
- tapestry.event${event[1]}=function( inv ){
- result = inv.proceed();
+ tapestry.event${event[1]}=function( event ){
var content={beventname:"${event[0]}"};
- var event = inv.args[0];
- tapestry.event.buildEventProperties( event, content);
+
+ tapestry.event.buildEventProperties( event, content, arguments);
if (!content["beventtarget.id"]) {
content["beventtarget.id"]="${clientId}";
- }
-
- if (! dojo.event.browser.isEvent(event)){
- tapestry.event.buildMethodInterceptionProperties( inv.args, content );
- }
+ }
tapestry.bind("${url}", content);
-
- return result;
};
- dojo.event.connect("around", dojo.byId("${clientId}"), "${event[0]}", tapestry, "event${event[1]}");
+ dojo.event.connect(dojo.byId("${clientId}"), "${event[0]}", tapestry, "event${event[1]}");
</foreach>
</if>
<if expression="formEvents">
@@ -44,7 +37,7 @@
"${formEvent[0]}", "formEvent${formEvent[4]}");
tapestry.formEvent${formEvent[4]}=function(e){
var content={beventname:"${formEvent[0]}"};
- tapestry.event.buildEventProperties(e, content);
+ tapestry.event.buildEventProperties(e, content, arguments);
if (!content["beventtarget.id"]){
content["beventtarget.id"]="${clientId}";
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script Wed Jul 4 12:27:47 2007
@@ -19,7 +19,7 @@
tapestry.cleanConnect(dojo.widget.byId("${clientId}"), "${event[0]}", "event${event[1]}");
tapestry.event${event[1]}=function(e){
var content={beventname:"${event[0]}"};
- tapestry.event.buildEventProperties(e, content);
+ tapestry.event.buildEventProperties(e, content, arguments);
if (!content["beventtarget.id"]) content["beventtarget.id"]="${clientId}";
tapestry.bind("${url}", content);
};
@@ -32,7 +32,7 @@
"${formEvent[0]}", "formEvent${formEvent[4]}");
tapestry.formEvent${formEvent[4]}=function(e){
var content={beventname:"${formEvent[0]}"};
- tapestry.event.buildEventProperties(e, content);
+ tapestry.event.buildEventProperties(e, content, arguments);
if (!content["beventtarget.id"]) content["beventtarget.id"]="${clientId}";
<foreach expression="formEvent[1]" key="formName">
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java Wed Jul 4 12:27:47 2007
@@ -13,13 +13,16 @@
// limitations under the License.
package org.apache.tapestry.event;
+import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.util.Defense;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.json.JSONArray;
/**
@@ -41,6 +44,8 @@
public static final String TARGET="beventtarget";
public static final String TARGET_ATTR_ID="id";
+ public static final String METHOD_ARGUMENTS="methodArguments";
+
private String _name;
private String _type;
private String[] _keys;
@@ -51,6 +56,9 @@
private String _layerY;
private EventTarget _target;
+ private String _methodArguments;
+ private JSONArray _methodArgumentsArray;
+
/**
* Creates a new browser event that will extract its own
* parameters.
@@ -78,6 +86,8 @@
if (targetId != null) {
props.put(TARGET_ATTR_ID, targetId);
}
+
+ _methodArguments = cycle.getParameter(METHOD_ARGUMENTS);
}
/**
@@ -171,6 +181,33 @@
{
return _type;
}
+
+
+ /**
+ * @return the method arguments of an intercepted method-call, if any. If none
+ * are available, return an empty JSONArray, never null.
+ *
+ * @throws ApplicationRuntimeException when the JSON-String could not be
+ * parsed.
+ */
+ public JSONArray getMethodArguments()
+ {
+ if ( _methodArgumentsArray == null)
+ {
+ try
+ {
+ _methodArgumentsArray =
+ _methodArguments != null ?
+ new JSONArray( _methodArguments )
+ : new JSONArray();
+ }
+ catch (ParseException ex)
+ {
+ throw new ApplicationRuntimeException(ex);
+ }
+ }
+ return _methodArgumentsArray;
+ }
/**
* Utility method to check if the current request contains
@@ -198,6 +235,7 @@
.append("layerX", _layerX)
.append("layerY", _layerY)
.append("target", _target)
+ .append("methodArguments", _methodArguments)
.toString();
}
}
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script Wed Jul 4 12:27:47 2007
@@ -18,7 +18,7 @@
tapestry.cleanConnect(dojo.byId("${target}"), "${event[0]}", "event${event[1]}");
tapestry.event${event[1]}=function(e){
var content={beventname:"${event[0]}"};
- tapestry.event.buildEventProperties(e, content);
+ tapestry.event.buildEventProperties(e, content, arguments);
if (!content["beventtarget.id"]) content["beventtarget.id"]="${target}";
tapestry.bind("${url}", content);
};
@@ -31,7 +31,7 @@
"${formEvent[0]}", "formEvent${formEvent[4]}");
tapestry.formEvent${formEvent[4]}=function(e){
var content={beventname:"${formEvent[0]}"};
- tapestry.event.buildEventProperties(e, content);
+ tapestry.event.buildEventProperties(e, content, arguments);
if (!content["beventtarget.id"]) content["beventtarget.id"]="${target}";
<foreach expression="formEvent[1]" key="formName">
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js Wed Jul 4 12:27:47 2007
@@ -7,7 +7,8 @@
dojo.require("dojo.io.BrowserIO");
dojo.require("dojo.event.browser");
dojo.require("dojo.html.style");
-dojo.require("dojo.json");
+
+
// redirect logging calls to standard debug if logging not enabled
if (dj_undef("logging", dojo)) {
@@ -532,7 +533,7 @@
},
_getContentAsStringIE:function(node){
- var s="";
+ var s=" "; //blank works around an IE-bug
for (var i = 0; i < node.childNodes.length; i++){
s += node.childNodes[i].xml;
}
@@ -600,59 +601,34 @@
* browser event it will be ignored.
* props - The existing property object to set the values on, if it doesn't
* exist one will be created.
+ * args - The arguments from an method-call interception
* Returns:
*
* The desired event properties bound to an object. Ie obj.target,obj.charCode, etc..
*/
- buildEventProperties:function(event, props){
+ buildEventProperties:function(event, props, args){
if (!props) props={};
- if (!dojo.event.browser.isEvent(event)) return props;
-
- if(event["type"]) props.beventtype=event.type;
- if(event["keys"]) props.beventkeys=event.keys;
- if(event["charCode"]) props.beventcharCode=event.charCode;
- if(event["pageX"]) props.beventpageX=event.pageX;
- if(event["pageY"]) props.beventpageY=event.pageY;
- if(event["layerX"]) props.beventlayerX=event.layerX;
- if(event["layerY"]) props.beventlayerY=event.layerY;
-
- if (event["target"]) this.buildTargetProperties(props, event.target);
+ if (dojo.event.browser.isEvent(event)) {
+ if(event["type"]) props.beventtype=event.type;
+ if(event["keys"]) props.beventkeys=event.keys;
+ if(event["charCode"]) props.beventcharCode=event.charCode;
+ if(event["pageX"]) props.beventpageX=event.pageX;
+ if(event["pageY"]) props.beventpageY=event.pageY;
+ if(event["layerX"]) props.beventlayerX=event.layerX;
+ if(event["layerY"]) props.beventlayerY=event.layerY;
+
+ if (event["target"]) this.buildTargetProperties(props, event.target);
+
+ } else if ( args != undefined ) {
+
+ props.methodArguments = dojo.json.serialize( args );
+
+ }
return props;
},
- /**
- * Function: buildMethodInterceptionProperties
- *
- * Stuffs the parameters of an @EventListener-intercepted method into
- * a property object suitable to be passed as the content-argument to
- * the bind-function. Arguments will be passed as service-parameters (sp)
- * so that the usual listener-invocation mechanism can do its work.
- * String parameters are encoded as such (StringAdaptor, prefix "S")
- * Other types/objects will be serialised to a JSON-String which is
- * to be handled by the JSONAdaptor on the server side (prefix "J").
- *
- * Parameters:
- *
- * args - the arguments array.
- * props - The existing property object to set the values on, if it doesn't
- * exist one will be created.
- * Returns:
- *
- * The passed in properties object augmented in the way described above
- */
- buildMethodInterceptionProperties:function( args, props ){
- if (!props) props={};
- props.sp = new Array();
- for ( var i=0; i < args.length; i++ ) {
- if ( typeof(args[i]) == "string" )
- props.sp[i] = "S"+String(args[i]);
- else
- props.sp[i] = "J"+dojo.json.serialize( args[i] );
- }
- return props;
- },
/**
* Function: buildTargetProperties
@@ -737,4 +713,134 @@
}
return true;
}
-}
\ No newline at end of file
+}
+
+/*
+ ** dojo json support just dumped in here until we build dojo anew for T4 **
+
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+
+dojo.require("dojo.lang.func");
+dojo.require("dojo.string.extras");
+
+dojo.AdapterRegistry = function (returnWrappers) {
+ this.pairs = [];
+ this.returnWrappers = returnWrappers || false;
+};
+dojo.lang.extend(dojo.AdapterRegistry, {register:function (name, check, wrap, directReturn, override) {
+ var type = (override) ? "unshift" : "push";
+ this.pairs[type]([name, check, wrap, directReturn]);
+}, match:function () {
+ for (var i = 0; i < this.pairs.length; i++) {
+ var pair = this.pairs[i];
+ if (pair[1].apply(this, arguments)) {
+ if ((pair[3]) || (this.returnWrappers)) {
+ return pair[2];
+ } else {
+ return pair[2].apply(this, arguments);
+ }
+ }
+ }
+ throw new Error("No match found");
+}, unregister:function (name) {
+ for (var i = 0; i < this.pairs.length; i++) {
+ var pair = this.pairs[i];
+ if (pair[0] == name) {
+ this.pairs.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+}});
+
+
+dojo.json = {jsonRegistry:new dojo.AdapterRegistry(), register:function (name, check, wrap, override) {
+ dojo.json.jsonRegistry.register(name, check, wrap, override);
+}, evalJson:function (json) {
+ try {
+ return eval("(" + json + ")");
+ }
+ catch (e) {
+ dojo.debug(e);
+ return json;
+ }
+}, serialize:function (o) {
+ var objtype = typeof (o);
+ if (objtype == "undefined") {
+ return "undefined";
+ } else {
+ if ((objtype == "number") || (objtype == "boolean")) {
+ return o + "";
+ } else {
+ if (o === null) {
+ return "null";
+ }
+ }
+ }
+ if (objtype == "string") {
+ return dojo.string.escapeString(o);
+ }
+ var me = arguments.callee;
+ var newObj;
+ if (typeof (o.__json__) == "function") {
+ newObj = o.__json__();
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ }
+ if (typeof (o.json) == "function") {
+ newObj = o.json();
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ }
+ if (objtype != "function" && typeof (o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ var val = me(o[i]);
+ if (typeof (val) != "string") {
+ val = "undefined";
+ }
+ res.push(val);
+ }
+ return "[" + res.join(",") + "]";
+ }
+ try {
+ window.o = o;
+ newObj = dojo.json.jsonRegistry.match(o);
+ return me(newObj);
+ }
+ catch (e) {
+ }
+ if (objtype == "function") {
+ return null;
+ }
+ res = [];
+ for (var k in o) {
+ var useKey;
+ if (typeof (k) == "number") {
+ useKey = "\"" + k + "\"";
+ } else {
+ if (typeof (k) == "string") {
+ useKey = dojo.string.escapeString(k);
+ } else {
+ continue;
+ }
+ }
+ val = me(o[k]);
+ if (typeof (val) != "string") {
+ continue;
+ }
+ res.push(useKey + ":" + val);
+ }
+ return "{" + res.join(",") + "}";
+}};
\ No newline at end of file
Added: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java?view=auto&rev=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java Wed Jul 4 12:27:47 2007
@@ -0,0 +1,93 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package org.apache.tapestry.event;
+
+import static org.easymock.EasyMock.expect;
+
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.tapestry.BaseComponentTestCase;
+import org.apache.tapestry.IRequestCycle;
+import org.testng.annotations.Test;
+
+/**
+ * Tests how BrowserEvent extracts itself from the RequestCycle
+ *
+ */
+@Test
+public class BrowserEventTest extends BaseComponentTestCase
+{
+ public void testConstructAndReadMethodArguments() {
+ IRequestCycle cycle = newCycle();
+
+ trainCycleForStandardBrowserEvent(cycle);
+
+ expect(cycle.getParameter(BrowserEvent.METHOD_ARGUMENTS))
+ .andReturn("[1,2]");
+
+ replay();
+
+ BrowserEvent event = new BrowserEvent(cycle);
+
+ verify();
+
+ assertEquals(1, event.getMethodArguments().getInt(0));
+ assertEquals(2, event.getMethodArguments().getInt(1));
+ }
+
+
+
+ public void testUnparseableJSON() {
+
+ IRequestCycle cycle = newCycle();
+
+ trainCycleForStandardBrowserEvent(cycle);
+
+ expect(cycle.getParameter(BrowserEvent.METHOD_ARGUMENTS))
+ .andReturn("*/utterRubbsh");
+ replay();
+
+ BrowserEvent event = new BrowserEvent(cycle);
+
+ verify();
+
+ try {
+ event.getMethodArguments();
+ unreachable();
+ } catch( ApplicationRuntimeException e) {
+ //success.
+ }
+ }
+
+ /**
+ * @param cycle
+ */
+ private void trainCycleForStandardBrowserEvent(IRequestCycle cycle)
+ {
+ expect(cycle.getParameter(BrowserEvent.NAME)).andReturn("onClick").anyTimes();
+
+ expect(cycle.getParameter(BrowserEvent.TYPE)).andReturn("click");
+ expect(cycle.getParameters(BrowserEvent.KEYS)).andReturn(null);
+ expect(cycle.getParameter(BrowserEvent.CHAR_CODE)).andReturn(null);
+ expect(cycle.getParameter(BrowserEvent.PAGE_X)).andReturn("123");
+ expect(cycle.getParameter(BrowserEvent.PAGE_Y)).andReturn("1243");
+ expect(cycle.getParameter(BrowserEvent.LAYER_X)).andReturn(null);
+ expect(cycle.getParameter(BrowserEvent.LAYER_Y)).andReturn(null);
+
+ expect(cycle.getParameter(BrowserEvent.TARGET + "." + BrowserEvent.TARGET_ATTR_ID))
+ .andReturn("element1");
+ }
+
+
+
+}