This is an automated email from the ASF dual-hosted git repository.

svenmeier pushed a commit to branch WICKET-6703-replace-eval-with-domEval
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit cb4a7d3bf43338db134d9605060397a84cffe218
Author: Sven Meier <svenme...@apache.org>
AuthorDate: Mon Oct 28 10:15:16 2019 +0100

    WICKET-6703 Ajax using header-contribution for evaluations too
---
 .../org/apache/wicket/ajax/AjaxRequestHandler.java |   6 +-
 .../wicket/ajax/res/js/wicket-ajax-jquery.js       | 165 +++++++--------------
 .../markup/head/filter/CspNonceHeaderResponse.java |   2 +-
 .../org/apache/wicket/page/PartialPageUpdate.java  |  67 ++++++---
 .../apache/wicket/page/XmlPartialPageUpdate.java   |  54 +------
 .../filter/AjaxServerAndClientTimeFilter.java      |  59 ++++----
 .../apache/wicket/TestDetachPageAjaxResult.html    |   7 +-
 .../AjaxHeaderContributionPage2_ajax_expected.html |  14 +-
 .../AjaxHeaderContributionPage_ajax_expected.html  |  14 +-
 .../ajax/DomReadyOrderPage_ajax_expected.html      |   7 +-
 .../SimpleTestPageExpectedResult-1.html            |   7 +-
 .../markup/head/filter/CspNoncePageExpected.html   |   2 +-
 12 files changed, 181 insertions(+), 223 deletions(-)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java 
b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
index 1dad048..230aead 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
@@ -153,15 +153,13 @@ public class AjaxRequestHandler implements 
AjaxRequestTarget
                                        final Map<String, Component> components 
= Collections
                                                
.unmodifiableMap(markupIdToComponent);
 
-                                       // create response that will be used by 
listeners to append
-                                       // javascript
+                                       // create response that will be used by 
listeners to append javascript
                                        final 
AjaxRequestTarget.IJavaScriptResponse jsresponse = new 
AjaxRequestTarget.IJavaScriptResponse()
                                        {
                                                @Override
                                                public void 
addJavaScript(String script)
                                                {
-                                                       
writeNormalEvaluations(response,
-                                                               
Collections.<CharSequence> singleton(script));
+                                                       
writeEvaluations(response, Collections.<CharSequence> singleton(script));
                                                }
                                        };
 
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js 
b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
index 018fc4b..a960c55 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
+++ 
b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
@@ -850,35 +850,23 @@
                                }
 
                                var steps = context.steps;
-
-                               // go through the ajax response and execute all 
priority-invocations first
-                               for (var i = 0; i < root.childNodes.length; 
++i) {
-                                       var childNode = root.childNodes[i];
-                                       if (childNode.tagName === 
"header-contribution") {
-                                               
this.processHeaderContribution(context, childNode);
-                                       } else if (childNode.tagName === 
"priority-evaluate") {
-                                               this.processEvaluation(context, 
childNode);
-                                       }
-                               }
-
-                               // go through the ajax response and for every 
action (component, js evaluation, header contribution)
-                               // ad the proper closure to steps
                                var stepIndexOfLastReplacedComponent = -1;
-                               for (var c = 0; c < root.childNodes.length; 
++c) {
-                                       var node = root.childNodes[c];
 
-                                       if (node.tagName === "component") {
+                               // go through the ajax response and execute all 
items
+                               for (var i = 0; i < root.childNodes.length; 
++i) {
+                                       var node = root.childNodes[i];
+                                       
+                                       if (node.tagName === 
"header-contribution") {
+                                               
this.processHeaderContribution(context, node);
+                                       } else if (node.tagName === 
"component") {
                                                if 
(stepIndexOfLastReplacedComponent === -1) {
                                                        
this.processFocusedComponentMark(context);
                                                }
                                                
stepIndexOfLastReplacedComponent = steps.length;
                                                this.processComponent(context, 
node);
-                                       } else if (node.tagName === "evaluate") 
{
-                                               this.processEvaluation(context, 
node);
                                        } else if (node.tagName === "redirect") 
{
                                                this.processRedirect(context, 
node);
                                        }
-
                                }
                                if (stepIndexOfLastReplacedComponent !== -1) {
                                        
this.processFocusedComponentReplaceCheck(steps, 
stepIndexOfLastReplacedComponent);
@@ -952,63 +940,6 @@
                        });
                },
 
