001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.ajax; 018 019import org.apache.wicket.Component; 020import org.apache.wicket.Session; 021import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; 022import org.apache.wicket.markup.head.IHeaderResponse; 023import org.apache.wicket.markup.head.JavaScriptHeaderItem; 024import org.apache.wicket.markup.html.pages.BrowserInfoForm; 025import org.apache.wicket.protocol.http.request.WebClientInfo; 026import org.apache.wicket.request.IRequestParameters; 027import org.apache.wicket.request.cycle.RequestCycle; 028import org.apache.wicket.util.lang.Args; 029import org.danekja.java.util.function.serializable.SerializableBiConsumer; 030 031/** 032 * A behavior that collects the information to populate 033 * WebClientInfo's ClientProperties by using Ajax. Compared to 034 * {@link AjaxClientInfoBehavior} this class does not use a timer 035 * but the DOM ready "event" to collect browser info. 036 * 037 * @see #onClientInfo(AjaxRequestTarget, WebClientInfo) 038 */ 039public class AjaxOnDomReadyClientInfoBehavior extends AbstractDefaultAjaxBehavior 040{ 041 private static final long serialVersionUID = 1L; 042 043 @Override 044 protected void respond(AjaxRequestTarget target) 045 { 046 RequestCycle requestCycle = RequestCycle.get(); 047 048 IRequestParameters requestParameters = requestCycle.getRequest().getRequestParameters(); 049 WebClientInfo clientInfo = newWebClientInfo(requestCycle); 050 clientInfo.getProperties().read(requestParameters); 051 Session.get().setClientInfo(clientInfo); 052 053 onClientInfo(target, clientInfo); 054 } 055 056 protected WebClientInfo newWebClientInfo(RequestCycle requestCycle) 057 { 058 return new WebClientInfo(requestCycle); 059 } 060 061 /** 062 * A callback method invoked when the client info is collected. 063 * 064 * @param target 065 * The Ajax request handler 066 * @param clientInfo 067 * The collected info for the client 068 */ 069 protected void onClientInfo(AjaxRequestTarget target, WebClientInfo clientInfo) 070 { 071 } 072 073 @Override 074 protected void updateAjaxAttributes(AjaxRequestAttributes attributes) 075 { 076 super.updateAjaxAttributes(attributes); 077 attributes.setEventNames("domready"); 078 attributes.setMethod(AjaxRequestAttributes.Method.POST); 079 attributes.getDynamicExtraParameters().add("return Wicket.BrowserInfo.collect()"); 080 } 081 082 @Override 083 public void renderHead(Component component, IHeaderResponse response) 084 { 085 super.renderHead(component, response); 086 087 response.render(JavaScriptHeaderItem.forReference(BrowserInfoForm.JS)); 088 response.render(JavaScriptHeaderItem.forScript(getCallbackScript(), "ajaxOnDomReadyClientInfoBehavior")); 089 } 090 091 /** 092 * Creates an {@link AjaxOnDomReadyClientInfoBehavior} based on lambda expressions 093 * 094 * @param onClientInfo 095 * the {@code SerializableBiConsumer} which accepts the {@link AjaxRequestTarget} and the 096 * {@link WebClientInfo} 097 * @return the {@link AjaxOnDomReadyClientInfoBehavior} 098 */ 099 public static AjaxOnDomReadyClientInfoBehavior onClientInfo(SerializableBiConsumer<AjaxRequestTarget, WebClientInfo> onClientInfo) 100 { 101 Args.notNull(onClientInfo, "onClientInfo"); 102 103 return new AjaxOnDomReadyClientInfoBehavior() 104 { 105 106 private static final long serialVersionUID = 1L; 107 108 @Override 109 protected void onClientInfo(AjaxRequestTarget target, WebClientInfo clientInfo) 110 { 111 onClientInfo.accept(target, clientInfo); 112 } 113 }; 114 } 115}