You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2006/03/12 19:26:37 UTC

svn commit: r385332 - in /cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources: cocoon.js js/BUHandler.js js/PartialLink.js js/cocoon.js js/common.js js/insertion.js js/timedbrowserupdater.js

Author: sylvain
Date: Sun Mar 12 10:26:37 2006
New Revision: 385332

URL: http://svn.apache.org/viewcvs?rev=385332&view=rev
Log:
New Ajax stuff with Dojo

Added:
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js   (with props)
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js   (with props)
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js   (with props)
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js   (with props)
Removed:
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/cocoon.js
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/timedbrowserupdater.js
Modified:
    cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/BUHandler.js

Added: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js?rev=385332&view=auto
==============================================================================
--- cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js (added)
+++ cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js Sun Mar 12 10:26:37 2006
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2006 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.
+ */
+/**
+ * Bootstrap file to plug Cocoon in the Dojo package system. It declares the
+ * "cocoon" root package and hooks in the script loading engine to handle
+ * the per-block organization of JS files in Cocoon.
+ * <p>
+ * A typical usage scenario would be:
+ * <pre>
+ *   <script src="resources/dojo/dojo.js">
+ *   <script src="resources/ajax/cocoon.js"/>
+ *   <script>
+ *      dojo.require("cocoon.forms.Form");
+ *      ...
+ *    </script>
+ * </pre>
+ *
+ * @version $Id$
+ */
+
+dojo.provide("cocoon");
+
+// Setup hooks to load JS files provided by Cocoon blocks
+(function() {
+    // base path is "resources/dojo". Move to back to "resources"
+    var rsrcPath = "../";
+  
+    // cocoon.foo.bar is loaded from "resources/foo/js/bar.js"
+    var orgRequire = dojo.require;
+    dojo.require = function() {
+        var module = arguments[0];
+        var match = module.match(/^(cocoon\.([^\.]*))/);
+        if (match) {
+            var block = match[1];
+            var name = match[2];
+            if (dojo.hostenv.getModulePrefix(block) == block) {
+                // Register the block's path
+                //dojo.debug("Registering Cocoon module = " + arguments[0]);
+                var prefix = rsrcPath + name + "/js";
+                dojo.hostenv.setModulePrefix(block, prefix);           
+                //dojo.debug("calling setModulePrefix("+block+", "+ prefix +")");
+            }
+        }
+        // Continue normal processing
+        return orgRequire.apply(this, arguments);
+    };
+
+    // cocoon.foo (single JS file for a block) is loaded from "resources/foo/js/common.js"
+    var orgLoadUri = dojo.hostenv.loadUri;
+    dojo.hostenv.loadUri = function(uri) {
+        // match 'xxx/dojo/../yyy/js.js
+        var match = uri.match(/^(.*)\/dojo\/\.\.\/([^\/]*)\/js.js$/);
+        dojo.debug("Loading URI" + uri);
+        if (match) {
+            //dojo.debug("matched cocoon package " + uri);
+            arguments[0] = match[1] + "/" + match[2] + "/js/common.js";
+            //dojo.debug("arg " + arguments[0]);
+            
+        }
+        return orgLoadUri.apply(this, arguments);
+    }
+})();

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/cocoon.js
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/BUHandler.js
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/BUHandler.js?rev=385332&r1=385331&r2=385332&view=diff
==============================================================================
--- cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/BUHandler.js (original)
+++ cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/BUHandler.js Sun Mar 12 10:26:37 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 2006 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.
@@ -25,131 +25,11 @@
 
 dojo.require("dojo.dom");
 dojo.require("dojo.html");
+dojo.require("cocoon.ajax.insertion");
 dojo.provide("cocoon.ajax.BUHandler");
 
 cocoon.ajax.BUHandler = function() { };
 