-               /**
-                * Adds a closure that evaluates javascript code.
-                * @param context {Object} - the object that brings the 
executer's steps and the attributes
-                * @param node {XmlElement} - the <[priority-]evaluate> element 
with the script to evaluate
-                */
-               processEvaluation: function (context, node) {
-
-                       // get the javascript body
-                       var text = Wicket.DOM.text(node);
-
-                       // aliases to improve performance
-                       var steps = context.steps;
-                       var log = Wicket.Log;
-
-                       var evaluate = function (script) {
-                               return function(notify) {
-                                       
-                                       var suspension = {
-                                               suspended: 0,
-                                               
-                                               suspend: function() {
-                                                       suspension.suspended++;
-                                               },
-                                               
-                                               release: function() {
-                                                       suspension.suspended--;
-                                                       if 
(suspension.suspended == 0) {
-                                                               notify();
-                                                       }
-                                               }
-                                       };
-                                       
-                                       try {
-                                               Wicket.Ajax._currentSuspension 
= suspension;
-                                               
-                                               // do the evaluation in global 
scope
-                                               window.eval(script);
-                                       } catch (exception) {
-                                               
log.error("Ajax.Call.processEvaluation: Exception evaluating javascript: %s", 
text, exception);
-                                       } finally {
-                                               Wicket.Ajax.currentSuspension = 
undefined;
-                                       }
-                                       
-                                       // continue to next step
-                                       if (suspension.suspended === 0) {
-                                               // execution finished without 
suspension, just continue to next step
-                                               return FunctionsExecuter.DONE;
-                                       } else {
-                                               // suspended, signal 
asynchronous execution of next step
-                                               return FunctionsExecuter.ASYNC;
-                                       }
-                               };
-                       };
-                       
-                       steps.push(evaluate(text));
-               },
-
                // Adds a closure that processes a header contribution
                processHeaderContribution: function (context, node) {
                        var c = Wicket.Head.Contributor;
@@ -1937,20 +1868,17 @@
                                                        }
                                                }
 
+                                               // convert the XML node to DOM 
node
+                                               var scriptDomNode = 
document.createElement("script");
+                                               var attrs = node.attributes;
+                                               for (var a = 0; a < 
attrs.length; a++) {
+                                                       var attr = attrs[a];
+                                                       
scriptDomNode[attr.name] = attr.value;
+                                               }
+                                               
                                                // determine whether it is 
external javascript (has src attribute set)
                                                var src = 
