You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/01/12 19:12:12 UTC

svn commit: r611448 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/internal/services/ site/apt/guide/ test/java/org/apache/tapestry/internal/services/ test/resources/org/apache/tapestry/internal/services/

Author: hlship
Date: Sat Jan 12 10:12:11 2008
New Revision: 611448

URL: http://svn.apache.org/viewvc?rev=611448&view=rev
Log:
TAPESTRY-2028: Mimimize whitespace in the output markup

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java?rev=611448&r1=611447&r2=611448&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/TemplateParserImpl.java Sat Jan 12 10:12:11 2008
@@ -60,9 +60,17 @@
     private static final Pattern ID_PATTERN = Pattern.compile("^[a-z]\\w*$", Pattern.CASE_INSENSITIVE);
 
     /**
-     * Used when compressing whitespace.
+     * Any amount of mixed simple whitespace (space, tab, form feed) mixed with at least one carriage return or line feed,
+     * followed by any amount of whitespace.  Will be reduced to a single linefeed.
      */
-    private static final Pattern REDUCE_WHITESPACE_PATTERN = Pattern.compile("//s+");
+    private static final Pattern REDUCE_LINEBREAKS_PATTERN = Pattern.compile("[ \\t\\f]*[\\r\\n]\\s*",
+                                                                             Pattern.MULTILINE);
+
+    /**
+     * Used when compressing whitespace, matches any sequence of simple whitespace (space, tab, formfeed). Applied
+     * after REDUCE_LINEBREAKS_PATTERN.
+     */
+    private static final Pattern REDUCE_WHITESPACE_PATTERN = Pattern.compile("[ \\t\\f]+", Pattern.MULTILINE);
 
     // Note the use of the non-greedy modifier; this prevents the pattern from merging multiple
     // expansions on the same text line into a single large
@@ -70,7 +78,7 @@
 
     private static final String EXPANSION_REGEXP = "\\$\\{\\s*(.*?)\\s*}";
 
-    private static final Pattern EXPANSION_PATTERN = Pattern.compile(EXPANSION_REGEXP, Pattern.MULTILINE);
+    private static final Pattern EXPANSION_PATTERN = Pattern.compile(EXPANSION_REGEXP);
 
 
     private XMLReader _reader;
@@ -251,18 +259,31 @@
 
         String text = _textBuffer.toString();
 
+        _textBuffer.setLength(0);
+
         if (_textIsCData)
         {
             _tokens.add(new CDATAToken(text, _textStartLocation));
+
+            return;
         }
-        else
+
+        if (_compressWhitespace)
         {
-            if (_compressWhitespace) text = REDUCE_WHITESPACE_PATTERN.matcher(text.trim()).replaceAll(" ");
+            text = compressWhitespaceInText(text);
 
-            addTokensForText(text);
+            if (InternalUtils.isBlank(text)) return;
         }
 
-        _textBuffer.setLength(0);
+
+        addTokensForText(text);
+    }
+
+    private String compressWhitespaceInText(String text)
+    {
+        String linebreaksReduced = REDUCE_LINEBREAKS_PATTERN.matcher(text).replaceAll("\n");
+
+        return REDUCE_WHITESPACE_PATTERN.matcher(linebreaksReduced).replaceAll(" ");
     }
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt?rev=611448&r1=611447&r2=611448&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/templates.apt Sat Jan 12 10:12:11 2008
@@ -342,9 +342,10 @@
    
 Whitespace in Templates
 
-  Tapestry strips out unnecessary whitespace from templates as they are parsed.  This includes whitespace
-  immediately before and after a start or end tag.  Inside any block of text, repeated whitespace is reduced
-  to a single space character.
+  Tapestry strips out unnecessary whitespace from templates as they are parsed.
+  Inside any block of text, repeated whitespace is reduced
+  to a single space character.  Blocks of text that are entirely whitespace, such a line break
+  and whitespace between two tags, is eliminated entirely.
 
   If you do a view source on the rendered output, you'll see that the bulk of the rendered page is one
   long unbroken line.

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java?rev=611448&r1=611447&r2=611448&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java Sat Jan 12 10:12:11 2008
@@ -611,19 +611,28 @@
     @DataProvider(name = "parse_failure_data")
     public Object[][] parse_failure_data()
     {
-        return new Object[][]{{"mixin_requires_id_or_type.tml",
-                               "You may not specify mixins for element <span> because it does not represent a component (which requires either an id attribute or a type attribute).",
-                               2}, {"illegal_nesting_within_body_element.tml",
-                                    "Element 'xyz' is nested within a Tapestry body element", 2}, {
-                "unexpected_attribute_in_parameter_element.tml",
-                "Element <parameter> does not support an attribute named 'grok'. The only allowed attribute name is 'name'.",
-                4}, {"name_attribute_of_parameter_element_omitted.tml",
-                     "The name attribute of the <parameter> element must be specified.", 4}, {
-                "name_attribute_of_parameter_element_blank.tml",
-                "The name attribute of the <parameter> element must be specified.", 4}, {
-                "unexpected_attribute_in_block_element.tml",
-                "Element <block> does not support an attribute named 'name'. The only allowed attribute name is 'id'.",
-                3},
+        return new Object[][]{
+
+                {"mixin_requires_id_or_type.tml",
+                 "You may not specify mixins for element <span> because it does not represent a component (which requires either an id attribute or a type attribute).",
+                 2},
+
+                {"illegal_nesting_within_body_element.tml", "Element 'xyz' is nested within a Tapestry body element",
+                 2},
+
+                {"unexpected_attribute_in_parameter_element.tml",
+                 "Element <parameter> does not support an attribute named 'grok'. The only allowed attribute name is 'name'.",
+                 4},
+
+                {"name_attribute_of_parameter_element_omitted.tml",
+                 "The name attribute of the <parameter> element must be specified.", 4},
+
+                {"name_attribute_of_parameter_element_blank.tml",
+                 "The name attribute of the <parameter> element must be specified.", 4},
+
+                {"unexpected_attribute_in_block_element.tml",
+                 "Element <block> does not support an attribute named 'name'. The only allowed attribute name is 'id'.",
+                 3},
 
         };
     }
@@ -757,6 +766,23 @@
 
         TextToken token2 = get(tokens, 2);
         assertEquals(token2.getText(), "\n" + "        some text\n" + "    ");
+
+    }
+
+    @Test
+    public void minimal_whitespace_maintained_inside_tags() throws Exception
+    {
+        List<TemplateToken> tokens = tokens("minimal_whitespace_maintained_inside_tags.tml");
+
+        // A line feed or carriage return surrounded by other whitespace is reduced to
+        // just a line feed.
+
+        TextToken token1 = get(tokens, 1);
+        assertEquals(token1.getText(), "\nWhitespace\n");
+
+
+        TextToken token5 = get(tokens, 5);
+        assertEquals(token5.getText(), "\nis maintained.\n");
 
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml?rev=611448&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/internal/services/minimal_whitespace_maintained_inside_tags.tml Sat Jan 12 10:12:11 2008
@@ -0,0 +1,8 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    Whitespace
+    <em>around tags</em>
+
+    is maintained.
+
+
+</html>
\ No newline at end of file