Author: ehillenius
Date: Sun Nov 19 15:13:03 2006
New Revision: 476971

URL: http://svn.apache.org/viewvc?view=rev&rev=476971
Log:
WICKET-95: Backport of Header contribution filtering

Added:
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderResponse.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java
Modified:
    
incubator/wicket/branches/wicket-1.x/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Component.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractAjaxTimerBehavior.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractDefaultAjaxBehavior.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractAjaxBehavior.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractHeaderContributor.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/HeaderContributor.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/StringHeaderContributor.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderContributor.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/WebPage.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java
    
incubator/wicket/branches/wicket-1.x/wicket/src/test/java/wicket/behavior/AjaxHandlerBodyOnLoadPage.java

Modified: 
incubator/wicket/branches/wicket-1.x/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
 Sun Nov 19 15:13:03 2006
@@ -21,6 +21,7 @@
 import wicket.Response;
 import wicket.ajax.AbstractDefaultAjaxBehavior;
 import wicket.ajax.AjaxRequestTarget;
+import wicket.markup.html.IHeaderResponse;
 import wicket.markup.html.resources.CompressedResourceReference;
 import wicket.util.string.JavascriptUtils;
 
@@ -34,32 +35,31 @@
        private static final ResourceReference AUTOCOMPLETE_JS = new 
CompressedResourceReference(
                        AutoCompleteBehavior.class, "wicket-autocomplete.js");
 
-       /**
-        * 
-        */
        private static final long serialVersionUID = 1L;
 
-       protected void onRenderHeadContribution(Response response)
-       {       
+       /**
+        * @see 
wicket.ajax.AbstractDefaultAjaxBehavior#renderHead(wicket.markup.html.IHeaderResponse)
+        */
+       public void renderHead(IHeaderResponse response)
+       {
+               super.renderHead(response);
+               response.renderJavascriptReference(AUTOCOMPLETE_JS);
        }
-       
+
        protected void onBind()
        {
-               // add empty AbstractDefaultAjaxBehavior to the component, to 
force 
-               // rendering wicket-ajax.js reference if no other ajax behavior 
is on page
-               getComponent().add(new AbstractDefaultAjaxBehavior() {
+               // add empty AbstractDefaultAjaxBehavior to the component, to 
force
+               // rendering wicket-ajax.js reference if no other ajax behavior 
is on
+               // page
+               getComponent().add(new AbstractDefaultAjaxBehavior()
+               {
                        private static final long serialVersionUID = 1L;
 
                        protected void respond(AjaxRequestTarget target)
-                       {                               
-                       }                                               
+                       {
+                       }
                });
        }
-       
-       protected void onRenderHeadInitContribution(Response response)
-       {
-               writeJsReference(response, AUTOCOMPLETE_JS);
-       }
 
        protected void onComponentRendered()
        {
@@ -70,18 +70,6 @@
                response.write(JavascriptUtils.SCRIPT_CLOSE_TAG);
        }
 
-       protected String getImplementationId()
-       {               
-               return "wicket-autocomplete";
-       }
-       
-       protected void respond(AjaxRequestTarget target)
-       {
-               final RequestCycle requestCycle = RequestCycle.get();
-               final String val = requestCycle.getRequest().getParameter("q");
-               onRequest(val, requestCycle);
-       }               
-
        /**
         * Callback for the ajax event generated by the javascript. This is 
where we
         * need to generate our response.
@@ -92,4 +80,14 @@
         *            current request cycle
         */
        protected abstract void onRequest(String input, RequestCycle 
requestCycle);
+
+       /**
+        * @see 
wicket.ajax.AbstractDefaultAjaxBehavior#respond(wicket.ajax.AjaxRequestTarget)
+        */
+       protected void respond(AjaxRequestTarget target)
+       {
+               final RequestCycle requestCycle = RequestCycle.get();
+               final String val = requestCycle.getRequest().getParameter("q");
+               onRequest(val, requestCycle);
+       }
 }

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Component.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Component.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Component.java 
(original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Component.java 
Sun Nov 19 15:13:03 2006
@@ -1837,7 +1837,7 @@
                                        IBehavior behavior = 
(IBehavior)iter.next();
                                        if (behavior instanceof 
IHeaderContributor)
                                        {
-                                               
((IHeaderContributor)behavior).renderHead(container.getResponse());
+                                               
((IHeaderContributor)behavior).renderHead(container.getHeaderResponse());
                                        }
                                }
                        }

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractAjaxTimerBehavior.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractAjaxTimerBehavior.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractAjaxTimerBehavior.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractAjaxTimerBehavior.java
 Sun Nov 19 15:13:03 2006
@@ -17,6 +17,7 @@
 package wicket.ajax;
 
 import wicket.Response;
+import wicket.markup.html.IHeaderResponse;
 import wicket.markup.html.WebPage;
 import wicket.util.time.Duration;
 
@@ -57,11 +58,11 @@
        }
 
        /**
-        * @see 
wicket.behavior.AbstractAjaxBehavior#onRenderHeadContribution(wicket.Response)
+        * @see 
wicket.behavior.AbstractAjaxBehavior#renderHead(wicket.markup.html.IHeaderResponse)
         */