node.getAttribute("src");
-
                                                if (src !== null && src !== "") 
{
-
-                                                       // convert the XML node 
to DOM node
-                                                       var scriptDomNode = 
document.createElement("script");
-
-                                                       var attrs = 
node.attributes;
-                                                       for (var a = 0; a < 
attrs.length; a++) {
-                                                               var attr = 
attrs[a];
-                                                               
scriptDomNode[attr.name] = attr.value;
-                                                       }
-
                                                        var onScriptReady = 
function () {
                                                                notify();
                                                        };
@@ -1973,29 +1901,47 @@
 
                                                        return 
FunctionsExecuter.ASYNC;
                                                } else {
-                                                       // serialize the 
element content to string
-                                                       var text = 
Wicket.DOM.serializeNodeChildren(node);
-                                                       // get rid of prefix 
and suffix, they are not eval-d correctly
-                                                       text = 
text.replace(/^\n\/\*<!\[CDATA\[\*\/\n/, "");
-                                                       text = 
text.replace(/\n\/\*\]\]>\*\/\n$/, "");
-
-                                                       var id = 
node.getAttribute("id");
-                                                       var type = 
node.getAttribute("type");
-
-                                                       if (typeof(id) === 
"string" && id.length > 0) {
-                                                               // add 
javascript to document head
-                                                               
Wicket.Head.addJavascript(text, id, "", type);
-                                                       } else {
-                                                               try {
-                                                                       // do 
the evaluation in global scope
-                                                                       
window.eval(text);
-                                                               } catch (e) {
-                                                                       
Wicket.Log.error("Wicket.Head.Contributor.processScript: %s", text, e);
+                                                       var suspension = {
+                                                               suspended: 0,
+                                                                               
+                                                               suspend: 
function() {
+                                                                       
suspension.suspended++;
+                                                               },
+                                                                               
+                                                               release: 
function() {
+                                                                       
suspension.suspended--;
+                                                                       if 
(suspension.suspended == 0) {
+                                                                               
notify();
+                                                                       }
                                                                }
+                                                       };
+
+                                                       try {
+                                                               
Wicket.Ajax._currentSuspension = suspension;
+
+                                                               // serialize 
the element content to string
+                                                               var text = 
Wicket.DOM.serializeNodeChildren(node);
+                                                               // get rid of 
prefix and suffix, they are not eval-d correctly
+                                                               text = 
text.replace(/^\n\/\*<!\[CDATA\[\*\/\n/, "");
+                                                               text = 
text.replace(/\n\/\*\]\]>\*\/\n$/, "");
+                                                               
scriptDomNode.innerHTML = text;
+
+                                                               var id = 
node.getAttribute("id");
+                                                               
Wicket.Head.addElement(scriptDomNode, typeof(id) !== "string" || id.length == 
0);
+                                                       } catch (exception) {
+                                                               
log.error("Ajax.Call.processEvaluation: Exception evaluating javascript: %s", 
text, exception);
+                                                       } finally {
+                                                               
Wicket.Ajax.currentSuspension = undefined;
                                                        }
 
                                                        // continue to next step
-                                                       return 
FunctionsExecuter.DONE;
+                                                       if 
(suspension.suspended === 0) {
+                                                               // execution 
finished without suspension, just continue to next step
+                                                               return 
FunctionsExecuter.DONE;
+                                                       } else {
+                                                               // suspended, 
signal asynchronous execution of next step
+                                                               return 
FunctionsExecuter.ASYNC;
+                                                       }
                                                }
                                        });
                                },
@@ -2044,17 +1990,20 @@
                        },
 
                        // Adds the element to page head
