dev@javaserverfaces.java.net

Seeking Review: nested content in outputScript, outputStylesheet

From: Ed Burns <Ed.Burns_at_Sun.COM>
Date: Tue, 02 Dec 2008 10:25:25 -0800

https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=115

Attachment

https://javaserverfaces-spec-public.dev.java.net/nonav/issues/showattachment.cgi/169/changebundle.txt

Issue: 115 Resource

Make it so content nested inside of <h:outputScript> and
<h:outputStylesheet> is rendered.


SECTION: Modified Files
----------------------------
M jsf-api/doc/standard-html-renderkit-base.xml
M jsf-api/doc/output-resource-props.xml
M jsf-api/doc/standard-html-renderkit.xml

- Documentataion changes

M jsf-ri/src/com/sun/faces/renderkit/html_basic/StylesheetRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/ScriptRenderer.java

- Changes to match spec

A jsf-ri/systest/src/com/sun/faces/render/OutputScriptStyleTestCase.java
A jsf-ri/systest/web/render/outputScriptStyleNested.xhtml

- New automated tests


SECTION: Diffs
----------------------------
Index: jsf-api/doc/standard-html-renderkit-base.xml
===================================================================
--- jsf-api/doc/standard-html-renderkit-base.xml (revision 5978)
+++ jsf-api/doc/standard-html-renderkit-base.xml (working copy)
@@ -2709,9 +2709,8 @@
             <description><![CDATA[<div class="changed_added_2_0">
 
 <p>Render the markup for a <code>&lt;script&gt;</code> element that
-renders the script <code>Resource</code> specified by the required
-<code>name</code> attribute and optional <code>library</code>
-attribute.</p>
+renders the script <code>Resource</code> specified by the optional
+<code>name</code> attribute and <code>library</code> attributes.</p>
 
 <p>The implementation of this renderer must have a <a target="_"
 href="../../javadocs/javax/faces/event/ListenerFor.html"><code>@ListenerFor</code></a>
@@ -2751,14 +2750,26 @@
           encoding.</p>
 
           <li><p>Look in the component attribute <code>Map</code> for a
- value under the key <em>name</em>. A value is required for
- this attribute.</p></li>
+ value under the key <em>name</em>.</p></li>
 
           <li><p>Look in the component attribute <code>Map</code> for a
           value under the key <em>library</em>. This attribute is
           optional, therefore, <em>library</em> may be
           <code>null</code>.</p></li>
 
+ <li><p>If <em>name</em> is <code>null</code>, and the argument
+ <code>component</code> has no children, and
+ <code>ProjectStage</code> is not
+ <code>ProjectStage.Production</code>, add a
+ <code>FacesMessage</code> for this component's clientId to the
+ <code>FacesContext</code> stating that if no name attribute is
+ present, and no body content is present either, then the user
+ should take action to correct this problem. If <em>name</em>
+ is <code>null</code> and the argument <code>component</code>
+ <b>does</b> have children, simply return from the encode,
+ assuming the children will be rendered normally, and their
+ retargeting will happen as specified.</p></li>
+
           <li><p>Create the resource by calling
           <code>Application.getResourceHandler.createResource(<em>name</em>,
           <em>library</em>);</code>.</p></li>
@@ -2811,9 +2822,8 @@
             <description><![CDATA[<div class="changed_added_2_0">
 
 <p>Render the markup for a <code>&lt;link&gt;</code> element that
-renders the style <code>Resource</code> specified by the required
-<code>name</code> attribute and optional <code>library</code>
-attribute.</p>
+renders the style <code>Resource</code> specified by the optional
+<code>name</code> and <code>library</code> attributes.</p>
 
       <p>Decode Behavior</p>
 
Index: jsf-api/doc/output-resource-props.xml
===================================================================
--- jsf-api/doc/output-resource-props.xml (revision 5978)
+++ jsf-api/doc/output-resource-props.xml (working copy)
@@ -62,7 +62,7 @@
         <attribute-name>name</attribute-name>
         <attribute-class>java.lang.String</attribute-class>
         <attribute-extension>
- <required>true</required>
+ <required>false</required>
             <tag-attribute>false</tag-attribute>
         </attribute-extension>
 
Index: jsf-api/doc/standard-html-renderkit.xml
===================================================================
--- jsf-api/doc/standard-html-renderkit.xml (revision 5978)
+++ jsf-api/doc/standard-html-renderkit.xml (working copy)
@@ -36,7 +36,7 @@
 -->
 <!-- =========== FULL CONFIGURATION FILE ================================== -->
 <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0">
- <!-- Generic User Interface Components -->
+<!-- Generic User Interface Components -->
   <component>
     <component-type>javax.faces.Column</component-type>
     <component-class>javax.faces.component.UIColumn</component-class>
@@ -373,7 +373,7 @@
         <method-signature>
                 void actionListener(javax.faces.event.ActionEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -1326,7 +1326,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -2704,7 +2704,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -3424,7 +3424,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -3785,7 +3785,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -4011,7 +4011,7 @@
       <component-family>javax.faces.ViewRoot</component-family>
     </component-extension>
   </component>
- <!-- Concrete HTML Components -->
+<!-- Concrete HTML Components -->
   <component>
     <description><![CDATA[<p>Represents a column that will be rendered
       in an HTML <code>table</code> element.</p>]]></description>
@@ -4382,7 +4382,7 @@
         <method-signature>
                 void actionListener(javax.faces.event.ActionEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -4987,7 +4987,7 @@
         <method-signature>
                 void actionListener(javax.faces.event.ActionEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -7298,7 +7298,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -7653,7 +7653,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -8399,7 +8399,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -9129,7 +9129,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -13050,7 +13050,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -13740,7 +13740,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -14498,7 +14498,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -15220,7 +15220,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -15932,7 +15932,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -16641,7 +16641,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -17340,7 +17340,7 @@
         <method-signature>
                 void valueChange(javax.faces.event.ValueChangeEvent)
             </method-signature>
- <!-- PENDING modify tlddoc to handle an OR of method signatures
+<!-- PENDING modify tlddoc to handle an OR of method signatures
 as required by
 https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
             <method-signature>
@@ -17756,7 +17756,7 @@
       <renderer-type>javax.faces.Radio</renderer-type>
     </component-extension>
   </component>
- <!-- Standard HTML Renderkit -->
+<!-- Standard HTML Renderkit -->
   <render-kit>
     <description><![CDATA[
      The standard HTML RenderKit. Please see the spec for additional
@@ -20071,7 +20071,7 @@
         <attribute-name>name</attribute-name>
         <attribute-class>java.lang.String</attribute-class>
         <attribute-extension>
- <required>true</required>
+ <required>false</required>
           <tag-attribute>false</tag-attribute>
         </attribute-extension>
       </attribute>
@@ -26567,9 +26567,8 @@
       <description><![CDATA[<div class="changed_added_2_0">
 
 <p>Render the markup for a <code>&lt;script&gt;</code> element that
-renders the script <code>Resource</code> specified by the required
-<code>name</code> attribute and optional <code>library</code>
-attribute.</p>
+renders the script <code>Resource</code> specified by the optional
+<code>name</code> attribute and <code>library</code> attributes.</p>
 
 <p>The implementation of this renderer must have a <a target="_"
 href="../../javadocs/javax/faces/event/ListenerFor.html"><code>@ListenerFor</code></a>
@@ -26609,14 +26608,26 @@
           encoding.</p>
 
           <li><p>Look in the component attribute <code>Map</code> for a
- value under the key <em>name</em>. A value is required for
- this attribute.</p></li>
+ value under the key <em>name</em>.</p></li>
 
           <li><p>Look in the component attribute <code>Map</code> for a
           value under the key <em>library</em>. This attribute is
           optional, therefore, <em>library</em> may be
           <code>null</code>.</p></li>
 
+ <li><p>If <em>name</em> is <code>null</code>, and the argument
+ <code>component</code> has no children, and
+ <code>ProjectStage</code> is not
+ <code>ProjectStage.Production</code>, add a
+ <code>FacesMessage</code> for this component's clientId to the
+ <code>FacesContext</code> stating that if no name attribute is
+ present, and no body content is present either, then the user
+ should take action to correct this problem. If <em>name</em>
+ is <code>null</code> and the argument <code>component</code>
+ <b>does</b> have children, simply return from the encode,
+ assuming the children will be rendered normally, and their
+ retargeting will happen as specified.</p></li>
+
           <li><p>Create the resource by calling
           <code>Application.getResourceHandler.createResource(<em>name</em>,
           <em>library</em>);</code>.</p></li>
@@ -26667,7 +26678,7 @@
         <attribute-name>name</attribute-name>
         <attribute-class>java.lang.String</attribute-class>
         <attribute-extension>
- <required>true</required>
+ <required>false</required>
           <tag-attribute>false</tag-attribute>
         </attribute-extension>
       </attribute>
@@ -26702,9 +26713,8 @@
       <description><![CDATA[<div class="changed_added_2_0">
 
 <p>Render the markup for a <code>&lt;link&gt;</code> element that
-renders the style <code>Resource</code> specified by the required
-<code>name</code> attribute and optional <code>library</code>
-attribute.</p>
+renders the style <code>Resource</code> specified by the optional
+<code>name</code> and <code>library</code> attributes.</p>
 
       <p>Decode Behavior</p>
 
@@ -26758,7 +26768,7 @@
         <attribute-name>name</attribute-name>
         <attribute-class>java.lang.String</attribute-class>
         <attribute-extension>
- <required>true</required>
+ <required>false</required>
           <tag-attribute>false</tag-attribute>
         </attribute-extension>
       </attribute>
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/StylesheetRenderer.java
===================================================================
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/StylesheetRenderer.java (revision 5978)
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/StylesheetRenderer.java (working copy)
@@ -39,9 +39,10 @@
 import java.io.IOException;
 import java.util.Map;
 
+import javax.faces.application.FacesMessage;
+import javax.faces.application.ProjectStage;
 import javax.faces.application.Resource;
 import javax.faces.component.UIComponent;
-import javax.faces.component.UIOutput;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.event.AbortProcessingException;
@@ -100,6 +101,18 @@
         String library = (String) attributes.get("library");
         String key = name + library;
         
+ if (null == name) {
+ if (0 == component.getChildCount()) {
+ if (ProjectStage.Production != context.getApplication().getProjectStage()) {
+ FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN,
+ "outputStylesheet with no library, no name, and no body content",
+ "Is body content intended?");
+ context.addMessage(component.getClientId(context), message);
+ }
+ }
+ return;
+ }
+
         // Ensure this stylesheet is not rendered more than once per request
         if (contextMap.containsKey(key)) {
             return;
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/ScriptRenderer.java
===================================================================
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/ScriptRenderer.java (revision 5978)
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/ScriptRenderer.java (working copy)
@@ -39,12 +39,13 @@
 import java.io.IOException;
 import java.util.Map;
 
+import javax.faces.application.FacesMessage;
+import javax.faces.application.ProjectStage;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.render.Renderer;
 import javax.faces.application.Resource;
-import javax.faces.component.UIOutput;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.AfterAddToParentEvent;
 import javax.faces.event.ComponentSystemEvent;
@@ -94,7 +95,7 @@
           throws IOException {
         // no-op
     }
-
+
     @Override
     public void encodeChildren(FacesContext context, UIComponent component)
           throws IOException {
@@ -113,6 +114,18 @@
         
         String key = name + library;
         
+ if (null == name) {
+ if (0 == component.getChildCount()) {
+ if (ProjectStage.Production != context.getApplication().getProjectStage()) {
+ FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN,
+ "outputScript with no library, no name, and no body content",
+ "Is body content intended?");
+ context.addMessage(component.getClientId(context), message);
+ }
+ }
+ return;
+ }
+
         // Ensure this script is not rendered more than once per request
         if (contextMap.containsKey(key)) {
             return;
Index: jsf-ri/systest/src/com/sun/faces/render/OutputScriptStyleTestCase.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/render/OutputScriptStyleTestCase.java (revision 0)
+++ jsf-ri/systest/src/com/sun/faces/render/OutputScriptStyleTestCase.java (revision 0)
@@ -0,0 +1,81 @@
+package com.sun.faces.render;
+
+import com.sun.faces.htmlunit.AbstractTestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import com.gargoylesoftware.htmlunit.html.*;
+
+
+public class OutputScriptStyleTestCase extends AbstractTestCase {
+
+ public OutputScriptStyleTestCase(String name) {
+ super(name);
+ }
+
+ /**
+ * Set up instance variables required by this test case.
+ */
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+
+ /**
+ * Return the tests included in this test suite.
+ */
+ public static Test suite() {
+ return (new TestSuite(OutputScriptStyleTestCase.class));
+ }
+
+
+ /**
+ * Tear down instance variables required by this test case.
+ */
+ public void tearDown() {
+ super.tearDown();
+ }
+
+
+ public void testOutputScriptStyle() throws Exception {
+ HtmlPage page = getPage("/faces/render/outputScriptStyleNested.xhtml");
+
+ String text = page.asXml();
+ assertTrue(text.matches(
+ "(?s).*<head>.*"+
+ "<style type=\"text/css\">.*" +
+ "\\.style0 \\{ color: red \\}.*" +
+ "</style>.*" +
+ "</head>.*"
+ ));
+ assertTrue(text.matches(
+ "(?s).*<head>.*"+
+ "<script type=\"text/javascript\">.*" +
+ "alert\\(\"script1 invoked\"\\);.*" +
+ "</script>.*" +
+ "</head>.*"
+ ));
+ assertTrue(text.matches(
+ "(?s).*<body>.*"+
+ "<script type=\"text/javascript\">.*" +
+ "alert\\(\"script0 invoked\"\\);.*" +
+ "</script>.*" +
+ "</body>.*"
+ ));
+ assertTrue(text.matches(
+ "(?s).*<head>.*"+
+ "<script type=\"text/javascript\">.*" +
+ "alert\\(\"script2 invoked\"\\);.*" +
+ "</script>.*<script type=\"text/javascript\" src=\"/jsf-systest/faces/javax.faces.resource/simple.js\">.*</script>.*" +
+ "</head>.*"
+ ));
+ assertTrue(text.matches(
+ "(?s).*<head>.*"+
+ "<style type=\"text/css\">.*" +
+ "\\.style1 \\{ color: blue \\}.*" +
+ "</style>.*<link.* type=\"text/css\".* rel=\"stylesheet\".* href=\"/jsf-systest/faces/javax.faces.resource/simple.css\".*" +
+ "</head>.*"
+ ));
+
+
+ }
+}
\ No newline at end of file
Index: jsf-ri/systest/web/render/outputScriptStyleNested.xhtml
===================================================================
--- jsf-ri/systest/web/render/outputScriptStyleNested.xhtml (revision 0)
+++ jsf-ri/systest/web/render/outputScriptStyleNested.xhtml (revision 0)
@@ -0,0 +1,56 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core">
+<h:head>
+ <title>Test nested output script content</title>
+</h:head>
+<h:body>
+ <h:form prependId="false">
+
+ <h:outputScript id="script0">
+
+ <script type="text/javascript">
+ alert("script0 invoked");
+ </script>
+
+
+ </h:outputScript>
+
+ <h:outputScript target="head">
+
+ <script type="text/javascript">
+ alert("script1 invoked");
+ </script>
+
+ </h:outputScript>
+
+ <h:outputStylesheet>
+ <style type="text/css">
+
+.style0 { color: red }
+ </style>
+ </h:outputStylesheet>
+
+ <h:outputScript target="head" name="simple.js">
+ <script type="text/javascript">
+ alert("script2 invoked");
+ </script>
+
+ </h:outputScript>
+
+ <h:outputStylesheet name="simple.css">
+ <style type="text/css">
+
+.style1 { color: blue }
+ </style>
+ </h:outputStylesheet>
+
+
+
+
+ </h:form>
+</h:body>
+</html>



-- 
| ed.burns_at_sun.com  | office: 408 884 9519 OR x31640
| homepage:         | http://ridingthecrest.com/