-       protected void onRenderHeadContribution(final Response response)
+       public void renderHead(IHeaderResponse response)
        {
-               super.onRenderHeadContribution(response);
+               super.renderHead(response);
 
                if (this.attachedBodyOnLoadModifier == false)
                {

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractDefaultAjaxBehavior.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractDefaultAjaxBehavior.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractDefaultAjaxBehavior.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AbstractDefaultAjaxBehavior.java
 Sun Nov 19 15:13:03 2006
@@ -22,6 +22,7 @@
 import wicket.ResourceReference;
 import wicket.Response;
 import wicket.behavior.AbstractAjaxBehavior;
+import wicket.markup.html.IHeaderResponse;
 import wicket.markup.html.resources.CompressedResourceReference;
 import wicket.settings.IAjaxSettings;
 import wicket.util.string.AppendingStringBuffer;
@@ -58,15 +59,6 @@
                        AbstractDefaultAjaxBehavior.class, 
"wicket-ajax-debug.js");
 
        /**
-        * 
-        * @see wicket.behavior.AbstractAjaxBehavior#getImplementationId()
-        */
-       protected String getImplementationId()
-       {
-               return "wicket-default";
-       }
-
-       /**
         * Subclasses should call super.onBind()
         * 
         * @see wicket.behavior.AbstractAjaxBehavior#onBind()
@@ -77,20 +69,21 @@
        }
 
        /**
-        * 
-        * @see 
wicket.behavior.AbstractAjaxBehavior#onRenderHeadInitContribution(wicket.Response)
+        * @see 
wicket.behavior.AbstractAjaxBehavior#renderHead(wicket.markup.html.IHeaderResponse)
         */
-       protected void onRenderHeadInitContribution(final Response response)
+       public void renderHead(IHeaderResponse response)
        {
+               super.renderHead(response);
+               
                final IAjaxSettings settings = 
Application.get().getAjaxSettings();
 
-               writeJsReference(response, JAVASCRIPT);
-
+               response.renderJavascriptReference(JAVASCRIPT);
+               
                if (settings.isAjaxDebugModeEnabled())
                {
-                       JavascriptUtils.writeJavascript(response, 
"wicketAjaxDebugEnable=true;", "wicket-ajax-debug-enable");
-                       writeJsReference(response, JAVASCRIPT_DEBUG_DRAG);
-                       writeJsReference(response, JAVASCRIPT_DEBUG);
+                       
response.renderJavascript("wicketAjaxDebugEnable=true;", 
"wicket-ajax-debug-enable");                   
+                       
response.renderJavascriptReference(JAVASCRIPT_DEBUG_DRAG);                      
+                       response.renderJavascriptReference( JAVASCRIPT_DEBUG);
                }
        }
 

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java
 Sun Nov 19 15:13:03 2006
@@ -496,6 +496,9 @@
                encodingBodyResponse.reset();
        }
 