-                       addElement: function (element) {
+                       addElement: function (element, remove) {
                                var headItems = document.querySelector('head 
meta[name="wicket.header.items"]');
                                if (headItems) {
                                        
headItems.parentNode.insertBefore(element, headItems);
                                } else {
                                        var head = 
document.querySelector("head");
-
                                        if (head) {
                                                head.appendChild(element);
                                        }
                                }
+
+                               if (remove) {
+                                       element.parentNode.removeChild(element);
+                               }
                        },
 
                        // Returns true, if the page head contains element that 
has attribute with
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
 
b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
index 6376518..ec72315 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/markup/head/filter/CspNonceHeaderResponse.java
@@ -88,6 +88,6 @@ public class CspNonceHeaderResponse extends 
DecoratingHeaderResponse
         */
        protected String getContentSecurityPolicy(String nonce)
        {
-               return String.format("script-src 'unsafe-eval' 'strict-dynamic' 
'nonce-%1$s'; style-src 'nonce-%1$s';", nonce);
+               return String.format("script-src 'strict-dynamic' 'nonce-%1$s'; 
style-src 'nonce-%1$s';", nonce);
        }
 }
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java 
b/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
index 2e026bd..efefafb 100644
--- a/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
+++ b/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
@@ -25,12 +25,16 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import javax.servlet.http.Cookie;
+
+import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.feedback.FeedbackDelay;
 import org.apache.wicket.markup.head.HeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.IWrappedHeaderItem;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
 import org.apache.wicket.markup.head.OnEventHeaderItem;
 import org.apache.wicket.markup.head.OnLoadHeaderItem;
@@ -45,6 +49,7 @@ import org.apache.wicket.request.IRequestCycle;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.http.WebResponse;
+import org.apache.wicket.response.StringResponse;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Generics;
 import org.apache.wicket.util.string.AppendingStringBuffer;
@@ -52,16 +57,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * A partial update of a page that collects components and header 
contributions to be written to the client in a specific
- * String-based format (XML, JSON, * ...).
+ * A partial update of a page that collects components and header 
contributions to be written to the
+ * client in a specific String-based format (XML, JSON, * ...).
  * <p>
  * The elements of such response are:
  * <ul>
- * <li>priority-evaluate - an item of the prepend JavaScripts</li>
  * <li>component - the markup of the updated component</li>
- * <li>evaluate - an item of the onDomReady and append JavaScripts</li>
- * <li>header-contribution - all HeaderItems which have been contributed in
- * components' and their behaviors' #renderHead(Component, 
IHeaderResponse)</li>
+ * <li>header-contribution - all HeaderItems which have been contributed in 
any{@link Component#renderHead(IHeaderResponse)},
+ * {@link Behavior#renderHead(Component, IHeaderResponse)} or JavaScript 
explicitly added via {@link #appendJavaScript(CharSequence)}
+ * or {@link #prependJavaScript(CharSequence)}</li>
  * </ul>
  */
 public abstract class PartialPageUpdate
@@ -155,21 +159,21 @@ public abstract class PartialPageUpdate
 
                        onBeforeRespond(response);
 
+                       // queue up prepend javascripts. unlike other steps 
these are executed out of order so that
+                       // components can contribute them from inside their 
onbeforerender methods.
+                       writeEvaluations(response, prependJavaScripts);
+
                        // process added components
                        writeComponents(response, encoding);
 
                        onAfterRespond(response);
 
-                       // queue up prepend javascripts. unlike other steps 
these are executed out of order so that
-                       // components can contribute them from inside their 
onbeforerender methods.
-                       writePriorityEvaluations(response, prependJavaScripts);
-
                        // execute the dom ready javascripts as first 
javascripts
                        // after component replacement
                        List<CharSequence> evaluationScripts = new 
ArrayList<>();
                        evaluationScripts.addAll(domReadyJavaScripts);
                        evaluationScripts.addAll(appendJavaScripts);
-                       writeNormalEvaluations(response, evaluationScripts);
+                       writeEvaluations(response, evaluationScripts);
 
                        writeFooter(response, encoding);
                } finally {
@@ -212,16 +216,33 @@ public abstract class PartialPageUpdate
         * @param js
         *      the JavaScript to evaluate
         */
-       protected abstract void writePriorityEvaluations(Response response, 
Collection<CharSequence> js);
+       protected void writeEvaluations(final Response response, 
Collection<CharSequence> scripts)
+       {
+               if (scripts.size() > 0)
+               {
+                       StringBuilder combinedScript = new StringBuilder(1024);
+                       for (CharSequence script : scripts)
+                       {
+                               
combinedScript.append("(function(){").append(script).append("})();");
+                       }
+
+                       StringResponse stringResponse = new StringResponse();
+                       IHeaderResponse headerResponse = 
Application.get().decorateHeaderResponse(new HeaderResponse()
+                       {
+                               @Override
+                               protected Response getRealResponse()
+                               {
+                                       return stringResponse;
+                               }
+                       });
+                       
+                       
headerResponse.render(JavaScriptHeaderItem.forScript(combinedScript, null));
+                       headerResponse.close();
+                       
+                       writeHeaderContribution(response, 
stringResponse.getBuffer());
+               }
+       }
 
-       /**
-        *
-        * @param response
-        *      the response to write to
-        * @param js
-        *      the JavaScript to evaluate
-        */
-       protected abstract void writeNormalEvaluations(Response response, 
Collection<CharSequence> js);
 
        /**
         * Processes components added to the target. This involves attaching 
components, rendering
@@ -281,7 +302,7 @@ public abstract class PartialPageUpdate
                        cycle.setResponse(oldResponse);
 
                        // write the XML tags and we're done
-                       writeHeaderContribution(response);
+                       writeHeaderContribution(response, 
headerBuffer.getContents());
                        headerRendering = false;
                }
        }
@@ -358,7 +379,7 @@ public abstract class PartialPageUpdate
         * @param response
         *      the response to write to
         */
-       protected abstract void writeHeaderContribution(Response response);
+       protected abstract void writeHeaderContribution(Response response, 
CharSequence contents);
 
        @Override
        public boolean equals(Object o)
@@ -575,7 +596,7 @@ public abstract class PartialPageUpdate
                        requestCycle.setResponse(oldResponse);
                }
 
-               writeHeaderContribution(response);
+               writeHeaderContribution(response, headerBuffer.getContents());
                headerRendering = false;
        }
 
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java 
b/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
index 0af4342..20c12d7 100644
--- a/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
+++ b/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
@@ -20,6 +20,7 @@ import java.util.Collection;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.Page;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.http.WebResponse;
@@ -102,9 +103,8 @@ public class XmlPartialPageUpdate extends PartialPageUpdate
        }
 
        @Override
-       protected void writeHeaderContribution(Response response)
+       protected void writeHeaderContribution(Response response, CharSequence 
contents)
        {
-               CharSequence contents = headerBuffer.getContents();
                if (Strings.isEmpty(contents) == false)
                {
                        response.write("<header-contribution>");
@@ -118,56 +118,6 @@ public class XmlPartialPageUpdate extends PartialPageUpdate
                }
        }
 
-       @Override
-       protected void writeNormalEvaluations(final Response response, final 
Collection<CharSequence> scripts)
-       {
-               writeEvaluations(response, "evaluate", scripts);
-
-       }
-
-       @Override
-       protected void writePriorityEvaluations(Response response, 
Collection<CharSequence> scripts)
-       {
-               writeEvaluations(response, "priority-evaluate", scripts);
-       }
-
-       private void writeEvaluations(final Response response, String 
elementName, Collection<CharSequence> scripts)
-       {
-               if (scripts.size() > 0)
-               {
-                       StringBuilder combinedScript = new StringBuilder(1024);
-                       for (CharSequence script : scripts)
-                       {
-                               
combinedScript.append("(function(){").append(script).append("})();");
-                       }
-                       writeEvaluation(elementName, response, combinedScript);
-               }
-       }
-
-       /**
-       * @param invocation
-       *            type of invocation tag, usually {@literal evaluate} or
-       *            {@literal priority-evaluate}
-       * @param response
-       * @param js
-       */
-       private void writeEvaluation(final String invocation, final Response 
response, final CharSequence js)
-       {
-               response.write("<");
-               response.write(invocation);
-               response.write(">");
-
-               response.write("<![CDATA[");
-               response.write(encode(js));
-               response.write("]]>");
-
-               response.write("</");
-               response.write(invocation);
-               response.write(">");
-
-               bodyBuffer.reset();
-       }
-
        protected CharSequence encode(CharSequence str)
        {
                return Strings.replaceAll(str, "]]>", "]]]]><![CDATA[>"); 
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/response/filter/AjaxServerAndClientTimeFilter.java
 
b/wicket-core/src/main/java/org/apache/wicket/response/filter/AjaxServerAndClientTimeFilter.java
index 618a39b..8db3b90 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/response/filter/AjaxServerAndClientTimeFilter.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/response/filter/AjaxServerAndClientTimeFilter.java
@@ -17,13 +17,12 @@
 package org.apache.wicket.response.filter;
 
 import java.util.HashMap;
-import java.util.Map;
 
 import org.apache.wicket.Application;
+import org.apache.wicket.core.util.string.JavaScriptUtils;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.util.string.AppendingStringBuffer;
-import org.apache.wicket.core.util.string.JavaScriptUtils;
-import org.apache.wicket.util.string.interpolator.MapVariableInterpolator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,32 +67,38 @@ public class AjaxServerAndClientTimeFilter implements 
IResponseFilter
                long timeTaken = System.currentTimeMillis() - 
RequestCycle.get().getStartTime();
                if (headIndex != -1 && bodyIndex != -1)
                {
-                       AppendingStringBuffer endScript = new 
AppendingStringBuffer(150);
-                       
endScript.append("\n").append(JavaScriptUtils.SCRIPT_OPEN_TAG);
-                       endScript.append("\nwindow.defaultStatus='");
-                       endScript.append(getStatusString(timeTaken, 
"ServerAndClientTimeFilter.statustext"));
-                       
endScript.append("';\n").append(JavaScriptUtils.SCRIPT_CLOSE_TAG).append("\n");
-                       responseBuffer.insert(bodyIndex - 1, endScript);
-                       responseBuffer.insert(headIndex + 6, "\n" + 
JavaScriptUtils.SCRIPT_OPEN_TAG +
-                               "\nvar clientTimeVariable = new 
Date().getTime();\n" +
-                               JavaScriptUtils.SCRIPT_CLOSE_TAG + "\n");
+                       responseBuffer.insert(bodyIndex, 
scriptTag("window.defaultStatus=" + getStatusString(timeTaken, 
"ServerAndClientTimeFilter.statustext") + ";"));
+                       responseBuffer.insert(headIndex + 6, 
scriptTag("clientTimeVariable = new Date().getTime();"));
                }
                else if (ajaxStart != -1 && ajaxEnd != -1)
                {
-                       AppendingStringBuffer startScript = new 
AppendingStringBuffer(250);
-                       
startScript.append("<evaluate><![CDATA[window.defaultStatus='");
-                       startScript.append(getStatusString(timeTaken,
-                               "ajax.ServerAndClientTimeFilter.statustext"));
-                       startScript.append("';]]></evaluate>");
-                       responseBuffer.insert(ajaxEnd, startScript.toString());
-                       responseBuffer.insert(ajaxStart + 15,
-                               "<priority-evaluate><![CDATA[clientTimeVariable 
= new Date().getTime();]]></priority-evaluate>");
+                       responseBuffer.insert(ajaxEnd, 
headerContribution("window.defaultStatus=" + getStatusString(timeTaken, 
"ajax.ServerAndClientTimeFilter.statustext") + ";"));
+                       responseBuffer.insert(ajaxStart + 15, 
headerContribution("clientTimeVariable = new Date().getTime();"));
                }
                log.info(timeTaken + "ms server time taken for request " +
                        RequestCycle.get().getRequest().getUrl() + " response 
size: " + responseBuffer.length());
                return responseBuffer;
        }
 
+       private String scriptTag(String script)
+       {
+               AppendingStringBuffer buffer = new AppendingStringBuffer(250);
+               buffer.append("\n");
+               buffer.append(JavaScriptUtils.SCRIPT_OPEN_TAG);
+               buffer.append(script);
+               buffer.append(JavaScriptUtils.SCRIPT_CLOSE_TAG).append("\n");
+               return buffer.toString();
+       }
+       
+       private String headerContribution(String script)
+       {
+               AppendingStringBuffer buffer = new AppendingStringBuffer(250);
+               buffer.append("<header-contribution><![CDATA[<head 
xmlns:wicket=\"http://wicket.apache.org\";>");
+               buffer.append(script);
+               buffer.append("</head>]]></header-contribution>");
+               return buffer.toString();
+       }
+
        /**
         * Returns a locale specific status message about the server and client 
time.
         * 
@@ -105,14 +110,14 @@ public class AjaxServerAndClientTimeFilter implements 
IResponseFilter
         */
        private String getStatusString(long timeTaken, String resourceKey)
        {
-               final String txt = Application.get()
+               final HashMap<String, String> map = new HashMap<String, 
String>(4);
+               map.put("servertime", ((double)timeTaken) / 1000 + "s");
+               map.put("clienttime", "' + (new Date().getTime() - 
clientTimeVariable)/1000 +  's");
+
+               return Application.get()
                        .getResourceSettings()
                        .getLocalizer()
-                       .getString(resourceKey, null,
-                               "Server parsetime: ${servertime}, Client 
parsetime: ${clienttime}");
-               final Map<String, String> map = new HashMap<String, String>(4);
-               map.put("clienttime", "' + (new Date().getTime() - 
clientTimeVariable)/1000 +  's");
-               map.put("servertime", ((double)timeTaken) / 1000 + "s");
-               return MapVariableInterpolator.interpolate(txt, map);
+                       .getString(resourceKey, null, Model.of(map),
+                               "'Server parsetime: ${servertime}, Client 
parsetime: ${clienttime}'");
        }
 }
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/TestDetachPageAjaxResult.html 
b/wicket-core/src/test/java/org/apache/wicket/TestDetachPageAjaxResult.html
index 973720e..ecda0eb 100644
--- a/wicket-core/src/test/java/org/apache/wicket/TestDetachPageAjaxResult.html
+++ b/wicket-core/src/test/java/org/apache/wicket/TestDetachPageAjaxResult.html
@@ -10,4 +10,9 @@ Wicket.Log.enabled=true;
 
Wicket.Ajax.baseUrl="wicket/bookmarkable/org.apache.wicket.TestDetachPage?0-1.0-comp";
 /*]]]]><![CDATA[>*/
 </script>
-</head>]]></header-contribution><evaluate><![CDATA[(function(){Wicket.Ajax.ajax({"u":"./org.apache.wicket.TestDetachPage?0-1.0-comp","c":"comp1","e":"click"});})();]]></evaluate></ajax-response>
\ No newline at end of file
+</head>]]></header-contribution><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){Wicket.Ajax.ajax({"u":"./org.apache.wicket.TestDetachPage?0-1.0-comp","c":"comp1","e":"click"});})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution></ajax-response>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2_ajax_expected.html
 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2_ajax_expected.html
