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

reiern70 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/master by this push:
     new 8a5a7b2d00 [WICKET-7048] AjaxClientInfoBehavior is AJAX timer based. 
This seems not to work reliable in all situations. We add a 
AjaxOnDomReadyClientInfoBehavior that uses DOMREADY and seems to work more 
reliable.
8a5a7b2d00 is described below

commit 8a5a7b2d0064ef2c0a1e41b2f19ed3f2ae4a149f
Author: reiern70 <[email protected]>
AuthorDate: Mon Apr 17 07:53:49 2023 +0300

    [WICKET-7048] AjaxClientInfoBehavior is AJAX timer based. This seems not to 
work reliable in all situations. We add a AjaxOnDomReadyClientInfoBehavior that 
uses DOMREADY and seems to work more reliable.
---
 .../ajax/AjaxOnDomReadyClientInfoBehavior.java     | 115 +++++++++++++++++
 .../AjaxHelloBrowserOnDomReady.html                |  19 +++
 .../AjaxHelloBrowserOnDomReady.java                | 139 +++++++++++++++++++++
 .../HelloBrowserOnDomReadyApplication.java         |  33 +++++
 .../apache/wicket/examples/homepage/HomePage.html  |   1 +
 wicket-examples/src/main/webapp/WEB-INF/web.xml    |  16 +++
 6 files changed, 323 insertions(+)

diff --git 
a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxOnDomReadyClientInfoBehavior.java
 