+       
+       private HtmlHeaderContainer header = null;
+       
        /**
         * 
         * @param response
@@ -503,8 +506,11 @@
         */
        private void respondHeaderContribution(final Response response, final 
Component component)
        {
-               final HtmlHeaderContainer header = new HtmlHeaderContainer(
-                               HtmlHeaderSectionHandler.HEADER_ID);
+               if (header == null) {
+                       header = new HtmlHeaderContainer(
+                                       HtmlHeaderSectionHandler.HEADER_ID);    
+               }
+               
                if (component.getPage().get(HtmlHeaderSectionHandler.HEADER_ID) 
!= null)
                {
                        component.getPage().replace(header);

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractAjaxBehavior.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractAjaxBehavior.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractAjaxBehavior.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractAjaxBehavior.java
 Sun Nov 19 15:13:03 2006
@@ -16,20 +16,14 @@
  */
 package wicket.behavior;
 
-import java.util.HashSet;
-import java.util.Set;
-
 import wicket.Component;
-import wicket.RequestCycle;
 import wicket.RequestListenerInterface;
-import wicket.ResourceReference;
 import wicket.Response;
 import wicket.markup.ComponentTag;
 import wicket.markup.html.IHeaderContributor;
-import wicket.markup.html.PackageResourceReference;
+import wicket.markup.html.IHeaderResponse;
 import wicket.protocol.http.request.WebRequestCodingStrategy;
 import wicket.util.string.AppendingStringBuffer;
-import wicket.util.string.JavascriptUtils;
 
 /**
  * Abstract class for handling Ajax roundtrips. This class serves as a base for
@@ -45,9 +39,6 @@
                        IBehaviorListener,
                        IHeaderContributor
 {
-       /** thread local for head contributions. */
-       private static final ThreadLocal headContribHolder = new ThreadLocal();
-
        /** the component that this handler is bound to. */
        private Component component;
 
@@ -169,69 +160,10 @@
        }
 
        /**
-        * @see wicket.behavior.AbstractBehavior#cleanup()
+        * @see 
wicket.markup.html.IHeaderContributor#renderHead(IHeaderResponse)
         */
-       public void cleanup()
+       public void renderHead(final IHeaderResponse response)
        {
-               headContribHolder.set(null);
-       }
-
-       /**
-        * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.Response)
-        */
-       public final void renderHead(final Response response)
-       {
-               Set contributors = (Set)headContribHolder.get();
-
-               // were any contributors set?
-               if (contributors == null)
-               {
-                       contributors = new HashSet(1);
-                       headContribHolder.set(contributors);
-               }
-
-               // get the id of the implementation; we need this trick to be
-               // able to support multiple implementations
-               String implementationId = getImplementationId();
-
-               // was a contribution for this specific implementation done yet?
-               if (!contributors.contains(implementationId))
-               {
-                       onRenderHeadInitContribution(response);
-                       contributors.add(implementationId);
-               }
-
-               onRenderHeadContribution(response);
-       }
-
-       /**
-        * Convenience method to add a javascript reference.
-        * 
-        * @param response
-        * 
-        * @param ref
-        *            reference to add
-        * @deprecated use [EMAIL PROTECTED] #writeJsReference(Response, 
ResourceReference)} instead
-        */
-       protected void writeJsReference(final Response response, final 
PackageResourceReference ref)
-       {
-               CharSequence url = RequestCycle.get().urlFor(ref);
-               JavascriptUtils.writeJavascriptUrl(response, url);
-       }
-
-
-       /**
-        * Convenience method to add a javascript reference.
-        * 
-        * @param response
-        * 
-        * @param ref
-        *            reference to add
-        */
-       protected void writeJsReference(final Response response, final 
ResourceReference ref)
-       {
-               CharSequence url = RequestCycle.get().urlFor(ref);
-               JavascriptUtils.writeJavascriptUrl(response, url);
        }
 
        /**
@@ -245,20 +177,6 @@
        }
 
        /**
-        * Gets the unique id of an ajax implementation. This should be 
implemented
-        * by base classes only - like the dojo or scriptaculous implementation 
- to
-        * provide a means to differentiate between implementations while not 
going
-        * to the level of concrete implementations. It is used to ensure 
'static'
-        * header contributions are done only once per implementation.
-        * 
-        * @return unique id of an ajax implementation
-        * 
-        * @deprecated The mechanism will be changed for Wicket 2.0, where 
doubles
-        *             are filtered in (future) class IHeaderResponse.
-        */
-       protected abstract String getImplementationId();
-
-       /**
         * Called any time a component that has this handler registered is 
rendering
         * the component tag. Use this method e.g. to bind to javascript event
         * handlers of the tag
@@ -288,33 +206,27 @@
        }
 
        /**
-        * Let this handler print out the needed header contributions. This
-        * implementation does nothing.
-        * 
-        * @param response
-        *            head container
+        * @see wicket.behavior.AbstractBehavior#getStatelessHint()
         */
-       protected void onRenderHeadContribution(final Response response)
+       public boolean getStatelessHint()
        {
+               return false;
        }
 
-       /**
-        * Do a one time (per page) header contribution that is the same for all
-        * ajax variant implementations (e.g. Dojo, Scriptaculous). This
-        * implementation does nothing.
-        * 
-        * @param response
-        *            head container
-        */
-       protected void onRenderHeadInitContribution(final Response response)
+
+       // TODO the next three methods will be removed with next commit. Here as
+       // final to help with refactoring
+
+       protected final String getImplementationId()
        {
+               return "foo";
        }
-       
-       /**
-        * @see wicket.behavior.AbstractBehavior#getStatelessHint()
-        */
-       public boolean getStatelessHint()
+
+       protected final void onRenderHeadContribution(final Response response)
+       {
+       }
+
+       protected final void onRenderHeadInitContribution(final Response 
response)
        {
-               return false;
        }
 }

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractHeaderContributor.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractHeaderContributor.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractHeaderContributor.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/AbstractHeaderContributor.java
 Sun Nov 19 15:13:03 2006