index 7dbede2..08ef620 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2_ajax_expected.html
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage2_ajax_expected.html
@@ -1,4 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?><ajax-response><component id="test12" 
><![CDATA[<span wicket:id="test1" id="test12"><wicket:panel>
+<?xml version="1.0" 
encoding="UTF-8"?><ajax-response><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){prepend();})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution><component id="test12" ><![CDATA[<span 
wicket:id="test1" id="test12"><wicket:panel>
 test
 </wicket:panel></span>]]></component><component id="test23" ><![CDATA[<span 
wicket:id="test2" id="test23"><wicket:panel>
 test
@@ -18,4 +23,9 @@ test
 
 <link href="../../test2"/>
 <script type="text/javascript" src="../../javascripturlB"></script>
-</head>]]></header-contribution><priority-evaluate><![CDATA[(function(){prepend();})();]]></priority-evaluate><evaluate><![CDATA[(function(){domReady();})();(function(){domReadyB();})();(function(){append();})();(function(){onLoad();})();(function(){onLoadB();})();]]></evaluate></ajax-response>
\ No newline at end of file
+</head>]]></header-contribution><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){domReady();})();(function(){domReadyB();})();(function(){append();})();(function(){onLoad();})();(function(){onLoadB();})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution></ajax-response>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage_ajax_expected.html
 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage_ajax_expected.html
