You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by kn...@apache.org on 2008/08/25 17:09:37 UTC

svn commit: r688748 - in /wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket: ajax/wicket-ajax.js ajaxng/js/wicket-ajax-ng.js ajaxng/request/AjaxRequestTarget.java

Author: knopp
Date: Mon Aug 25 08:09:37 2008
New Revision: 688748

URL: http://svn.apache.org/viewvc?rev=688748&view=rev
Log:
woot 
component replacement

Modified:
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/js/wicket-ajax-ng.js
    wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/request/AjaxRequestTarget.java

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js?rev=688748&r1=688747&r2=688748&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js Mon Aug 25 08:09:37 2008
@@ -1307,7 +1307,7 @@
 			var node = rootNode.childNodes[i];			
 			if (node.tagName != null) {
 				var name = node.tagName.toLowerCase();
-				
+
 				// it is possible that a reference is surrounded by a <wicket:link
 				// in that case, we need to find the inner element
 				if (name == "wicket:link") {					
@@ -1321,9 +1321,9 @@
 						}					
 					}					
 				}
-						
+
 				// process the element
-			    if (name == "link") {
+				if (name == "link") {
 					this.processLink(steps, node);
 				} else if (name == "script") {
 					this.processScript(steps, node);

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/js/wicket-ajax-ng.js
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/js/wicket-ajax-ng.js?rev=688748&r1=688747&r2=688748&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/js/wicket-ajax-ng.js (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/js/wicket-ajax-ng.js Mon Aug 25 08:09:37 2008
@@ -1,3 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * Wicket Ajax Support
+ * 
+ * @author Matej Knopp
+ */
+
 (function() {
 
 YUI().use('*', function(Y) {
@@ -395,7 +418,7 @@
 					} 
 					catch (ex)
 					{
-						log.error("FunctionsExecutor", "Error execution function: ", f);
+						log.error("FunctionsExecutor", "Error execution function: ", f, ex);
 						notify();
 					}
 				}, this);
@@ -623,7 +646,7 @@
 	 * Also this method takes care of replacing table elements (tbody, tr, td, thead)
 	 * on browsers where it's not supported when using outerHTML (IE).
 	 */
-	var replaceOuterHtml = function(element, text) 
+	var _replaceOuterHtml = function(element, text) 
 	{	
 		if (UA.ie) 
 		{		
@@ -643,6 +666,31 @@
 	        element.parentNode.replaceChild(fragment, element);        
 	    }		
 	}	
+	
+	var replaceOuterHtml = function(element, text)
+	{		
+		if (element == null)
+		{
+			log.error("ReplaceOuterHtml", "Element can not be null. Markup: ", text);
+			return;
+		}
+		// remember next sibling (if any)
+		var nextSibling = element.nextSibling;
+		var id = element.id;				
+		
+		// replace
+		_replaceOuterHtml(element, text);
+		
+		// get the list of inserted nodes		
+		var res = new Array();
+		var e = W.$(id);
+		while (e != nextSibling && e != null)
+		{
+			res.push(e);
+			e = e.nextSibling;
+		}
+		return res;
+	}
 
 	W.replaceOuterHtml = replaceOuterHtml;
 	
@@ -1614,11 +1662,147 @@
 			
 		},
 		
+		processJavascripts: function(javascripts, steps)
+		{
+			var process = bind(function(script)
+			{
+				if (script.async == true)
+				{
+					var f = eval("(function(requestQueueItem, notify) {" + script.javascript + "})");					
+					var f2 = bind(function(notify)
+					{
+						f(this, notify);
+					}, this);
+					steps.push(f2);
+				}
+				else
+				{
+					var f = eval("(function(requestQueueItem) {" + script.javascript + "})");
+					var f2 = bind(function(notify)
+					{
+						f(this);
+						notify();
+					}, this);
+					steps.push(f2);
+				}
+			}, this);
+			
+			if (L.isArray(javascripts))
+			{
+				for (var i = 0; i < javascripts.length; ++i)
+				{
+					var j = javascripts[i];
+					process(j);
+				}
+			}
+		},
+		
+		processComponent: function(component, steps)
+		{
+			var markup = component.markup;
+			var id = component.componentId;
+			var before = component.beforeReplaceJavascript;
+			var after = component.afterReplaceJavascript;
+			var replace = component.replaceJavascript;
+			
+			// 1 - Before replacement javascript
+			if (before != null)
+			{
+				var f = eval("(function(requestQueueItem, componentId, notify) {" + before + "})");
+				var f2 = bind(function(notify)
+				{
+					log.trace("RequestQueue", "Invoking before replacement javascript", f);
+					f(this, id, notify);
+				}, this);
+				steps.push(f2);
+			}
+			
+			// 2 - replacement
+			var replaceFunction;
+			if (replace != null)
+			{
+				// user specified replacement function
+				replaceFunction = eval("(function(requestQueueItem, componentId, markup, notify) {" + before + "})");				
+			}
+			else
+			{
+				// default replacement function
+				replaceFunction = function(requestQueueItem, componentId, markup, notify)
+				{
+					log.trace("RequestQueue", "Replacing component", requestQueueItem, componentId, markup);
+					var e = W.$(componentId);
+					var res;
+					if (e == null)
+					{
+						log.error("RequestQueue", "Couldn't find element to be replaced ", componentId);					
+					}
+					else
+					{
+						res = W.replaceOuterHtml(e, markup);
+						log.trace("RequestQueue", "Replacement done:", res);
+					}
+					notify(res);
+				}
+			}			
+			
+			// bind it with special notify function that invokes nodesAddedListeners
+			var replaceFunction2 = bind(function(notify)
+			{
+				var replaceNotify = bind(function(elements)
+				{
+					if (L.isArray(elements))
+					{
+						W.ajax.invokeNodesAddedListeners(elements, this);
+					}
+					notify();
+				}, this);
+				
+				replaceFunction(this, id, markup, replaceNotify);
+			}, this);
+			steps.push(replaceFunction2);			
+			
+			// 3 - After replacement javascript
+			if (after != null)
+			{
+				var f = eval("(function(requestQueueItem, componentId, notify) {" + after + "})");
+				var f2 = bind(function(notify)
+				{
+					log.trace("RequestQueue", "Invoking after replacement javascript", f);
+					f(this, id, notify);
+				}, this);
+				steps.push(f2);
+			}
+		},
+		
+		processComponents: function(components, steps)
+		{
+			if (L.isArray(components))
+			{
+				for (var i = 0; i < components.length; ++i)
+				{
+					var c = components[i];
+					if (L.isObject(c))
+					{
+						this.processComponent(c, steps);
+					}
+				}
+			}
+		},
+		
 		processResponse: function(response)
 		{
 			var steps = new Array();
+		
+			this.processJavascripts(response.prependJavascript, steps);
 			
-			this.processHeaderContribution(response.header, steps);
+			if (response.header != null)
+			{
+				this.processHeaderContribution(response.header, steps);
+			}			
+			
+			this.processComponents(response.components, steps);
+			
+			this.processJavascripts(response.appendJavascript, steps);
 			
 			steps.push(bind(function(notify)
 			{
@@ -1856,6 +2040,11 @@
 		return res; 
 	}
 	
+	var defaultNodesAddedListener = function(nodes, requestQueueItem)
+	{
+		log.trace("General", "New nodes added to document:", nodes, ", from RequestQueueItem (optional):", requestQueueItem);
+	}
+	
 	var globalSettings = 
 	{
 		defaultRequestTimeout: 60000,
@@ -1877,7 +2066,8 @@
 		urlParamListenerInterface: "INVALID_LISTENER_INTERFACE_PARAM",
 		urlParamBehaviorIndex: "INVALID_BEHAVIOR_INDEX_PARAM",
 		urlParamUrlDepth: "INVALID_URL_DEPTH_PARAM",
-		urlDepthValue: 0
+		urlDepthValue: 0,
+		nodesAddedListeners: [defaultNodesAddedListener]
 	};
 	
 	var Ajax = function() 
@@ -1888,7 +2078,21 @@
 	
 	Ajax.prototype = 
 	{
-		
+		invokeNodesAddedListeners: function(elements, requestQueueItem)
+		{
+			try 
+			{
+				var l = this.globalSettings.nodesAddedListeners;
+				for (var i = 0; i < l.length; ++i)
+				{
+					l[i](elements, requestQueueItem);
+				}
+			} 
+			catch (e)
+			{
+				log.error("Ajax", "Error invoking nodes added listeners", e);
+			}
+		}
 	};
 	
 	W.ajax = new Ajax();

Modified: wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/request/AjaxRequestTarget.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/request/AjaxRequestTarget.java?rev=688748&r1=688747&r2=688748&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/request/AjaxRequestTarget.java (original)
+++ wicket/sandbox/knopp/experimental/wicket/src/main/java/org/apache/wicket/ajaxng/request/AjaxRequestTarget.java Mon Aug 25 08:09:37 2008
@@ -225,9 +225,6 @@
 		 * <dd>RequestQueueItem instance for current request</dd>
 		 * <dt>componentId</dt>
 		 * <dd>MarkupId of component that is about to be replaced
-		 * <dt>sourceComponentId</dt>
-		 * <dd>MarkupId of component that has initiated current ajax request or <code>null</code>
-		 * if the component is not available.
 		 * <dt>notify</dt>
 		 * <dd>Method that javascript needs to execute after it has finished. Note that it is
 		 * mandatory to call this method otherwise the processing pipeline will stop</dd>
@@ -298,15 +295,17 @@
 		 * <dd>The new markup that should replace current markup</dd>
 		 * <dt>notify</dt>
 		 * <dd>Method that javascript needs to execute after the component has been replaced. Note
-		 * that it is mandatory to call this method otherwise the processing pipeline will stop</dd>
+		 * that it is mandatory to call this method otherwise the processing pipeline will stop.
+		 * Array of newly inserted elements should be passed as argument to the notify method.</dd>
 		 * </dl>
 		 * 
 		 * An example javascript:
 		 * 
 		 * <pre>
 		 * var element = W.$(componentId);
-		 * W.replaceOuterHtml(element, markup);
-		 * notify();
+		 * var insertedElements = W.replaceOuterHtml(element, markup);
+		 * notify(insertedElements);
+		 * 
 		 * </pre>
 		 * 
 		 * @param replaceJavascript
@@ -910,7 +909,7 @@
 		JSONObject object = new JSONObject();
 
 		Component component = componentEntry.getComponent();
-		object.put("componentId", component.getId());
+		object.put("componentId", component.getMarkupId());
 		object.put("beforeReplaceJavascript", componentEntry.getBeforeReplaceJavascript());
 		object.put("afterReplaceJavascript", componentEntry.getAfterReplaceJavascript());
 		object.put("replaceJavascript", componentEntry.getReplaceJavascript());