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.markup.html.link; 018 019import org.apache.wicket.util.io.IClusterable; 020import org.slf4j.Logger; 021import org.slf4j.LoggerFactory; 022 023 024/** 025 * A popup specification can be used as a property of the {@link Link}classes to specify that the 026 * link should be rendered with an onClick javascript event handler that opens a new window with the 027 * links' URL. 028 * <p> 029 * You can 'or' display flags together like this: 030 * 031 * <pre> 032 * new PopupSettings(PopupSettings.RESIZABLE | PopupSettings.SCROLLBARS); 033 * </pre> 034 * 035 * </p> 036 * 037 * @author Jonathan Locke 038 * @author Eelco Hillenius 039 */ 040public class PopupSettings implements IClusterable 041{ 042 /** The log. */ 043 private static final Logger log = LoggerFactory.getLogger(PopupSettings.class); 044 045 private static final long serialVersionUID = 1L; 046 047 /** Flag to include location bar */ 048 public static final int LOCATION_BAR = 1; 049 050 /** Flag to include menu bar */ 051 public static final int MENU_BAR = 2; 052 053 /** Flag to make popup resizable */ 054 public static final int RESIZABLE = 4; 055 056 /** Flag to include scrollbars */ 057 public static final int SCROLLBARS = 8; 058 059 /** Flag to include status bar */ 060 public static final int STATUS_BAR = 16; 061 062 /** Flag to include location bar */ 063 public static final int TOOL_BAR = 32; 064 065 /** Display flags */ 066 private int displayFlags; 067 068 /** Height of popup window. */ 069 private int height = -1; 070 071 /** Left position of popup window. */ 072 private int left = -1; 073 074 /** 075 * The target to put in JavaScript. This implementation simply refers to the href attribute, but 076 * clients may want to override this (e.g. when the HTML element is not an anchor). 077 */ 078 private String target = "href"; 079 080 /** Top position of popup window. */ 081 private int top = -1; 082 083 /** Width of popup window. */ 084 private int width = -1; 085 086 /** 087 * The logical name of the window. This can be anything you want, although you should use 088 * alphanumeric characters only (no spaces or punctuation). If you have a window already open 089 * and call window.open a second time using the same windowName, the first window will be reused 090 * rather than opening a second window. 091 */ 092 private String windowName = null; 093 094 /** 095 * Constructor. 096 */ 097 public PopupSettings() 098 { 099 } 100 101 /** 102 * Construct. 103 * 104 * @param displayFlags 105 * Display flags 106 */ 107 public PopupSettings(final int displayFlags) 108 { 109 this(null, displayFlags); 110 } 111 112 /** 113 * Construct. 114 * 115 * @param windowName 116 */ 117 public PopupSettings(String windowName) 118 { 119 this(windowName, 0); 120 } 121 122 /** 123 * Construct. 124 * 125 * @param windowName 126 * The pagemap where this popup must be in. Typically, you should put any popup in a 127 * separate page map as Wicket holds references to a limited number of pages/ 128 * versions only. If you don't put your popup in a separate page map, the user might 129 * get page expired exceptions when getting back to the main window again. 130 * @param displayFlags 131 * Display flags 132 */ 133 public PopupSettings(String windowName, final int displayFlags) 134 { 135 this.displayFlags = displayFlags; 136 this.windowName = windowName; 137 } 138 139 /** 140 * Get the onClick javascript event handler. 141 * 142 * @return the onClick javascript event handler 143 */ 144 public String getPopupJavaScript() 145 { 146 String windowTitle = windowName; 147 148 if (windowTitle == null) 149 { 150 windowTitle = ""; 151 } 152 else 153 { 154 // Fix for IE bug. 155 windowTitle = windowTitle.replaceAll("\\W", "_"); 156 } 157 158 StringBuilder script = new StringBuilder("var w = window.open(" + target + ", '").append( 159 windowTitle).append("', '"); 160 161 script.append("scrollbars=").append(flagToString(SCROLLBARS)); 162 script.append(",location=").append(flagToString(LOCATION_BAR)); 163 script.append(",menuBar=").append(flagToString(MENU_BAR)); 164 script.append(",resizable=").append(flagToString(RESIZABLE)); 165 script.append(",status=").append(flagToString(STATUS_BAR)); 166 script.append(",toolbar=").append(flagToString(TOOL_BAR)); 167 168 if (width != -1) 169 { 170 script.append(",width=").append(width); 171 } 172 173 if (height != -1) 174 { 175 script.append(",height=").append(height); 176 } 177 178 if (left != -1) 179 { 180 script.append(",left=").append(left); 181 } 182 183 if (top != -1) 184 { 185 script.append(",top=").append(top); 186 } 187 188 script.append("'); try {if (w.blur) w.focus();}catch(ignore){}; return false;"); 189 190 return script.toString(); 191 } 192 193 /** 194 * Sets the popup window height. 195 * 196 * @param popupHeight 197 * the popup window height. 198 * @return This 199 */ 200 public PopupSettings setHeight(int popupHeight) 201 { 202 height = popupHeight; 203 return this; 204 } 205 206 /** 207 * Sets the left position of the popup window. 208 * 209 * @param popupPositionLeft 210 * the left position of the popup window. 211 * @return This 212 */ 213 public PopupSettings setLeft(int popupPositionLeft) 214 { 215 left = popupPositionLeft; 216 return this; 217 } 218 219 /** 220 * Sets the target of the link. The default implementation simply refers to the href attribute of 221 * the anchor element, but clients may want to override this (e.g. when the HTML element is not an anchor) by 222 * setting the target explicitly. 223 * 224 * <strong>Note</strong>: if the target is an url (relative or absolute) then it should be wrapped in 225 * quotes, for example: <code>setTarget("'some/url'")</code>. If the url is delivered with an HTML attribute then 226 * it should be without quotes, for example: <code>setTarget("this.dataset['popup-url']")</code> with markup like: 227 * <pre><code><a data-popup-url="some/url">Link</a></code></pre>. 228 * 229 * @param target 230 * the target of the link 231 */ 232 public void setTarget(String target) 233 { 234 this.target = target; 235 } 236 237 /** 238 * Sets the top position of the popup window. 239 * 240 * @param popupPositionTop 241 * the top position of the popup window. 242 * @return This 243 */ 244 public PopupSettings setTop(int popupPositionTop) 245 { 246 top = popupPositionTop; 247 return this; 248 } 249 250 /** 251 * Sets the popup window width. 252 * 253 * @param popupWidth 254 * the popup window width. 255 * @return This 256 */ 257 public PopupSettings setWidth(int popupWidth) 258 { 259 width = popupWidth; 260 return this; 261 } 262 263 /** 264 * Sets the window name. The logical name of the window. This can be anything you want, although 265 * you should use alphanumeric characters only (no spaces or punctuation). If you have a window 266 * already open and call window.open a second time using the same windowName, the first window 267 * will be reused rather than opening a second window 268 * 269 * @param popupWindowName 270 * window name. 271 * @return This 272 */ 273 public PopupSettings setWindowName(String popupWindowName) 274 { 275 if (popupWindowName != null) 276 { 277 windowName = popupWindowName; 278 } 279 return this; 280 } 281 282 /** 283 * @param flag 284 * The flag to test 285 * @return Yes or no depending on whether the flag is set 286 */ 287 private String flagToString(final int flag) 288 { 289 return (displayFlags & flag) != 0 ? "yes" : "no"; 290 } 291}