index ab1020a..dc3d8af 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage_ajax_expected.html
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxHeaderContributionPage_ajax_expected.html
@@ -1,4 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?><ajax-response><component id="test12" 
><![CDATA[<span wicket:id="test1" id="test12"><wicket:panel>
+<?xml version="1.0" 
encoding="UTF-8"?><ajax-response><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){prepend();})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution><component id="test12" ><![CDATA[<span 
wicket:id="test1" id="test12"><wicket:panel>
 test
 </wicket:panel></span>]]></component><component id="test23" ><![CDATA[<span 
wicket:id="test2" id="test23"><wicket:panel>
 test
@@ -9,4 +14,9 @@ test
 <script type="text/javascript" src="../../javascripturl"></script>
 <script type="text/javascript" 
src="../resource/org.apache.wicket.resource.JQueryResourceReference/jquery/jquery-3.4.1.js"></script>
 <script type="text/javascript" 
src="../resource/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/res/js/wicket-ajax-jquery.js"></script>
-</head>]]></header-contribution><priority-evaluate><![CDATA[(function(){prepend();})();]]></priority-evaluate><evaluate><![CDATA[(function(){domReady();})();(function(){append();})();(function(){onLoad();})();]]></evaluate></ajax-response>
\ No newline at end of file
+</head>]]></header-contribution><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){domReady();})();(function(){append();})();(function(){onLoad();})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution></ajax-response>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage_ajax_expected.html
 
