Author: hlship
Date: Thu Sep  4 11:44:45 2008
New Revision: 692189

URL: http://svn.apache.org/viewvc?rev=692189&view=rev
Log:
TAPESTRY-2541: Tapestry DOM needs basic methods to manipulate the DOM 
post-render

Modified:
    tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt
    tapestry/tapestry5/trunk/src/site/apt/index.apt
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java

Modified: tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/guide/dom.apt Thu Sep  4 11:44:45 2008
@@ -43,9 +43,7 @@
   allows the majority of code to treat the generation of output as a stream. 
In fact,
   MarkupWriter is more like a cursor into the DOM tree.
   
-  Once all rendering is complete, the DOM tree is streamed to the client.  
Planned enhancements
-  will control output formatting, including pretty-printing and/or output 
compression (elimination
-  of all unnecessary whitespace).
+  Once all rendering is complete, the DOM tree is streamed to the client.
   
 DOM Classes
 
@@ -156,3 +154,14 @@
   writer.comment("Start of JS Menu code");
   
 +----+
+
+DOM Manipulation
+
+  A powerful feature of Tapestry 5 is the ability to manipulate the DOM after 
it has been rendered.
+
+  Methods on Node allow an existing node to be moved relative to an Element.  
Nodes may be moved before or after the Element,
+  or may be moved inside an Element at the top (the first child) or the bottom 
(the last child).
+
+  In addition, the children of an Element may be removed or a Node (and all of 
its children) removed entirely.
+
+  Finally, an Element may "pop": the Element is removed and replaced with its 
children.
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/src/site/apt/index.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/index.apt?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/index.apt Thu Sep  4 11:44:45 2008
@@ -84,6 +84,10 @@
 
 New And Of Note
 
+  * New methods have been added to
+    {{{../apidocs/org/apache/tapestry5/dom/Node.html}Node}} to allow nodes to 
be moved about or otherwise
+    manipulated.
+
   * Application State Objects are now automatically saved back to the session 
at the end of the request,
     which ensures that ASO data is properly replicated across at cluster.
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/CData.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -24,18 +24,15 @@
 {
     private final String content;
 
-    private final Document document;
-
-    public CData(Node container, Document document, String content)
+    public CData(Node container, String content)
     {
         super(container);
 
-        this.document = document;
         this.content = content;
     }
 
-
-    public void toMarkup(PrintWriter writer)
+    @Override
+    void toMarkup(Document document, PrintWriter writer)
     {
         MarkupModel model = document.getMarkupModel();
 
@@ -47,13 +44,8 @@
             return;
         }
 
-        // CDATA not supported, so write it normally, with entities escaped.  
Create a working
-        // buffer that's plenty big even if a lot of characters need escaping.
-
-        StringBuilder builder = new StringBuilder(2 * content.length());
-
-        model.encode(content, builder);
+        // CDATA not supported, so write it normally, with entities escaped.
 
-        writer.print(builder.toString());
+        writer.print(model.encode(content));
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Comment.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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.
@@ -31,11 +31,10 @@
     }
 
     @Override
-    public void toMarkup(PrintWriter writer)
+    void toMarkup(Document document, PrintWriter writer)
     {
         writer.print("<!-- ");
         writer.print(comment);
         writer.print(" -->");
     }
-
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/DefaultMarkupModel.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -37,6 +37,15 @@
         encode(content, false, buffer);
     }
 
+    public String encode(String content)
+    {
+        StringBuilder buffer = new StringBuilder(content.length() * 2);
+
+        encode(content, false, buffer);
+
+        return buffer.toString();
+    }
+
     public void encodeQuoted(String content, StringBuilder buffer)
     {
         encode(content, true, buffer);

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Document.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -44,7 +44,7 @@
         this.encoding = encoding;
     }
 
-    Document getDocument()
+    public Document getDocument()
     {
         return this;
     }
@@ -109,7 +109,7 @@
     }
 
     @Override
-    public void toMarkup(PrintWriter writer)
+    public void toMarkup(Document document, PrintWriter writer)
     {
         if (rootElement == null) throw new 
IllegalStateException(DomMessages.noRootElement());
 
@@ -129,7 +129,7 @@
             dtd.toMarkup(writer);
         }
 
-        rootElement.toMarkup(writer);
+        rootElement.toMarkup(document, writer);
     }
 
     @Override

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Element.java
 Thu Sep  4 11:44:45 2008
@@ -48,10 +48,6 @@
             this.value = value;
         }
 