-/**
- * Imports an element into a document, taking care of using the correct implementation
- * so that the browser interprets it as displayable XML.
- *
- * Any <script> in the imported node are collected and for post-import evaluation
- * FIXME: only inline script are considered, but not <script src="">
- *
- * @return { element: <em>imported_element</em>, scripts: <em>array_of_script_text</em> }
- */
-cocoon.ajax.BUHandler.importNode = function(node, targetDoc) {
-    if(node.xml) {
-        // IE
-        var div = targetDoc.createElement("DIV");
-        var text = node.xml;
-        
-        // Code below heavily inspired by the Prototype library
-        var scriptExpr = "(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)";
-        
-        // Update screen with removed scripts
-        div.innerHTML = text.replace(new RegExp(scriptExpr, 'img'), '');;
-        
-        var matchAll = new RegExp(scriptExpr, 'img');
-        var matchOne = new RegExp(scriptExpr, 'im');
-        var allMatches = text.match(matchAll);
-        var scripts = new Array();
-        for (var i = 0; i < allMatches.length; i++) {
-            scripts.push(allMatches[i].match(matchOne)[1]);
-        }
-        return { element: dojo.dom.getFirstChildElement(div), scripts: scripts };
-        
-    } else {
-        var scripts = new Array();
-        var element = cocoon.ajax.BUHandler._DOMimportNode(node, targetDoc, scripts);
-        return { element: element, scripts: scripts }
-    }
-}
-	
-/**
- * DOM implementation of importNode, recursively creating nodes.
- * Scripts are collected in the "scripts" parameter
- */
-cocoon.ajax.BUHandler._DOMimportNode = function(node, targetDoc, scripts) {
-    switch(node.nodeType) {
-        case dojo.dom.ELEMENT_NODE:
-            if (node.nodeName.toLowerCase() == "script") {
-                // Collect scripts
-                scripts.push(node.firstChild && node.firstChild.nodeValue);
-                return;
-            }
-            var element = targetDoc.createElement(node.nodeName);
-            //var element = targetDoc.createElementNS(node.namespaceURI, node.nodeName);
-            var attrs = node.attributes;
-            for (var i = 0; i < attrs.length; i++) {
-                var attr = attrs[i];
-                element.setAttribute(attr.nodeName, attr.nodeValue);
-                //element.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.nodeValue);
-            }
-            var children = node.childNodes;
-            for (var j = 0; j < children.length; j++) {
-                var imported = cocoon.ajax.BUHandler._DOMimportNode(children[j], targetDoc, scripts);
-                if (imported) element.appendChild(imported);
-            }
-            return element;
-        break;
-        
-        case dojo.dom.TEXT_NODE:
-            return targetDoc.createTextNode(node.nodeValue);
-        break;
-        
-        case dojo.dom.CDATA_SECTION_NODE:
-            return targetDoc.createTextNode(node.nodeValue);
-        break;
-    }
-}
-
-cocoon.ajax.BUHandler._destroyDojoWidgets = function(element) {
-    var widget = dojo.widget.byNode(element);
-    if (widget) {
-        // Dojo will destroy all its children
-        widget.destroy(true, true);
-    } else {
-        // Recurse until we eventually find a widget
-        var children = element.childNodes;
-        for (var i = 0; i < children.length; i++) {
-            var child = children[i];
-            if (child.nodeType == dojo.dom.ELEMENT_NODE) {
-                cocoon.ajax.BUHandler._destroyDojoWidgets(child);
-            }
-        }
-    }
-}
-
-cocoon.ajax.BUHandler._parseDojoWidgets = function(element) {
-    // Find a parent widget (if any) so that Dojo can maintain its widget tree
-    var parentWidget = cocoon.ajax.BUHandler._findParentWidget(element);
-	var parser = new dojo.xml.Parse();
-
-	// FIXME: parser.parseElement() parses the _children_ of an element, whereas we want here
-	// the element itself to be parsed. Parsing its parent is not an option as we don't want
-	// to parse the siblings. So place it in a temporary div that we'll trash afterwards.
-	var div = document.createElement("DIV");
-	element.parentNode.replaceChild(div, element);
-	div.appendChild(element);
-	var frag = parser.parseElement(div, null, true);
-	dojo.widget.getParser().createComponents(frag, parentWidget);
-	div.parentNode.replaceChild(element, div);
-	parentWidget && parentWidget.onResized();
-}
-
-cocoon.ajax.BUHandler._findParentWidget = function(element) {
-    var parent = element.parentNode;
-    var widget;
-    while (parent && !widget) {
-        var widget = dojo.widget.byNode(parent);
-        if (widget) {
-            return widget;
-        }
-        parent = parent.parentNode;
-    }
-}
-
 cocoon.ajax.BUHandler.fade = function(node) {
     dojo.require("dojo.fx.*");
     dojo.fx.highlight(element, dojo.graphics.color.hex2rgb("#ffc"), 700, 300);
@@ -211,34 +91,12 @@
 	            alert("no element '" + id + "' in source document");
 	            return;
 	        }