b/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage_ajax_expected.html
index 9791e9c..93b9b8c 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage_ajax_expected.html
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/DomReadyOrderPage_ajax_expected.html
@@ -10,4 +10,9 @@ Wicket.Log.enabled=true;
 
Wicket.Ajax.baseUrl="wicket/bookmarkable/org.apache.wicket.ajax.DomReadyOrderPage?0-1.0-test";
 /*]]]]><![CDATA[>*/
 </script>
-</head>]]></header-contribution><evaluate><![CDATA[(function(){Wicket.Ajax.ajax({"u":"./org.apache.wicket.ajax.DomReadyOrderPage?0-1.0-test","c":"test1","e":"click","pd":true});})();(function(){test1();})();(function(){test2();})();]]></evaluate></ajax-response>
\ No newline at end of file
+</head>]]></header-contribution><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){Wicket.Ajax.ajax({"u":"./org.apache.wicket.ajax.DomReadyOrderPage?0-1.0-test","c":"test1","e":"click","pd":true});})();(function(){test1();})();(function(){test2();})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution></ajax-response>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/componentMap/SimpleTestPageExpectedResult-1.html
 
b/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/componentMap/SimpleTestPageExpectedResult-1.html
index 279ac72..ba09269 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/componentMap/SimpleTestPageExpectedResult-1.html
+++ 
b/wicket-core/src/test/java/org/apache/wicket/ajax/markup/html/componentMap/SimpleTestPageExpectedResult-1.html
@@ -10,4 +10,9 @@ Wicket.Log.enabled=true;
 