@@ -16,11 +16,8 @@
  */
 package wicket.behavior;
 
-import java.util.HashSet;
-import java.util.Set;
-
-import wicket.Response;
 import wicket.markup.html.IHeaderContributor;
+import wicket.markup.html.IHeaderResponse;
 
 /**
  * Behaviour that delegates header contribution to a number of other
@@ -34,12 +31,6 @@
                        IHeaderContributor
 {
        /**
-        * thread local for the entries that were processed during the current
-        * request.
-        */
-       private static final ThreadLocal processedEntries = new ThreadLocal();
-
-       /**
         * Construct.
         */
        public AbstractHeaderContributor()
@@ -56,7 +47,7 @@
        /**
         * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.Response)
         */
-       public final void renderHead(final Response response)
+       public final void renderHead(final IHeaderResponse response)
        {
                IHeaderContributor[] contributors = getHeaderContributors();
                // do nothing if we don't need to
@@ -65,35 +56,14 @@
                        return;
                }
 
-               // get the processed entries for this request
-               Set entries = (Set)processedEntries.get();
-
-               int len = contributors.length;
-               // were any contributors set?
-               if (entries == null)
-               {
-                       entries = new HashSet(len);
-                       processedEntries.set(entries);
-               }
-
-               for (int i = 0; i < len; i++)
+               for (int i = 0; i < contributors.length; i++)
                {
-                       if (!entries.contains(contributors[i]))
+                       if (response.wasRendered(contributors[i]) == false) 
                        {
-                               // not yet printed for this request: print it
                                contributors[i].renderHead(response);
-                               entries.add(contributors[i]);
+                               response.markRendered(contributors[i]);
                        }
-                       // else the reference was already printed out: ignore it
                }
        }
 
-       /**
-        * @see wicket.behavior.AbstractBehavior#cleanup()
-        */
-       public final void cleanup()
-       {
-               // clean up thread
-               processedEntries.set(null);
-       }
 }

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/HeaderContributor.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/HeaderContributor.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/HeaderContributor.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/HeaderContributor.java
 Sun Nov 19 15:13:03 2006
@@ -26,6 +26,7 @@
 import wicket.ResourceReference;
 import wicket.Response;
 import wicket.markup.html.IHeaderContributor;
+import wicket.markup.html.IHeaderResponse;
 import wicket.markup.html.PackageResource;
 import wicket.model.AbstractReadOnlyModel;
 import wicket.protocol.http.WebRequestCycle;
@@ -283,8 +284,9 @@
                /**
                 * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.Response)
                 */
-               public void renderHead(Response response)
+               public void renderHead(IHeaderResponse headerResponse)
                {
+                       Response response = headerResponse.getResponse();
                        final CharSequence url = 
RequestCycle.get().urlFor(getResourceReference());
                        response.write("<link rel=\"stylesheet\" 
type=\"text/css\" href=\"");
                        response.write(url);
@@ -381,10 +383,10 @@
                /**
                 * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.Response)
                 */
-               public void renderHead(Response response)
+               public void renderHead(IHeaderResponse response)
                {
                        final CharSequence url = 
RequestCycle.get().urlFor(getResourceReference());
-                       JavascriptUtils.writeJavascriptUrl(response, url);
+                       
JavascriptUtils.writeJavascriptUrl(response.getResponse(), url);
                }
        }
 

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/StringHeaderContributor.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/StringHeaderContributor.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/StringHeaderContributor.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/behavior/StringHeaderContributor.java
 Sun Nov 19 15:13:03 2006