-
-	        var imported = cocoon.ajax.BUHandler.importNode(firstChild, document);
-	        var newElement = imported.element;
-	        // Don't update if we don't have a valid new element.
-	        if (newElement) {
-		        // Warn: it's replace(new, old)!!
-		        oldElement.parentNode.replaceChild(newElement, oldElement);
-		        // Ensure the new node has the correct id
-		        newElement.setAttribute("id", id);
-		        
-	            // Destroy Dojo widgets associated with the old element
-	            cocoon.ajax.BUHandler._destroyDojoWidgets(oldElement);
-
-		        // Evaluate scripts
-		        for (var i = 0; i < imported.scripts.length; i++) {
-		            eval(imported.scripts[i]);
-		        }
-		        
-		        // Parse dojo widgets for the new element
-		        cocoon.ajax.BUHandler._parseDojoWidgets(newElement);
-		        
-		        // Reload it as the widgetization may have changed it
-		        newElement = document.getElementById(id);
-		        
-		        if (this.highlight) {
-		           this.highlight(newElement);
-		        }
-		    }
+	        
+	        var newElement = cocoon.ajax.insertion.replace(oldElement, firstChild);
+	        
+	        if (this.highlight) {
+	           this.highlight(newElement);
+	        }
 		}
     }
 });

