WICKET-6498 always add event listener regardless of readyState

for Ajax requests PartialPageUpdate will pack all OnDomReady and OnLoad items into an <evaluate> block anyways
diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java b/wicket-core/src/main/java/org/apache/wicket/Application.java
index 356c8b9..9415afa 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -41,6 +41,7 @@
 import org.apache.wicket.event.IEventSink;
 import org.apache.wicket.javascript.DefaultJavaScriptCompressor;
 import org.apache.wicket.markup.MarkupFactory;
+import org.apache.wicket.markup.head.HeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.ResourceAggregator;
 import org.apache.wicket.markup.html.IHeaderContributor;
@@ -1612,9 +1613,13 @@
 	/**
 	 * Sets an {@link IHeaderResponseDecorator} that you want your application to use to decorate
 	 * header responses.
+	 * <p>
+	 * Calling this method replaces the default decorator, which utilizes a {@link ResourceAggregator}:
+	 * The given implementation should make sure, that it too wraps responses in a {@link ResourceAggregator},
+	 * otherwise no dependencies for {@link HeaderItem}s will be resolved.   
 	 * 
 	 * @param headerResponseDecorator
-	 *            your custom decorator
+	 *            your custom decorator, must not be null
 	 */
 	public final Application setHeaderResponseDecorator(final IHeaderResponseDecorator headerResponseDecorator)
 	{
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/JavaScriptDeferHeaderResponse.java b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/JavaScriptDeferHeaderResponse.java
index 15dd49e..300f960 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/JavaScriptDeferHeaderResponse.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/JavaScriptDeferHeaderResponse.java
@@ -22,19 +22,30 @@
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.IWrappedHeaderItem;
 import org.apache.wicket.markup.head.JavaScriptContentHeaderItem;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.OnLoadHeaderItem;
 import org.apache.wicket.markup.html.DecoratingHeaderResponse;
+import org.apache.wicket.page.PartialPageUpdate;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.util.string.Strings;
 
 /**
  * A header response that defers all {@link AbstractJavaScriptReferenceHeaderItem}s.
+ * <p>
+ * To prevent any error because of possible dependencies to referenced JavaScript files
+ * *all* {@link JavaScriptHeaderItem}s are replaced with suitable implementations that
+ * delay any execution until {@link AbstractJavaScriptReferenceHeaderItem}s have been loaded.
  * 
  * @author svenmeier
 + */
 public class JavaScriptDeferHeaderResponse extends DecoratingHeaderResponse
 {
+	/**
+	 * Decorate the given response.
+	 * 
+	 * @param response
+	 */
 	public JavaScriptDeferHeaderResponse(IHeaderResponse response)
 	{
 		super(response);
@@ -49,17 +60,23 @@
 
 		if (item instanceof AbstractJavaScriptReferenceHeaderItem) {
 			((AbstractJavaScriptReferenceHeaderItem)item).setDefer(true);
+		} else if (item instanceof JavaScriptContentHeaderItem) {
+			item = new NativeOnDomContentLoadedHeaderItem(((JavaScriptContentHeaderItem)item).getJavaScript());
 		} else if (item instanceof OnDomReadyHeaderItem) {
 			item = new NativeOnDomContentLoadedHeaderItem(((OnDomReadyHeaderItem)item).getJavaScript());
 		} else if (item instanceof OnLoadHeaderItem) {
 			item = new NativeOnLoadHeaderItem(((OnLoadHeaderItem)item).getJavaScript());
-		} else if (item instanceof JavaScriptContentHeaderItem) {
-			item = new NativeOnDomContentLoadedHeaderItem(((JavaScriptContentHeaderItem)item).getJavaScript());
 		}
 		
 		super.render(item);
 	}
 
+	/**
+	 * A specialization that uses native "DOMContentLoaded" events without dependency to external JavaScript.
+	 * <p>
+	 * For Ajax requests we utilize the fact, that {@link PartialPageUpdate} renders {@link #getJavaScript()} only,
+	 * thus executing the JavaScript directly without any event registration.
+	 */
 	private class NativeOnDomContentLoadedHeaderItem extends OnDomReadyHeaderItem
 	{
 		/**
@@ -72,18 +89,26 @@
 			super(javaScript);
 		}
 
+		/**
+		 * Overriden to use native {@code addEventListener('DOMContentLoaded')} instead.
+		 */
 		@Override
 		public void render(Response response)
 		{
 			CharSequence js = getJavaScript();
 			if (Strings.isEmpty(js) == false)
 			{
-				JavaScriptUtils.writeJavaScript(response,
-					"(function(){ var f = function() {" + js + ";};\nif ('loading' !== document.readyState) f(); else document.addEventListener('DOMContentLoaded', f); })();");
+				JavaScriptUtils.writeJavaScript(response, "document.addEventListener('DOMContentLoaded', function() { " + js + "; });");
 			}
 		}
 	}
 	
+	/**
+	 * A specialization that uses native "load" events without dependency to external JavaScript 
+	 * <p>
+	 * For Ajax requests we utilize the fact, that {@link PartialPageUpdate} renders {@link #getJavaScript()} only,
+	 * thus executing the JavaScript directly without any event registration.
+	 */
 	private class NativeOnLoadHeaderItem extends OnLoadHeaderItem
 	{
 
@@ -97,15 +122,17 @@
 			super(javaScript);
 		}
 
+		/**
+		 * Overriden to use native {@code addEventListener('load')} instead.
+		 */
 		@Override
 		public void render(Response response)
 		{
 			CharSequence js = getJavaScript();
 			if (Strings.isEmpty(js) == false)
 			{
-				JavaScriptUtils.writeJavaScript(response,
-					"(function(){ var f = function() {" + js + ";};\nif ('complete' === document.readyState) f(); else window.addEventListener('load', f); })();");
+				JavaScriptUtils.writeJavaScript(response, "window.addEventListener('load', function() { " + js + "; });");
 			}
 		}
 	}	
-} 
\ No newline at end of file
+} 
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/IHeaderResponseDecorator.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/IHeaderResponseDecorator.java
index 3e502b9..00c9b17 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/IHeaderResponseDecorator.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/IHeaderResponseDecorator.java
@@ -19,10 +19,10 @@
 import org.apache.wicket.markup.head.IHeaderResponse;
 
 /**
- * Setting an IHeaderResponseDecorator on an application allows you to wrap any IHeaderResponse
- * created by Wicket in a separate implementation that incrementally adds functionality to the
- * IHeaderResponse that is used by all IHeaderContributor components or behaviors.
- * 
+ * Setting an IHeaderResponseDecorator on an application allows you to wrap any {@link IHeaderResponse}
+ * created by Wicket in a separate implementation that adds functionality to it when used by all
+ * {@link IHeaderContributor} components or behaviors.
+ * <p>
  * Everywhere that Wicket creates an instance of IHeaderResponse, it will call to your application
  * and give it the opportunity to decorate that IHeaderResponse before using it.
  * 
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPage.html b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPage.html
new file mode 100644
index 0000000..ee4a485
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPage.html
@@ -0,0 +1,4 @@
+<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
+    <body>
+    </body>
+</html>
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPage.java b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPage.java
new file mode 100644
index 0000000..355328b
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPage.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.wicket.markup.head.filter;
+
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.WebPage;
+
+/**
+ * @author svenmeier
+ */
+public class DeferredPage extends WebPage
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param parameters
+	 */
+	public DeferredPage()
+	{
+		add(new AjaxEventBehavior("click") {
+			@Override
+			protected void onEvent(AjaxRequestTarget target)
+			{
+			}
+		});
+	}
+}
\ No newline at end of file
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPageExpected.html b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPageExpected.html
new file mode 100644
index 0000000..894bad2
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/DeferredPageExpected.html
@@ -0,0 +1,25 @@
+<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
+    <head><script type="text/javascript" defer="defer" src="../resource/org.apache.wicket.resource.JQueryResourceReference/jquery/jquery-2.2.4.js"></script>
+<script type="text/javascript" defer="defer" src="../resource/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/res/js/wicket-ajax-jquery.js"></script>
+<script type="text/javascript" defer="defer" src="../resource/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/res/js/wicket-ajax-jquery-debug.js"></script>
+<script type="text/javascript" >
+/*<![CDATA[*/
+document.addEventListener('DOMContentLoaded', function() { Wicket.Ajax.DebugWindow.enabled=true;; });
+/*]]>*/
+</script>
+<script type="text/javascript" >
+/*<![CDATA[*/
+document.addEventListener('DOMContentLoaded', function() { Wicket.Ajax.baseUrl="wicket/bookmarkable/org.apache.wicket.markup.head.filter.DeferredPage?0";; });
+/*]]>*/
+</script>
+<script type="text/javascript" >
+/*<![CDATA[*/
+document.addEventListener('DOMContentLoaded', function() { 
+Wicket.Ajax.ajax({"u":"./org.apache.wicket.markup.head.filter.DeferredPage?0-1.0-","e":"click"});;
+Wicket.Event.publish(Wicket.Event.Topic.AJAX_HANDLERS_BOUND);
+; });
+/*]]>*/
+</script>
+</head><body>
+    </body>
+</html>
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
index d8a901a..99665a7 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/FilteringHeaderResponseTest.java
@@ -75,4 +75,22 @@
 		CharSequence realContent = headerResponse.getContent(filterName);
 		assertEquals(headerContent, realContent.toString());
 	}
-}
+
+	/**
+	 * WICKET-6498 all JavaScript resources have an "defer" attribute, all other JavaScript is
+	 * inside a {@code document.addEventListener('DOMContentLoaded', function() {}; } hook.
+	 */
+	@Test
+	public void deferred() throws Exception
+	{
+		tester.getApplication().setHeaderResponseDecorator(new IHeaderResponseDecorator()
+		{
+			@Override
+			public IHeaderResponse decorate(IHeaderResponse response)
+			{
+				return new ResourceAggregator(new JavaScriptDeferHeaderResponse(response));
+			}
+		});
+		executeTest(DeferredPage.class, "DeferredPageExpected.html");
+	}
+}
\ No newline at end of file