Wicket.Ajax.baseUrl="wicket/bookmarkable/org.apache.wicket.ajax.markup.html.componentMap.SimpleTestPage?0-1.0-testPanel-baseSpan-linja1";
 /*]]]]><![CDATA[>*/
 </script>
-</head>]]></header-contribution><evaluate><![CDATA[(function(){Wicket.Timer.set('linja11.0',
 
function(){Wicket.Ajax.ajax({"u":"./org.apache.wicket.ajax.markup.html.componentMap.SimpleTestPage?0-1.0-testPanel-baseSpan-linja1","c":"linja11"});},
 2000);})();]]></evaluate></ajax-response>
\ No newline at end of file
+</head>]]></header-contribution><header-contribution><![CDATA[<head 
xmlns:wicket="http://wicket.apache.org";><script type="text/javascript">
+/*<![CDATA[*/
+(function(){Wicket.Timer.set('linja11.0', 
function(){Wicket.Ajax.ajax({"u":"./org.apache.wicket.ajax.markup.html.componentMap.SimpleTestPage?0-1.0-testPanel-baseSpan-linja1","c":"linja11"});},
 2000);})();
+/*]]]]><![CDATA[>*/
+</script>
+</head>]]></header-contribution></ajax-response>
\ No newline at end of file
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/CspNoncePageExpected.html
 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/CspNoncePageExpected.html
index 63c9d08..2c44fc9 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/CspNoncePageExpected.html
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/head/filter/CspNoncePageExpected.html
@@ -1,5 +1,5 @@
 <html 
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"; >
-    <head><meta http-equiv="Content-Security-Policy" content="script-src 
'unsafe-eval' 'strict-dynamic' 'nonce-NONCE'; style-src 'nonce-NONCE';" />
+    <head><meta http-equiv="Content-Security-Policy" content="script-src 
'strict-dynamic' 'nonce-NONCE'; style-src 'nonce-NONCE';" />
 <script type="text/javascript" 
src="../resource/org.apache.wicket.resource.JQueryResourceReference/jquery/jquery-3.4.1.js"
 nonce="NONCE"></script>
 <script type="text/javascript" 
src="../resource/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/res/js/wicket-ajax-jquery.js"
 nonce="NONCE"></script>
 <script type="text/javascript" id="wicket-ajax-debug-enable" nonce="NONCE">

Reply via email to