@@ -17,8 +17,8 @@
 package wicket.behavior;
 
 import wicket.Component;
-import wicket.Response;
 import wicket.markup.html.IHeaderContributor;
+import wicket.markup.html.IHeaderResponse;
 import wicket.model.IModel;
 import wicket.model.Model;
 import wicket.util.lang.Objects;
@@ -85,12 +85,12 @@
                /**
                 * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.Response)
                 */
-               public void renderHead(Response response)
+               public void renderHead(IHeaderResponse response)
                {
                        Object object = contribution.getObject(null);
                        if (object != null)
                        {
-                               response.println(object.toString());
+                               
response.getResponse().println(object.toString());
                        }
                }
 

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderContributor.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderContributor.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderContributor.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderContributor.java
 Sun Nov 19 15:13:03 2006
@@ -18,8 +18,6 @@
 
 import java.io.Serializable;
 
-import wicket.Response;
-
 /**
  * An interface to be implemented by components which are able to render the
  * header section associated with the markup. Default implementations are with
@@ -32,12 +30,9 @@
        /**
         * Render to the web response whatever the component wants to 
contribute to
         * the head section.
-        * <p>
-        * Note: This method is kind of dangerous as users are able to write to 
the
-        * output whatever they like.
         * 
         * @param response
         *            Response object
         */
-       void renderHead(final Response response);
+       void renderHead(final IHeaderResponse response);
 }

Added: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderResponse.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderResponse.java?view=auto&rev=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderResponse.java
 (added)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/IHeaderResponse.java
 Sun Nov 19 15:13:03 2006
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package wicket.markup.html;
+
+import java.io.Serializable;
+
+import wicket.ResourceReference;
+import wicket.Response;
+
+/**
+ * Interface that is used to render header elements (usually javascript and CSS
+ * references).
+ * 
+ * Implementation of this interface is responsible for filtering duplicate
+ * contributions (so that for example the same javascript is not loaded twice)
+ * during the same request.
+ * 
+ * @author Matej Knopp
+ */
+public interface IHeaderResponse extends Serializable
+{
+       /**
+        * Writes a javascript reference, if the specified reference hasn't been
+        * rendered yet.
+        * 
+        * @param reference
+        *            resource reference pointing to the javascript resource
+        */
+       public void renderJavascriptReference(ResourceReference reference);
+
+       /**
+        * Renders javascript code to the response, if the javascript has not
+        * already been rendered.
+        * 
+        * the necessary surrounding <code>script</code> tags will be added to 
the
+        * output.
+        * 
+        * @param javascript
+        *            javacript content to be rendered.
+        * 
+        * @param id
+        *            unique id for the javascript element. This can be null,
+        *            however in that case the ajax header contribution can't 
detect
+        *            duplicate script fragments.
+        */
+       public void renderJavascript(CharSequence javascript, String id);
+
+       /**
+        * Writes a CSS reference, if the specified reference hasn't been 
rendered
+        * yet.
+        * 
+        * @param reference
+        *            resource reference pointing to the CSS resource
+        */
+       public void renderCSSReference(ResourceReference reference);
+
+       /**
+        * Renders an arbitrary string to the header. The string is only 
rendered if
+        * the same string hasn't been rendered before.
+        * <p>
+        * Note: This method is kind of dangerous as users are able to write to 
the
+        * output whatever they like.
+        * 
+        * @param string
+        *            string to be rendered to head
+        */
+       public void renderString(CharSequence string);
+
+       /**
+        * Marks the given object as rendered. The object can be anything 
(string,
+        * resource reference, etc...). The purpose of this function is to allow
+        * user to manually keep track of rendered items. This can be useful for
+        * items that are expensive to generate (like interpolated text).
+        * 
+        * @param object
+        *            object to be marked as rendered.
+        */
+       public void markRendered(Object object);
+
+       /**
+        * Returns whether the given object has been marked as rendered.
+        * <ul>
+        * <li>Methods <code>renderJavascriptReference</code> and
+        * <code>renderCSSReference</code> mark the specified
+        * [EMAIL PROTECTED] ResourceReference} as rendered.
+        * <li>Method <code>renderJavascript</code> marks List of two elements
+        * (first is javascript body CharSequence and second is id) as rendered.
+        * <li>Method <code>renderString</code> marks the whole string as
+        * rendered.
+        * <li>Method <code>markRendered</code> can be used to mark an arbitrary
+        * object as rendered
+        * </ul>
+        * 
+        * @param object
+        *            Object that is queried to be rendered
+        * @return Whether the object has been marked as rendered during the 
request
+        */
+       public boolean wasRendered(Object object);
+
+       /**
+        * Returns the response that can be used to write arbitrary text to the 
head
+        * section.
+        * <p>
+        * Note: This method is kind of dangerous as users are able to write to 
the
+        * output whatever they like.
+        * 
+        * @return Reponse
+        */
+       public Response getResponse();
+}

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/WebPage.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/WebPage.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/WebPage.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/WebPage.java
 Sun Nov 19 15:13:03 2006