Added: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js?rev=385332&view=auto
==============================================================================
--- cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js (added)
+++ cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js Sun Mar 12 10:26:37 2006
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999-2006 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.
+ */
+dojo.provide("cocoon.ajax.PartialLink");
+
+dojo.require("dojo.widget.DomWidget");
+dojo.require("dojo.io");
+dojo.require("cocoon.ajax.common");
+
+/**
+ * Dojo widget for links that partially update the page.
+ *
+ * @version $Id$
+ */
+
+cocoon.ajax.PartialLink = function() {
+	dojo.widget.DomWidget.call(this);
+};
+
+dojo.inherits(cocoon.ajax.PartialLink, dojo.widget.DomWidget);
+
+dojo.lang.extend(cocoon.ajax.PartialLink, {
+	// Properties
+	href: "",
+	target: "",
+	
+	// Widget definition
+	widgetType: "PartialLink",
+    isContainer: true,
+    
+    buildRendering: function(args, parserFragment, parentWidget) {
+
+        // Magical statement to get the dom node, stolen in DomWidget
+	    this.domNode = parserFragment["dojo:"+this.widgetType.toLowerCase()].nodeRef;
+
+	    if (this.target.indexOf("#") < 0) {
+	        dojo.debug("PartialLink: wrong value for 'target' attribute: " + this.target);
+	        return;
+	    }
+	    
+	    dojo.event.connect(this.domNode, "onclick", this, "onClick");
+    },
+    
+    onClick: function(event) {
+        event.preventDefault();
+        var _this = this;
+        cocoon.ajax.update(_this.href, _this.target);
+    }
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:PartialLink");
+// Register this module as a widget package
+dojo.widget.manager.registerWidgetPackage("cocoon.ajax");
+

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/PartialLink.js
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js?rev=385332&view=auto
==============================================================================
--- cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js (added)
+++ cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js Sun Mar 12 10:26:37 2006
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2006 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.
+ */
+
+/**
+ * Frequently used Ajax functions
+ */
+
+dojo.provide("cocoon.ajax");
+dojo.provide("cocoon.ajax.common");
+dojo.require("cocoon.ajax.insertion");
+
+dojo.lang.mixin(cocoon.ajax, {
+    /**
+     * Update the current page with some remote content.
+     * @param href the URL of the remote content
+     * @param target the update target. It can be either an element (DOM element or id), or
+     *        a string in the "{insertion}#{target-id}" format (e.g. "bottom#event-list").
+     * @param insertion the insertion method (see cocoon.ajax.insertion), either a sa function
+     *        or as a string. If the insertion is specified in target, that last one has
+     *        precedence. If no insertion is speficied, it default to "inside".
+     */
+    update: function(href, target, insertion) {
+        
+        // If target is a string, parse it. Otherwise, assume it's an element
+        if (dojo.lang.isString(target)) {
+            var split = target.split("#");
+            if (split.length == 2) {
+                insertion = split[0];
+                target = dojo.byId(split[1]);
+            } else {
+                target = dojo.byId(target);
+            }
+        }
+        
+        if (dojo.lang.isString(insertion)) {
+            insertion = cocoon.ajax.insertion[insertion];
+        }
+
+        insertion = insertion || cocoon.ajax.insertion.inside;
+        
+        dojo.io.bind({
+		    url: href,
+		    load: function(type, data, evt){
+		        insertion(target, data);
+		    },
+		    mimetype: "text/plain"
+		    // TODO: add an error-handling function
+		});
+        
+    },
+
+    /**
+     */
+    periodicalUpdate: function(delay, href, target, insertion) {
+        dojo.require("dojo.animation.Timer");
+        var timer = new dojo.animation.Timer(delay);
+        timer.onTick = function() {
+            cocoon.ajax.update(href, target, insertion);
+        };
+        
+        timer.onStart = timer.onTick;
+        timer.start();
+        return timer;
+    }
+});
\ No newline at end of file

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/common.js
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js
URL: http://svn.apache.org/viewcvs/cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js?rev=385332&view=auto
==============================================================================
--- cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js (added)
+++ cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js Sun Mar 12 10:26:37 2006
@@ -0,0 +1,250 @@
+/*
+ * Copyright 1999-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.
+ */
+
+/**
+ * Implementation of Prototype's Insertion class with Dojo
+ *
+ * @version $Id$
+ */
+
+dojo.provide("cocoon.ajax.insertion");
+dojo.require("dojo.dom");
+
+cocoon.ajax.insertion = {};
+
+dojo.lang.mixin(cocoon.ajax.insertion, {
+
+	/**
+	 * Inserts before the reference node
+	 */
+    before: function (refElt, content) {
+        return cocoon.ajax.insertionHelper.insert(refElt, content, function(refElt, newElt) {
+            refElt.parentNode.insertBefore(newElt, refElt);
+        });
+    },
+
+	/**
+	 * Inserts after the reference node
+	 */
+    after: function (refElt, content) {
+        return cocoon.ajax.insertionHelper.insert(refElt, content, function(refElt, newElt) {
+            // There's no node.insertAfter...
+            if (refElt.nextSibling) {
+                refElt.parentNode.insertBefore(newElt, refElt.nextSibling);
+            } else {
+                refElt.parentNode.appendChild(newElt);
+            }
+        });
+    },
+
+    /**
+     * Inserts at the top of the reference node children (i.e. as the first child)
+     */
+    top: function (refElt, content) {
+        return cocoon.ajax.insertionHelper.insert(refElt, content, function(refElt, newElt) {
+            if (refElt.firstChild) {
+                refElt.insertBefore(newElt, refElt.firstChild);
+            } else {
+                refElt.appendChild(newElt);
+            }
+        })
+    },
+
+    /**
+     * Inserts at the bottom of the reference node children (i.e. as the last child)
+     */
+    bottom: function (refElt, content) {
+        return cocoon.ajax.insertionHelper.insert(refElt, content, function(refElt, newElt) {
+            refElt.appendChild(newElt);
+        })
+    },
+
+    /**
+     * Inserts as the contents of the reference node (i.e. replaces all children)
+     */
+    inside: function (refElt, content) {
+        return cocoon.ajax.insertionHelper.insert(refElt, content, function(refElt, newElt) {
+            // Destroy and remove all children
+            while (refElt.hasChildNodes()) {
+                var firstChild = refElt.firstChild;
+                if (firstChild.nodeType == dojo.dom.ELEMENT_NODE) {
+                    cocoon.ajax.insertionHelper.destroy(firstChild);
+                }
+                refElt.removeChild(firstChild);
+            }
+            
+            // Insert the new one
+            refElt.appendChild(newElt);
+        })
+    },
+
+    /**
+     * Replaces the reference element
+     */
+    replace: function (refElt, content) {
+        return cocoon.ajax.insertionHelper.insert(refElt, content, function(refElt, newElt) {
+            refElt.parentNode.replaceChild(newElt, refElt);
+            cocoon.ajax.insertionHelper.destroy(refElt);
+        })
+    }
+});
+
+cocoon.ajax.insertionHelper = {};
+
+dojo.lang.mixin(cocoon.ajax.insertionHelper, {
+	/**
+	 * Imports an element into a document, taking care of using the correct implementation
+	 * so that the browser interprets it as displayable XML.
+	 *
+	 * Any <script> in the imported node are collected and for post-import evaluation
+	 * FIXME: only inline script are considered, but not <script src="">
+	 *
+	 * @return { element: <em>imported_element</em>, scripts: <em>array_of_script_text</em> }
+	 */
+    importNode: function(node, targetDoc) {
+	    if(node.xml || dojo.lang.isString(node)) {
+	        // IE or text
+	        var text = dojo.lang.isString(node) ? node : node.xml;
+	        var div = targetDoc.createElement("DIV");
+	        
+	        // Code below heavily inspired by the Prototype library
+	        var scriptExpr = "(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)";
+	        
+	        // Update screen with removed scripts
+	        div.innerHTML = text.replace(new RegExp(scriptExpr, 'img'), '');;
+	        
+	        var matchAll = new RegExp(scriptExpr, 'img');
+	        var matchOne = new RegExp(scriptExpr, 'im');
+	        var allMatches = text.match(matchAll);
+	        var scripts = new Array();
+	        if (allMatches) {
+		        for (var i = 0; i < allMatches.length; i++) {
+		            scripts.push(allMatches[i].match(matchOne)[1]);
+		        }
+		    }
+	        return { element: dojo.dom.getFirstChildElement(div), scripts: scripts };
+	        
+	    } else {
+	        var scripts = new Array();
+	        var element = this._importDomNode(node, targetDoc, scripts);
+	        return { element: element, scripts: scripts }
+	    }
+	},
+
+	/**
+	 * DOM implementation of importNode, recursively creating nodes.
+	 * Scripts are collected in the "scripts" parameter
+	 */
+	_importDomNode: function(node, targetDoc, scripts) {
+	    switch(node.nodeType) {
+	        case dojo.dom.ELEMENT_NODE:
+	            if (node.nodeName.toLowerCase() == "script") {
+	                // Collect scripts
+	                scripts.push(node.firstChild && node.firstChild.nodeValue);
+	                return;
+	            }
+	            var element = targetDoc.createElement(node.nodeName);
+	            //var element = targetDoc.createElementNS(node.namespaceURI, node.nodeName);
+	            var attrs = node.attributes;
+	            for (var i = 0; i < attrs.length; i++) {
+	                var attr = attrs[i];
+	                element.setAttribute(attr.nodeName, attr.nodeValue);
+	                //element.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.nodeValue);
+	            }
+	            var children = node.childNodes;
+	            for (var j = 0; j < children.length; j++) {
+	                var imported = this._importDomNode(children[j], targetDoc, scripts);
+	                if (imported) element.appendChild(imported);
+	            }
+	            return element;
+	        break;
+	        
+	        case dojo.dom.TEXT_NODE:
+	            return targetDoc.createTextNode(node.nodeValue);
+	        break;
+	        
+	        case dojo.dom.CDATA_SECTION_NODE:
+	            return targetDoc.createTextNode(node.nodeValue);
+	        break;
+	    }
+	},
+	
+	_runScripts: function(imported) {
+        // Evaluate scripts
+        for (var i = 0; i < imported.scripts.length; i++) {
+            eval(imported.scripts[i]);
+        }
+	},
+
+    insert: function(refElt, content, insertFunc) {
+        refElt = dojo.byId(refElt, content);
+        var imports = this.importNode(content, refElt.ownerDocument);
+        insertFunc(refElt, imports.element);
+        this._runScripts(imports);
+        return this.parseDojoWidgets(imports.element);
+    },
+    
+    destroy: function(element) {
+	    var widget = dojo.widget.byNode(element);
+	    if (widget) {
+	        // Dojo will destroy all its children
+	        widget.destroy(true, true);
+	    } else {
+	        // Recurse until we eventually find a widget
+	        var children = element.childNodes;
+	        for (var i = 0; i < children.length; i++) {
+	            var child = children[i];
+	            if (child.nodeType == dojo.dom.ELEMENT_NODE) {
+	                this.destroy(child);
+	            }
+	        }
+	    }
+	},
+
+	parseDojoWidgets: function(element) {
+	    // Find a parent widget (if any) so that Dojo can maintain its widget tree
+	    var parentWidget = this.findParentWidget(element);
+		var parser = new dojo.xml.Parse();
+	
+		// FIXME: parser.parseElement() parses the _children_ of an element, whereas we want here
+		// the element itself to be parsed. Parsing its parent is not an option as we don't want
+		// to parse the siblings. So place it in a temporary div that we'll trash afterwards.
+		var div = document.createElement("DIV");
+		element.parentNode.replaceChild(div, element);
+		div.appendChild(element);
+		var frag = parser.parseElement(div, null, true);
+		dojo.widget.getParser().createComponents(frag, parentWidget);
+		// Get again the first child of the div, which may no more be the original one
+		// if it's a widget
+		element = div.firstChild;
+		div.parentNode.replaceChild(element, div);
+		parentWidget && parentWidget.onResized();
+		
+		return element;
+	},
+	
+	findParentWidget: function(element) {
+	    var parent = element.parentNode;
+	    var widget;
+	    while (parent && !widget) {
+	        var widget = dojo.widget.byNode(parent);
+	        if (widget) {
+	            return widget;
+	        }
+	        parent = parent.parentNode;
+	    }
+	}
+});
\ No newline at end of file

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/cocoon-ajax/cocoon-ajax-impl/src/main/java/org/apache/cocoon/ajax/resources/js/insertion.js
------------------------------------------------------------------------------
    svn:keywords = Id