WICKET-5435 Ajaxified version of WebSession#getClientInfo should be added Introduce AjaxClientInfoBehavior that collects the client info.
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/c84f0c25 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/c84f0c25 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/c84f0c25 Branch: refs/heads/wicket-6.x Commit: c84f0c25bf86731e5abdaa1899def55f2545ee90 Parents: a2c21b1 Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Sat Dec 14 10:09:30 2013 +0200 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Sat Dec 14 10:09:30 2013 +0200 ---------------------------------------------------------------------- .../wicket/ajax/AjaxClientInfoBehavior.java | 134 +++++++++++++++++++ .../markup/html/pages/AjaxBrowserInfoForm.java | 91 ------------- .../markup/html/pages/wicket-browser-info.js | 57 +++++--- .../wicket/protocol/http/ClientProperties.java | 26 ++-- .../ajaxhellobrowser/AjaxHelloBrowser.html | 7 +- .../ajaxhellobrowser/AjaxHelloBrowser.java | 13 +- 6 files changed, 191 insertions(+), 137 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/c84f0c25/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxClientInfoBehavior.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxClientInfoBehavior.java b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxClientInfoBehavior.java new file mode 100644 index 0000000..c106d72 --- /dev/null +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxClientInfoBehavior.java @@ -0,0 +1,134 @@ +/* + * 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.ClientProperties; +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.request.resource.JavaScriptResourceReference; +import org.apache.wicket.util.time.Duration; + +/** + * An behavior that collects the information to populate + * WebClientInfo's ClientProperties by using Ajax + */ +public class AjaxClientInfoBehavior extends AbstractAjaxTimerBehavior +{ + /** + * Constructor. + * + * Auto fires after 50 millis. + */ + public AjaxClientInfoBehavior() + { + this(Duration.milliseconds(50)); + } + + /** + * Constructor. + * + * Auto fires after {@code duration}. + */ + public AjaxClientInfoBehavior(Duration duration) + { + super(duration); + } + + @Override + protected final void onTimer(AjaxRequestTarget target) + { + stop(target); + + RequestCycle requestCycle = RequestCycle.get(); + IRequestParameters requestParameters = requestCycle.getRequest().getRequestParameters(); + String navigatorAppName = requestParameters.getParameterValue("navigatorAppName").toString("N/A"); + String navigatorAppVersion = requestParameters.getParameterValue("navigatorAppVersion").toString("N/A"); + String navigatorAppCodeName = requestParameters.getParameterValue("navigatorAppCodeName").toString("N/A"); + boolean navigatorCookieEnabled = requestParameters.getParameterValue("navigatorCookieEnabled").toBoolean(false); + Boolean navigatorJavaEnabled = requestParameters.getParameterValue("navigatorJavaEnabled").toBoolean(false); + String navigatorLanguage = requestParameters.getParameterValue("navigatorLanguage").toString("N/A"); + String navigatorPlatform = requestParameters.getParameterValue("navigatorPlatform").toString("N/A"); + String navigatorUserAgent = requestParameters.getParameterValue("navigatorUserAgent").toString("N/A"); + int screenWidth = requestParameters.getParameterValue("screenWidth").toInt(-1); + int screenHeight = requestParameters.getParameterValue("screenHeight").toInt(-1); + int screenColorDepth = requestParameters.getParameterValue("screenColorDepth").toInt(-1); + String utcOffset = requestParameters.getParameterValue("utcOffset").toString("N/A"); + String utcDSTOffset = requestParameters.getParameterValue("utcDSTOffset").toString("N/A"); + int browserWidth = requestParameters.getParameterValue("browserWidth").toInt(-1); + int browserHeight = requestParameters.getParameterValue("browserHeight").toInt(-1); + String hostname = requestParameters.getParameterValue("hostname").toString("N/A"); + + WebClientInfo clientInfo = new WebClientInfo(requestCycle); + Session.get().setClientInfo(clientInfo); + + ClientProperties properties = clientInfo.getProperties(); + properties.setNavigatorAppCodeName(navigatorAppCodeName); + properties.setNavigatorAppName(navigatorAppName); + properties.setNavigatorAppVersion(navigatorAppVersion); + properties.setCookiesEnabled(navigatorCookieEnabled); + properties.setJavaEnabled(navigatorJavaEnabled); + properties.setNavigatorLanguage(navigatorLanguage); + properties.setNavigatorPlatform(navigatorPlatform); + properties.setNavigatorUserAgent(navigatorUserAgent); + properties.setScreenWidth(screenWidth); + properties.setScreenHeight(screenHeight); + properties.setScreenColorDepth(screenColorDepth); + properties.setUtcOffset(utcOffset); + properties.setUtcDSTOffset(utcDSTOffset); + properties.setBrowserWidth(browserWidth); + properties.setBrowserHeight(browserHeight); + properties.setHostname(hostname); + + onClientInfo(target, clientInfo); + } + + /** + * 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.getDynamicExtraParameters().add("return Wicket.BrowserInfo.collect()"); + } + + @Override + public void renderHead(Component component, IHeaderResponse response) + { + super.renderHead(component, response); + + response.render(JavaScriptHeaderItem.forReference( + new JavaScriptResourceReference(BrowserInfoForm.class, "wicket-browser-info.js"))); + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/c84f0c25/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/AjaxBrowserInfoForm.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/AjaxBrowserInfoForm.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/AjaxBrowserInfoForm.java deleted file mode 100644 index 1ac842c..0000000 --- a/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/AjaxBrowserInfoForm.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.html.pages; - -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.attributes.AjaxCallListener; -import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; -import org.apache.wicket.ajax.form.AjaxFormSubmitBehavior; -import org.apache.wicket.core.request.ClientInfo; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.protocol.http.request.WebClientInfo; - -/** - * An extension of BrowserInfoForm that uses AjaxFormSubmitBehavior - * to collect the client info without redirect to another page - */ -public class AjaxBrowserInfoForm extends BrowserInfoForm -{ - /** - * Constructor. - * - * @param id component id - */ - public AjaxBrowserInfoForm(String id) - { - super(id); - } - - @Override - protected Form<? extends ClientPropertiesBean> createForm(String componentId) - { - Form<? extends ClientPropertiesBean> f = super.createForm(componentId); - f.add(new AjaxFormSubmitBehavior(f, "domready") - { - @Override - protected void updateAjaxAttributes(AjaxRequestAttributes attributes) - { - super.updateAjaxAttributes(attributes); - AjaxCallListener listener = new AjaxCallListener(); - listener.onBefore(String.format("Wicket.BrowserInfo.populateFields('%s');", getFormMarkupId())); - attributes.getAjaxCallListeners().add(listener); - } - - @Override - protected void onAfterSubmit(AjaxRequestTarget target) - { - super.onAfterSubmit(target); - WebClientInfo info = getWebSession().getClientInfo(); - AjaxBrowserInfoForm.this.onAfterSubmit(target, info); - } - }); - return f; - } - - /** - * A callback method called when the client info is collected - * - * @param target - * The Ajax request handler - * @param info - * The client info - */ - protected void onAfterSubmit(AjaxRequestTarget target, WebClientInfo info) - { - } - - /** - * Does nothing. - * - * Use {@linkplain #onAfterSubmit(org.apache.wicket.ajax.AjaxRequestTarget, org.apache.wicket.protocol.http.request.WebClientInfo)} - */ - @Override - protected final void afterSubmit() - { - super.afterSubmit(); - } -} http://git-wip-us.apache.org/repos/asf/wicket/blob/c84f0c25/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/wicket-browser-info.js ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/wicket-browser-info.js b/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/wicket-browser-info.js index 6fb1fa3..528ff44 100644 --- a/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/wicket-browser-info.js +++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/pages/wicket-browser-info.js @@ -34,36 +34,51 @@ window.Wicket.BrowserInfo = { /** - * Populates the form elements with the client info + * Collects the client information * - * @param formMarkupId The markup id of the special form - * @returns {HTMLFormElement} The special form + * @returns {Object} */ - populateFields: function(formMarkupId) { - var postbackForm = document.getElementById(formMarkupId); - postbackForm.navigatorAppName.value = window.navigator.appName; - postbackForm.navigatorAppVersion.value = window.navigator.appVersion; - postbackForm.navigatorAppCodeName.value = window.navigator.appCodeName; + collect: function() { + var info = {}; + info.navigatorAppName = window.navigator.appName; + info.navigatorAppVersion = window.navigator.appVersion; + info.navigatorAppCodeName = window.navigator.appCodeName; var cookieEnabled = (window.navigator.cookieEnabled); if (typeof(window.navigator.cookieEnabled) === "undefined" && !cookieEnabled) { document.cookie = "wickettestcookie"; cookieEnabled = (document.cookie.indexOf("wickettestcookie") !== -1); } - postbackForm.navigatorCookieEnabled.value = cookieEnabled; - postbackForm.navigatorJavaEnabled.value = window.navigator.javaEnabled(); - postbackForm.navigatorLanguage.value = window.navigator.language ? window.navigator.language : window.navigator.userLanguage; - postbackForm.navigatorPlatform.value = window.navigator.platform; - postbackForm.navigatorUserAgent.value = window.navigator.userAgent; + info.navigatorCookieEnabled = cookieEnabled; + info.navigatorJavaEnabled = window.navigator.javaEnabled(); + info.navigatorLanguage = window.navigator.language ? window.navigator.language : window.navigator.userLanguage; + info.navigatorPlatform = window.navigator.platform; + info.navigatorUserAgent = window.navigator.userAgent; if (window.screen) { - postbackForm.screenWidth.value = window.screen.width; - postbackForm.screenHeight.value = window.screen.height; - postbackForm.screenColorDepth.value = window.screen.colorDepth; + info.screenWidth = window.screen.width; + info.screenHeight = window.screen.height; + info.screenColorDepth = window.screen.colorDepth; + } + info.utcOffset = (new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0).getTimezoneOffset() / -60); + info.utcDSTOffset = (new Date(new Date().getFullYear(), 6, 1, 0, 0, 0, 0).getTimezoneOffset() / -60); + info.browserWidth = window.innerWidth || document.body.offsetWidth; + info.browserHeight = window.innerHeight || document.body.offsetHeight; + info.hostname = window.location.hostname; + return info; + }, + + /** + * Populates the form elements with the client info + * + * @param formMarkupId The markup id of the special form + * @returns {HTMLFormElement} The special form + */ + populateFields: function(formMarkupId) { + var postbackForm = document.getElementById(formMarkupId); + var info = Wicket.BrowserInfo.collect(); + var i; + for (i in info) { + postbackForm[i].value = info[i]; } - postbackForm.utcOffset.value = (new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0).getTimezoneOffset() / -60); - postbackForm.utcDSTOffset.value = (new Date(new Date().getFullYear(), 6, 1, 0, 0, 0, 0).getTimezoneOffset() / -60); - postbackForm.browserWidth.value = window.innerWidth || document.body.offsetWidth; - postbackForm.browserHeight.value = window.innerHeight || document.body.offsetHeight; - postbackForm.hostname.value = window.location.hostname; return postbackForm; }, http://git-wip-us.apache.org/repos/asf/wicket/blob/c84f0c25/wicket-core/src/main/java/org/apache/wicket/protocol/http/ClientProperties.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/protocol/http/ClientProperties.java b/wicket-core/src/main/java/org/apache/wicket/protocol/http/ClientProperties.java index edf07be..dcd72a9 100644 --- a/wicket-core/src/main/java/org/apache/wicket/protocol/http/ClientProperties.java +++ b/wicket-core/src/main/java/org/apache/wicket/protocol/http/ClientProperties.java @@ -254,12 +254,12 @@ public class ClientProperties implements IClusterable // offset which can be parsed by the TimeZone class. AppendingStringBuffer sb = new AppendingStringBuffer("GMT"); - sb.append(offsetHours > 0 ? "+" : "-"); + sb.append(offsetHours > 0 ? '+' : '-'); sb.append(Math.abs(offsetHours)); - sb.append(":"); + sb.append(':'); if (offsetMins < 10) { - sb.append("0"); + sb.append('0'); } sb.append(offsetMins); timeZone = TimeZone.getTimeZone(sb.toString()); @@ -271,13 +271,13 @@ public class ClientProperties implements IClusterable { utc = utc.substring(1); } - timeZone = TimeZone.getTimeZone("GMT" + ((offset > 0) ? "+" : "-") + utc); + timeZone = TimeZone.getTimeZone("GMT" + ((offset > 0) ? '+' : '-') + utc); } String dstOffset = getUtcDSTOffset(); if (timeZone != null && dstOffset != null) { - TimeZone dstTimeZone = null; + TimeZone dstTimeZone; dotPos = dstOffset.indexOf('.'); if (dotPos >= 0) { @@ -296,12 +296,12 @@ public class ClientProperties implements IClusterable // offset which can be parsed by the TimeZone class. AppendingStringBuffer sb = new AppendingStringBuffer("GMT"); - sb.append(offsetHours > 0 ? "+" : "-"); + sb.append(offsetHours > 0 ? '+' : '-'); sb.append(Math.abs(offsetHours)); - sb.append(":"); + sb.append(':'); if (offsetMins < 10) { - sb.append("0"); + sb.append('0'); } sb.append(offsetMins); dstTimeZone = TimeZone.getTimeZone(sb.toString()); @@ -313,7 +313,7 @@ public class ClientProperties implements IClusterable { dstOffset = dstOffset.substring(1); } - dstTimeZone = TimeZone.getTimeZone("GMT" + ((offset > 0) ? "+" : "-") + + dstTimeZone = TimeZone.getTimeZone("GMT" + ((offset > 0) ? '+' : '-') + dstOffset); } // if the dstTimezone (1 July) has a different offset then @@ -1096,7 +1096,7 @@ public class ClientProperties implements IClusterable @Override public String toString() { - StringBuilder b = new StringBuilder(); + StringBuilder b = new StringBuilder(); Field[] fields = ClientProperties.class.getDeclaredFields(); @@ -1110,7 +1110,7 @@ public class ClientProperties implements IClusterable field.setAccessible(true); - Object value = null; + Object value; try { value = field.get(this); @@ -1135,9 +1135,9 @@ public class ClientProperties implements IClusterable if (value != null) { b.append(field.getName()); - b.append("="); + b.append('='); b.append(value); - b.append("\n"); + b.append('\n'); } } } http://git-wip-us.apache.org/repos/asf/wicket/blob/c84f0c25/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.html ---------------------------------------------------------------------- diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.html b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.html index 059abbc..48e9a0e 100644 --- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.html +++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.html @@ -7,12 +7,9 @@ <body> <div wicket:id="mainNavigation"></div> - <div wicket:id="form"></div> - <p> - Hi there. We have been snooping around your browser, even doing a sneaky - redirect to test some javascript properties in the process, and this is what we - found out: <br /><br /> + This page uses <em>org.apache.wicket.ajax.AjaxClientInfoBehavior</em> + to collect the following information: <br /><br /> ClientProperties: <span wicket:id="clientinfo">client info here</span> </p> http://git-wip-us.apache.org/repos/asf/wicket/blob/c84f0c25/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.java ---------------------------------------------------------------------- diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.java index 9e6c8e0..024ec01 100644 --- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.java +++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajaxhellobrowser/AjaxHelloBrowser.java @@ -21,12 +21,11 @@ import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; +import org.apache.wicket.ajax.AjaxClientInfoBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.core.request.ClientInfo; import org.apache.wicket.examples.WicketExamplePage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.basic.MultiLineLabel; -import org.apache.wicket.markup.html.pages.AjaxBrowserInfoForm; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.protocol.http.ClientProperties; @@ -84,20 +83,20 @@ public class AjaxHelloBrowser extends WicketExamplePage clientTime.setOutputMarkupPlaceholderTag(true); clientTime.setVisible(false); - AjaxBrowserInfoForm form = new AjaxBrowserInfoForm("form") + add(new AjaxClientInfoBehavior() { @Override - protected void onAfterSubmit(AjaxRequestTarget target, WebClientInfo info) + protected void onClientInfo(AjaxRequestTarget target, WebClientInfo info) { - super.onAfterSubmit(target, info); + super.onClientInfo(target, info); clientInfo.setVisible(true); clientTime.setVisible(true); target.add(clientInfo, clientTime); } - }; + }); - add(form, clientInfo, clientTime); + add(clientInfo, clientTime); } /**