@@ -335,8 +335,9 @@
                /**
                 * @see 
wicket.markup.html.IHeaderContributor#renderHead(wicket.Response)
                 */
-               public final void renderHead(final Response response)
+               public final void renderHead(final IHeaderResponse headResponse)
                {
+                       Response response = headResponse.getResponse();
                        final WebRequestCycle cycle = 
(WebRequestCycle)getRequestCycle();
                        final IRequestTarget target = cycle.getRequestTarget();
 

Added: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java?view=auto&rev=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java
 (added)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java
 Sun Nov 19 15:13:03 2006
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package wicket.markup.html.internal;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import wicket.RequestCycle;
+import wicket.ResourceReference;
+import wicket.Response;
+import wicket.markup.html.IHeaderResponse;
+import wicket.util.string.JavascriptUtils;
+
+/**
+ * Default implementation of the [EMAIL PROTECTED] IHeaderResponse} interface.
+ * 
+ * @author Matej Knopp
+ */
+public class HeaderResponse implements IHeaderResponse
+{
+       private static final long serialVersionUID = 1L;
+
+       private Response response;
+
+       private Set rendered = new HashSet();
+
+       /**
+        * Creates a new header response instance.
+        * 
+        * @param response
+        *            response used to write the head elements
+        */
+       public HeaderResponse(Response response)
+       {
+               this.response = response;
+       }
+
+       /**
+        * @see 
wicket.markup.html.IHeaderResponse#markRendered(java.lang.Object)
+        */
+       public final void markRendered(Object object)
+       {
+               rendered.add(object);
+       }
+
+       /**
+        * @see 
wicket.markup.html.IHeaderResponse#renderCSSReference(wicket.markup.html.ResourceReference)
+        */
+       public final void renderCSSReference(ResourceReference reference)
+       {
+               if (wasRendered(reference) == false)
+               {
+                       final CharSequence url = 
RequestCycle.get().urlFor(reference);
+                       response.write("<link rel=\"stylesheet\" 
type=\"text/css\" href=\"");
+                       response.write(url);
+                       response.println("\"></link>");
+                       markRendered(reference);
+               }
+       }
+
+       /**
+        * @see 
wicket.markup.html.IHeaderResponse#renderJavascriptReference(wicket.markup.html.ResourceReference)
+        */
+       public final void renderJavascriptReference(ResourceReference reference)
+       {
+               if (wasRendered(reference) == false)
+               {
+                       JavascriptUtils.writeJavascriptUrl(getResponse(), 
RequestCycle.get().urlFor(reference));
+                       markRendered(reference);
+               }
+       }
+
+       /**
+        * @see 
wicket.markup.html.IHeaderResponse#renderJavascript(java.lang.CharSequence, 
java.lang.String)
+        */
+       public void renderJavascript(CharSequence javascript, String id)
+       {
+               List token = Arrays.asList(new Object[] { javascript, id });
+               if (wasRendered(token) == false) 
+               {
+                       JavascriptUtils.writeJavascript(getResponse(), 
javascript, id);
+                       markRendered(token);
+               }               
+       }
+
+       /**
+        * @see 
wicket.markup.html.IHeaderResponse#renderString(java.lang.CharSequence)
+        */
+       public final void renderString(CharSequence string)
+       {
+               if (wasRendered(string) == false)
+               {
+                       getResponse().write(string);
+                       markRendered(string);
+               }
+       }
+
+       /**
+        * @see wicket.markup.html.IHeaderResponse#wasRendered(java.lang.Object)
+        */
+       public final boolean wasRendered(Object object)
+       {
+               return rendered.contains(object);
+       }
+
+       /**
+        * @see wicket.markup.html.IHeaderResponse#getResponse()
+        */
+       public final Response getResponse()
+       {
+               return response;
+       }
+}

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java
 Sun Nov 19 15:13:03 2006
@@ -27,6 +27,7 @@
 import wicket.WicketRuntimeException;
 import wicket.markup.ComponentTag;
 import wicket.markup.MarkupStream;
+import wicket.markup.html.IHeaderResponse;
 import wicket.markup.html.WebMarkupContainer;
 import wicket.markup.html.WebPage;
 import wicket.markup.html.border.Border;
@@ -78,6 +79,10 @@
         * scope attribute.
         */
        private Map renderedComponentsPerScope;
+       /**
+        * Header response that is responsible for filtering duplicate 
contributions.
+        */
+       private IHeaderResponse headerResponse = null;  
 
        /**
         * Construct
@@ -120,7 +125,7 @@
                {
                        final StringResponse response = new StringResponse();
                        this.getRequestCycle().setResponse(response);
-
+                       
                        // In any case, first render the header section 
directly associated
                        // with the markup
                        super.onComponentTagBody(markupStream, openTag);
@@ -144,7 +149,7 @@
                        else
                        {
                                throw new WicketRuntimeException(
-                                               "Programming error: 'parent' 
should be a Page or a Border implementing IHeaderRenderer");
+                                               "Programming error: 'parent' 
should be a Page or a Border.");
                        }
 
                        // Automatically add <head> if necessary
@@ -182,7 +187,7 @@
                                webResponse.write("<head>");
                                webResponse.write(output);
                                webResponse.write("</head>");
-                       }
+                       }                                               
                }
                finally
                {
@@ -281,5 +286,20 @@
                super.onDetach();
 
                this.renderedComponentsPerScope = null;
+               this.headerResponse = null;
+       }
+       
+       /**
+        * Returns the header response. 
+        * 
+        * @return header response
+        */
+       public IHeaderResponse getHeaderResponse() {
+               if (this.headerResponse == null)
+               {
+                       headerResponse = new HeaderResponse(getResponse());
+               }
+               return headerResponse;
        }
+       
 }