b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxOnDomReadyClientInfoBehavior.java
new file mode 100644
index 0000000000..84eaa08aaa
--- /dev/null
+++ 
b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxOnDomReadyClientInfoBehavior.java
@@ -0,0 +1,115 @@
+/*
+ * 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.ajax;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.Session;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.html.pages.BrowserInfoForm;
+import org.apache.wicket.protocol.http.request.WebClientInfo;
+import org.apache.wicket.request.IRequestParameters;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.util.lang.Args;
+import org.danekja.java.util.function.serializable.SerializableBiConsumer;
+
+/**
+ * A behavior that collects the information to populate
+ * WebClientInfo's ClientProperties by using Ajax. Compared to
+ * {@link AjaxClientInfoBehavior} this class does not use a timer
+ * but the DOM ready "event" to collect browser info.
+ *
+ * @see #onClientInfo(AjaxRequestTarget, WebClientInfo)
+ */
+public class AjaxOnDomReadyClientInfoBehavior extends 
AbstractDefaultAjaxBehavior
+{
+       private static final long serialVersionUID = 1L;
+
+       @Override
+       protected void respond(AjaxRequestTarget target)
+       {
+               RequestCycle requestCycle = RequestCycle.get();
+
+               IRequestParameters requestParameters = 
requestCycle.getRequest().getRequestParameters();
+               WebClientInfo clientInfo = newWebClientInfo(requestCycle);
+               clientInfo.getProperties().read(requestParameters);
+               Session.get().setClientInfo(clientInfo);
+
+               onClientInfo(target, clientInfo);
+       }
+
+       protected WebClientInfo newWebClientInfo(RequestCycle requestCycle)
+       {
+               return new WebClientInfo(requestCycle);
+       }
+
+       /**
+        * A callback method invoked when the client info is collected.
+        * 
+        * @param target
+        *          The Ajax request handler
+        * @param clientInfo
+        *          The collected info for the client 
+        */
+       protected void onClientInfo(AjaxRequestTarget target, WebClientInfo 
clientInfo)
+       {
+       }
+
+       @Override
+       protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
+       {
+               super.updateAjaxAttributes(attributes);
+               attributes.setEventNames("domready");
+               attributes.setMethod(AjaxRequestAttributes.Method.POST);
+               attributes.getDynamicExtraParameters().add("return 
Wicket.BrowserInfo.collect()");
+       }
+
+       @Override
+       public void renderHead(Component component, IHeaderResponse response)
+       {
+               super.renderHead(component, response);
+
+               
response.render(JavaScriptHeaderItem.forReference(BrowserInfoForm.JS));
+               
response.render(JavaScriptHeaderItem.forScript(getCallbackScript(), 
"ajaxOnDomReadyClientInfoBehavior"));
+       }
+
+       /**
+        * Creates an {@link AjaxOnDomReadyClientInfoBehavior} based on lambda 
expressions
+        *
+        * @param onClientInfo
+        *            the {@code SerializableBiConsumer} which accepts the 
{@link AjaxRequestTarget} and the
+        *            {@link WebClientInfo}
+        * @return the {@link AjaxOnDomReadyClientInfoBehavior}
+        */
+       public static AjaxOnDomReadyClientInfoBehavior 
onClientInfo(SerializableBiConsumer<AjaxRequestTarget, WebClientInfo> 
onClientInfo)
+       {
+               Args.notNull(onClientInfo, "onClientInfo");
+
+               return new AjaxOnDomReadyClientInfoBehavior()
+               {
+
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       protected void onClientInfo(AjaxRequestTarget target, 
WebClientInfo clientInfo)
+                       {
+                               onClientInfo.accept(target, clientInfo);
+                       }
+               };
+       }
+}
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/AjaxHelloBrowserOnDomReady.html
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/AjaxHelloBrowserOnDomReady.html
new file mode 100644
index 0000000000..2e68c8b85d
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/AjaxHelloBrowserOnDomReady.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml"; 
xmlns:wicket="http://wicket.apache.org";>
+<head>
+    <title>Wicket Examples - hellobrowser</title>
+</head>
+<body>
+    <wicket:extend>
+               <p>
+                   This page uses 
<em>org.apache.wicket.ajax.AjaxOnDomReadyClientInfoBehavior</em>
+               to collect the following information: <br /><br />
+                   ClientProperties: <span wicket:id="clientinfo">client info 
here</span>
+               </p>
+       
+               <p>
+                       <span wicket:id="clienttime">client time info 
here</span>
+               </p>
+    </wicket:extend>
+</body>
+</html>
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/AjaxHelloBrowserOnDomReady.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/AjaxHelloBrowserOnDomReady.java
new file mode 100644
index 0000000000..509b62dcd0
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/AjaxHelloBrowserOnDomReady.java
@@ -0,0 +1,139 @@
+/*
+ * 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.examples.ajaxhellowbrowserondomready;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxOnDomReadyClientInfoBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.examples.ajaxhellobrowser.ExtendedClientProperties;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.basic.MultiLineLabel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.protocol.http.ClientProperties;
+import org.apache.wicket.protocol.http.request.WebClientInfo;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.settings.RequestCycleSettings;
+
+
+/**
+ * A demo usage of AjaxBrowserInfoForm
+ */
+public class AjaxHelloBrowserOnDomReady extends WicketExamplePage
+{
+       /**
+        * Constructor.
+        */
+       public AjaxHelloBrowserOnDomReady()
+       {
+               final MultiLineLabel clientInfo = new 
MultiLineLabel("clientinfo", new IModel<String>()
+               {
+                       @Override
+                       public String getObject()
+                       {
+                               ClientProperties properties = 
getClientProperties();
+                               return properties.toString();
+                       }
+               });
+               clientInfo.setOutputMarkupPlaceholderTag(true);
+               clientInfo.setVisible(false);
+
+               IModel<String> clientTimeModel = () -> {
+                       ClientProperties properties = getClientProperties();
+                       TimeZone timeZone = properties.getTimeZone();
+                       if (timeZone != null)
+                       {
+                               Calendar cal = Calendar.getInstance(timeZone);
+                               Locale locale = getLocale();
+                               DateFormat dateFormat = 
DateFormat.getTimeInstance(DateFormat.LONG, locale);
+                               dateFormat.setTimeZone(timeZone);
+                               String calAsString = 
dateFormat.format(cal.getTime());
+                               StringBuilder b = new StringBuilder("Based on 
your settings, your time is: ");
+                               b.append(calAsString);
+                               b.append(" (and your time zone is ");
+                               b.append(timeZone.getDisplayName(getLocale()));
+                               b.append(')');
+                               return b.toString();
+                       }
+                       return "Unfortunately, we were not able to figure out 
what your time zone is, so we have"
+                                       + " no idea what your time is";
+               };
+               final Label clientTime = new Label("clienttime", 
clientTimeModel);
+               clientTime.setOutputMarkupPlaceholderTag(true);
+               clientTime.setVisible(false);
+
+               add(new AjaxOnDomReadyClientInfoBehavior() {
+
+                       @Override
+                       public void renderHead(Component component, 
IHeaderResponse response)
+                       {
+                               super.renderHead(component, response);
+
+                               String script = 
"Wicket.BrowserInfo.collectExtraInfo = function(info) { info.extendedProperty = 
'This property was read extra.'; };";
+
+                               
response.render(JavaScriptHeaderItem.forScript(script, "extended-client-info"));
+                       }
+
+                       @Override
+                       protected WebClientInfo newWebClientInfo(RequestCycle 
requestCycle)
+                       {
+                               return new WebClientInfo(requestCycle, new 
ExtendedClientProperties());
+                       }
+
+                       @Override
+                       protected void onClientInfo(AjaxRequestTarget target, 
WebClientInfo webClientInfo)
+                       {
+                               clientInfo.setVisible(true);
+                               clientTime.setVisible(true);
+
+                               target.add(clientInfo, clientTime);
+                       }
+               });
+
+               add(clientInfo, clientTime);
+       }
+
+       /**
+        * A helper function that makes sure that gathering of extended browser 
info
+        * is not enabled when reading the ClientInfo's properties
+        *
+        * @return the currently available client info
+        */
+       private ClientProperties getClientProperties()
+       {
+               RequestCycleSettings requestCycleSettings = 
getApplication().getRequestCycleSettings();
+               boolean gatherExtendedBrowserInfo = 
requestCycleSettings.getGatherExtendedBrowserInfo();
+               ClientProperties properties = null;
+               try
+               {
+                       
requestCycleSettings.setGatherExtendedBrowserInfo(false);
+                       WebClientInfo clientInfo = (WebClientInfo) 
getSession().getClientInfo();
+                       properties = clientInfo.getProperties();
+               }
+               finally
+               {
+                       
requestCycleSettings.setGatherExtendedBrowserInfo(gatherExtendedBrowserInfo);
+               }
+               return properties;
+       }
+}
diff --git 
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/HelloBrowserOnDomReadyApplication.java
 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/HelloBrowserOnDomReadyApplication.java
new file mode 100644
index 0000000000..15c4660f31
--- /dev/null
+++ 
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellowbrowserondomready/HelloBrowserOnDomReadyApplication.java
@@ -0,0 +1,33 @@
+/*
+ * 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.examples.ajaxhellowbrowserondomready;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.examples.WicketExampleApplication;
+
+/**
+ * Application class for Ajax based browser info extractor.
+ */
+public class HelloBrowserOnDomReadyApplication extends WicketExampleApplication
+{
+       @Override
+       public Class<? extends Page> getHomePage()
+       {
+               return AjaxHelloBrowserOnDomReady.class;
+       }
+
+}
diff --git 
a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
 
b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
index 46631905f3..2199c03f50 100644
--- 
a/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
+++ 
b/wicket-examples/src/main/resources/org/apache/wicket/examples/homepage/HomePage.html
@@ -28,6 +28,7 @@
        <tr><td align="right"><a href="stateless">stateless</a></td><td> - 
Demonstrates stateless pages/sessions.</td></tr>
        <tr><td align="right"><a href="hellobrowser">Browser Info</a></td><td> 
- Extracts client info by redirecting to a temporary page.</td></tr>
        <tr><td align="right"><a href="ajaxhellobrowser">Ajax Browser 
Info</a></td><td> - Extracts client info by using Ajax.</td></tr>
+       <tr><td align="right"><a href="ajaxhellobrowserondomready">Ajax Browser 
Info (OnDomReady)</a></td><td> - Extracts client info by using Ajax (using on 
DOM ready).</td></tr>
        <tr><td align="right"><a href="frames">frames</a></td><td> - Example 
demonstrating HTML frames.</td></tr>
        <tr><td align="right"><a href="prototype">ajax with 
prototype</a></td><td> - AJAX example using prototype.js.</td></tr>
        <tr><td align="right"><a href="wizard">abacadabra</a></td><td> - 
Demonstrates the wizard component.</td></tr>
diff --git a/wicket-examples/src/main/webapp/WEB-INF/web.xml 
b/wicket-examples/src/main/webapp/WEB-INF/web.xml
index 0601b975e5..c11a872f60 100644
--- a/wicket-examples/src/main/webapp/WEB-INF/web.xml
+++ b/wicket-examples/src/main/webapp/WEB-INF/web.xml
@@ -122,6 +122,15 @@
                </init-param>
        </filter>
 
+       <filter>
+               <filter-name>AjaxHelloBrowserOnDomReadyApplication</filter-name>
+               
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+               <init-param>
+                       <param-name>applicationClassName</param-name>
+                       
<param-value>org.apache.wicket.examples.ajaxhellowbrowserondomready.HelloBrowserOnDomReadyApplication</param-value>
+               </init-param>
+       </filter>
+
        <filter>
                <filter-name>HangmanApplication</filter-name>
                
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
@@ -604,6 +613,13 @@
                <dispatcher>INCLUDE</dispatcher>
        </filter-mapping>
 
+       <filter-mapping>
+               <filter-name>AjaxHelloBrowserOnDomReadyApplication</filter-name>
+               <url-pattern>/ajaxhellobrowserondomready/*</url-pattern>
+               <dispatcher>REQUEST</dispatcher>
+               <dispatcher>INCLUDE</dispatcher>
+       </filter-mapping>
+
        <filter-mapping>
                <filter-name>FormInputApplication</filter-name>
                <url-pattern>/forminput/*</url-pattern>

Reply via email to