-        public String getValue()
-        {
-            return value;
-        }
 
         void render(MarkupModel model, StringBuilder builder)
         {
@@ -105,12 +101,12 @@
         this.namespace = namespace;
         this.name = name;
 
-        document = parent.getDocument();
+        document = null;
     }
 
     public Document getDocument()
     {
-        return document;
+        return document != null ? document : super.getDocument();
     }
 
     /**
@@ -266,7 +262,7 @@
      */
     public Text text(String text)
     {
-        return newChild(new Text(this, document, text));
+        return newChild(new Text(this, text));
     }
 
     /**
@@ -277,7 +273,7 @@
      */
     public CData cdata(String content)
     {
-        return newChild(new CData(this, document, content));
+        return newChild(new CData(this, content));
     }
 
 
@@ -289,15 +285,16 @@
     }
 
     @Override
-    public void toMarkup(PrintWriter writer)
+    void toMarkup(Document document, PrintWriter writer)
     {
+        MarkupModel markupModel = document.getMarkupModel();
+
         StringBuilder builder = new StringBuilder();
 
         String prefixedElementName = toPrefixedName(namespace, name);
 
         builder.append("<").append(prefixedElementName);
 
-        MarkupModel markupModel = document.getMarkupModel();
 
         if (attributes != null)
         {
@@ -346,7 +343,7 @@
 
         writer.print(builder.toString());
 
-        if (hasChildren) writeChildMarkup(writer);
+        if (hasChildren) writeChildMarkup(document, writer);
 
         // Dangerous -- perhaps it should be an error for a tag of type OMIT 
to even have children!
         // We'll certainly be writing out unbalanced markup in that case.
@@ -446,7 +443,7 @@
     {
         Attribute attribute = InternalUtils.get(attributes, attributeName);
 
-        return attribute == null ? null : attribute.getValue();
+        return attribute == null ? null : attribute.value;
     }
 
     public String getName()
@@ -529,4 +526,34 @@
     {
         return namespace;
     }
+
+    /**
+     * Removes an element; the element's children take the place of the node 
within its container.
+     */
+    public void pop()
+    {
+        // Have to be careful because we'll be  modifying the underlying list 
of children
+        // as we work, so we need a copy of the children.
+
+        List<Node> childrenCopy = CollectionFactory.newList(getChildren());
+
+        for (Node child : childrenCopy)
+        {
+            child.moveBefore(this);
+        }
+
+        remove();
+    }
+
+    /**
+     * Removes all children from this element.
+     *
+     * @return the element, for method chaining
+     */
+    public Element removeChildren()
+    {
+        clearChildren();
+
+        return this;
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/MarkupModel.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -28,9 +28,9 @@
      * entities (such as &amp;lt;).
      *
      * @param content to be filtered
-     * @param buffer  to receive the filtered content
+     * @return the filtered content
      */
-    void encode(String content, StringBuilder buffer);
+    String encode(String content);
 
     /**
      * Encodes the characters into the buffer for use in a quoted value (that 
is, an attribute value), converting

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Node.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -15,7 +15,8 @@
 package org.apache.tapestry5.dom;
 
 import org.apache.tapestry5.internal.util.PrintOutCollector;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.Defense;
 
 import java.io.PrintWriter;
 import java.util.Collections;
@@ -28,6 +29,10 @@
 {
     private Node container;
 
+    /**
+     * Child notes; only Element actually has children.  Attributes are 
modeled differently in this DOM than in
+     * traditional W3C Dom (where Attributes are another type of child node).
+     */
     private List<Node> children;
 
     /**
@@ -41,13 +46,21 @@
         this.container = container;
     }
 
+    /**
+     * Returns the containing node for this node, or null if this node is the 
root element of the document.
+     */
     public Node getContainer()
     {
         return container;
     }
 
+    public Document getDocument()
+    {
+        return container.getDocument();
+    }
+
     /**
-     * Returns the node as an [EMAIL PROTECTED] Element}, if it is an element. 
Returns null otherwise.
+     * Returns the node as an [EMAIL PROTECTED] 
org.apache.tapestry5.dom.Element}, if it is an element. Returns null otherwise.
      */
     Element asElement()
     {
@@ -56,16 +69,25 @@
 
     void addChild(Node child)
     {
-        if (children == null) children = newList();
+        ensureChildren();
 
         children.add(child);
+
+        child.container = this;
+    }
+
+    private void ensureChildren()
+    {
+        if (children == null) children = CollectionFactory.newList();
     }
 
     void insertChildAt(int index, Node child)
     {
-        if (children == null) children = newList();
+        ensureChildren();
 
         children.add(index, child);
+
+        child.container = this;
     }
 
     boolean hasChildren()
@@ -73,7 +95,7 @@
         return children != null && !children.isEmpty();
     }
 
-    void writeChildMarkup(PrintWriter writer)
+    void writeChildMarkup(Document document, PrintWriter writer)
     {
         if (children == null) return;
 
@@ -88,7 +110,7 @@
     {
         PrintOutCollector collector = new PrintOutCollector();
 
-        writeChildMarkup(collector.getPrintWriter());
+        writeChildMarkup(getDocument(), collector.getPrintWriter());
 
         return collector.getPrintOut();
     }
@@ -100,18 +122,176 @@
     public String toString()
     {
         PrintOutCollector collector = new PrintOutCollector();
+
         toMarkup(collector.getPrintWriter());
+
         return collector.getPrintOut();
     }
 
+    /**
+     * Returns an unmodifiable list of children for this node. Only [EMAIL 
PROTECTED] org.apache.tapestry5.dom.Element}s will have
+     * children.  Also, note that unlike W3C DOM, attributes are not 
represented as [EMAIL PROTECTED]
+     * org.apache.tapestry5.dom.Node}s.
+     *
+     * @return unmodifiable list of children nodes
+     */
     @SuppressWarnings("unchecked")
     public List<Node> getChildren()
     {
-        return children == null ? Collections.EMPTY_LIST : children;
+        return children == null ? Collections.EMPTY_LIST : 
Collections.unmodifiableList(children);
     }
 
     /**
      * Writes the markup for this node to the writer.
      */
-    public abstract void toMarkup(PrintWriter writer);
+    public void toMarkup(PrintWriter writer)
+    {
+        toMarkup(getDocument(), writer);
+    }
+
+    /**
+     * Implemented by each subclass, with the document passed in for 
efficiency.
+     */
+    abstract void toMarkup(Document document, PrintWriter writer);
+
+    /**
+     * Moves this node so that it becomes a sibling of the element, ordered 
just before the element.
+     *
+     * @param element to move the node before
+     * @return the node for further modification
+     */
+    public Node moveBefore(Element element)
+    {
+        validateElement(element);
+
+        remove();
+
+        element.getContainer().insertChildBefore(element, this);
+
+        return this;
+    }
+
+
+    /**
+     * Moves this node so that it becomes a sibling of the element, ordered 
just after the element.
+     *
+     * @param element to move the node after
+     * @return the node for further modification
+     */
+    public Node moveAfter(Element element)
+    {
+        validateElement(element);
+
+        remove();
+
+        element.getContainer().insertChildAfter(element, this);
+
+        return this;
+    }
+
+    /**
+     * Moves this node so that it becomes this first child of the element, 
shifting existing elements forward.
+     *
+     * @param element to move the node inside
+     * @return the node for further modification
+     */
+    public Node moveToTop(Element element)
+    {
+        validateElement(element);
+
+        remove();
+
+        element.insertChildAt(0, this);
+
+        return this;
+    }
+
+    /**
+     * Moves this node so that it the last child of the element.
+     *
+     * @param element to move the node inside
+     * @return the node for further modification
+     */
+    public Node moveToBottom(Element element)
+    {
+        validateElement(element);
+
+        remove();
+
+        element.addChild(this);
+
+        return this;
+    }
+
+    private void validateElement(Element element)
+    {
+        Defense.notNull(element, "element");
+
+        Node search = element;
+        while (search != null)
+        {
+            if (search.equals(this))
+            {
+                throw new IllegalArgumentException("Unable to move a node 
relative to itself.");
+            }
+
+            search = search.getContainer();
+        }
+    }
+
+    /**
+     * Removes a node from its container, setting its container property to 
null, and removing it from its container's
+     * list of children.
+     */
+    public void remove()
+    {
+        getContainer().remove(this);
+
+        container = null;
+    }
+
+
+    /**
+     * Removes a child node from this node.
+     */
+    void remove(Node node)
+    {
+        if (children == null || !children.remove(node))
+            throw new IllegalArgumentException("Node to remove was not present 
as a child of this node.");
+    }
+
+    private void insertChildBefore(Node existing, Node node)
+    {
+        int index = indexOfNode(existing);
+
+        children.add(index, node);
+
+        node.container = this;
+    }
+
+    private void insertChildAfter(Node existing, Node node)
+    {
+        int index = indexOfNode(existing);
+
+        children.add(index + 1, node);
+
+        node.container = this;
+    }
+
+
+    private int indexOfNode(Node node)
+    {
+        ensureChildren();
+
+        int index = children.indexOf(node);
+
+        if (index < 0) throw new IllegalArgumentException("Existing element 
not a child of this node.");
+
+        return index;
+    }
+
+    void clearChildren()
+    {
+        children = null;
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Raw.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -34,9 +34,8 @@
      * Prints the text exactly as is, no translations, filtering, etc.
      */
     @Override
-    public void toMarkup(PrintWriter writer)
+    void toMarkup(Document document, PrintWriter writer)
     {
         writer.print(text);
     }
-
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/dom/Text.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2008 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.
@@ -23,14 +23,10 @@
 {
     private final StringBuilder buffer;
 
-    private final Document document;
-
-    Text(Node container, Document document, String text)
+    Text(Node container, String text)
     {
         super(container);
 
-        this.document = document;
-
         buffer = new StringBuilder(text.length());
 
         write(text);
@@ -41,7 +37,7 @@
      */
     public void write(String text)
     {
-        document.getMarkupModel().encode(text, buffer);
+        buffer.append(text);
     }
 
     public void writef(String format, Object... args)
@@ -50,9 +46,10 @@
     }
 
     @Override
-    public void toMarkup(PrintWriter writer)
+    void toMarkup(Document document, PrintWriter writer)
     {
-        writer.print(buffer.toString());
-    }
+        String encoded = document.getMarkupModel().encode(buffer.toString());
 
+        writer.print(encoded);
+    }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java?rev=692189&r1=692188&r2=692189&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/dom/DOMTest.java
 Thu Sep  4 11:44:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -465,4 +465,163 @@
 
         assertEquals(d.toString(), "<?xml version=\"1.0\" 
encoding=\"utf-8\"?>\n<root/>");
     }
+
+    @Test
+    public void move_before()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+
+        root.element("placeholder");
+
+        Element target = root.element("target");
+        Element mobile = root.element("source").element("mobile");
+
+        mobile.text("On the move");
+
+        assertEquals(d.toString(),
+                     
"<doc><placeholder></placeholder><target></target><source><mobile>On the 
move</mobile></source></doc>");
+
+
+        mobile.moveBefore(target);
+
+        assertEquals(d.toString(),
+                     "<doc><placeholder></placeholder><mobile>On the 
move</mobile><target></target><source></source></doc>");
+    }
+
+    @Test
+    public void move_after()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+        root.element("placeholder");
+
+        Element target = root.element("target");
+        Element mobile = root.element("source").element("mobile");
+
+        mobile.text("On the move");
+
+        assertEquals(d.toString(),
+                     
"<doc><placeholder></placeholder><target></target><source><mobile>On the 
move</mobile></source></doc>");
+
+
+        mobile.moveAfter(target);
+
+        assertEquals(d.toString(),
+                     
"<doc><placeholder></placeholder><target></target><mobile>On the 
move</mobile><source></source></doc>");
+    }
+
+    @Test
+    public void move_to_top()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+
+        Element target = root.element("target");
+        target.element("placeholder");
+        Element mobile = root.element("source").element("mobile");
+
+        mobile.text("On the move");
+
+        assertEquals(d.toString(),
+                     
"<doc><target><placeholder></placeholder></target><source><mobile>On the 
move</mobile></source></doc>");
+
+        mobile.moveToTop(target);
+
+        assertEquals(d.toString(),
+                     "<doc><target><mobile>On the 
move</mobile><placeholder></placeholder></target><source></source></doc>");
+    }
+
+    @Test
+    public void move_to_bottom()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+
+        Element target = root.element("target");
+        target.element("placeholder");
+        Element mobile = root.element("source").element("mobile");
+
+        mobile.text("On the move");
+
+        assertEquals(d.toString(),
+                     
"<doc><target><placeholder></placeholder></target><source><mobile>On the 
move</mobile></source></doc>");
+
+        mobile.moveToBottom(target);
+
+        assertEquals(d.toString(),
+                     "<doc><target><placeholder></placeholder><mobile>On the 
move</mobile></target><source></source></doc>");
+    }
+
+    @Test
+    public void remove_children()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+
+        root.element("before");
+        Element source = root.element("source");
+        Element mobile = source.element("mobile");
+        source.element("grok");
+        root.element("after");
+
+        mobile.text("On the move");
+
+        assertEquals(d.toString(),
+                     "<doc><before></before><source><mobile>On the 
move</mobile><grok></grok></source><after></after></doc>");
+
+        source.removeChildren();
+
+        assertEquals(d.toString(),
+                     
"<doc><before></before><source></source><after></after></doc>");
+    }
+
+    @Test
+    public void pop()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+
+        Element source = root.element("source");
+        source.element("mobile").text("On the move");
+        source.element("grok");
+
+        assertEquals(d.toString(),
+                     "<doc><source><mobile>On the 
move</mobile><grok></grok></source></doc>");
+
+        source.pop();
+
+        assertEquals(d.toString(),
+                     "<doc><mobile>On the move</mobile><grok></grok></doc>");
+    }
+
+    @Test
+    public void move_an_node_into_itself()
+    {
+        Document d = new Document();
+
+        Element root = d.newRootElement("doc");
+
+        Element target = root.element("target");
+        target.element("placeholder");
+        Element mobile = root.element("source").element("mobile");
+        mobile.text("On the move");
+        Element inside = mobile.element("inside");
+
+        try
+        {
+            mobile.moveToTop(inside);
+            unreachable();
+        }
+        catch (IllegalArgumentException ex)
+        {
+            assertEquals(ex.getMessage(), "Unable to move a node relative to 
itself.");
+        }
+    }
 }


Reply via email to