Modified: 
incubator/wicket/branches/wicket-1.x/wicket/src/test/java/wicket/behavior/AjaxHandlerBodyOnLoadPage.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/test/java/wicket/behavior/AjaxHandlerBodyOnLoadPage.java?view=diff&rev=476971&r1=476970&r2=476971
==============================================================================
--- 
incubator/wicket/branches/wicket-1.x/wicket/src/test/java/wicket/behavior/AjaxHandlerBodyOnLoadPage.java
 (original)
+++ 
incubator/wicket/branches/wicket-1.x/wicket/src/test/java/wicket/behavior/AjaxHandlerBodyOnLoadPage.java
 Sun Nov 19 15:13:03 2006
@@ -17,7 +17,7 @@
 package wicket.behavior;
 
 import wicket.MarkupContainer;
-import wicket.Response;
+import wicket.markup.html.IHeaderResponse;
 import wicket.markup.html.WebMarkupContainer;
 import wicket.markup.html.WebPage;
 
@@ -43,15 +43,14 @@
                {
                        private static final long serialVersionUID = 1L;
 
-                       protected String getImplementationId()
+                       public void renderHead(IHeaderResponse response)
                        {
-                               return "test";
-                       }
-
-                       protected void onRenderHeadInitContribution(Response 
response)
-                       {
-                               super.onRenderHeadInitContribution(response);
-                               
getBodyContainer().addOnLoadModifier("myFunction();", null);
+                               super.renderHead(response);
+                               if (response.wasRendered("test") == false) 
+                               {                               
+                                       
getBodyContainer().addOnLoadModifier("myFunction();", null);
+                                       response.markRendered("test");
+                               }
                        }
 
                        public void onRequest()


Reply via email to