001package com.hfg.javascript; 002 003import java.util.Map; 004import java.util.HashMap; 005 006import com.hfg.html.HTML; 007import com.hfg.util.StringUtil; 008import com.hfg.xml.XMLNode; 009import com.hfg.svg.SvgNode; 010 011//------------------------------------------------------------------------------ 012/** 013 Generic tooltip generation javascript. 014 Tooltips can be added to any tag which supports onmouseover and onmouseout. 015 You will also need to add generateJS() to the javascript in the page's <head> tag. 016 <p> 017 See <a href='doc-files/tooltipTest.html' target='_parent'>this page</a> for tooltip examples. 018 </p> 019 020 <div>Simple code example: 021 <pre> 022 <b>TooltipJS tooltip = new TooltipJS();</b> 023 024 HTMLDoc htmlDoc = new HTMLDoc(); 025 026 // Keep IE from going into quirks mode. 027 htmlDoc.setDoctype(Doctype.HTML_4_01_TRANSITIONAL_NO_URL); 028 029 HTML html = new HTML(); 030 htmlDoc.setRootTag(html); 031 html.getHead().addSubtag(Meta.CONTENT_TYPE_ISO_8859_1); 032 033 <b>// Add the necessary javascript to the page. 034 html.getHead().addJavascript(tooltip.generateJS());</b> 035 036 Body body = html.getBody(); 037 body.br(2); 038 039 // Create the target tag (in this case a span) the tooltip will function on. 040 Span testSpan = body.addSpan("Test span"); 041 042 <b>// Create the tooltip content 043 Pre tooltip1Content = new Pre("foobar and all that stuff\n"); 044 tooltip1Content.addSpan("just grinds my axe!\n").setStyle(CSS.BOLD + CSS.fontSize(24)); 045 046 // Attach the tooltip to the target. 047 tooltip.addTooltip(testSpan, tooltip1Content.toHTML());</b> 048 049 </pre> 050 </div> 051 052 @author J. Alex Taylor, hairyfatguy.com 053 */ 054//------------------------------------------------------------------------------ 055// com.hfg XML/HTML Coding Library 056// 057// This library is free software; you can redistribute it and/or 058// modify it under the terms of the GNU Lesser General Public 059// License as published by the Free Software Foundation; either 060// version 2.1 of the License, or (at your option) any later version. 061// 062// This library is distributed in the hope that it will be useful, 063// but WITHOUT ANY WARRANTY; without even the implied warranty of 064// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 065// Lesser General Public License for more details. 066// 067// You should have received a copy of the GNU Lesser General Public 068// License along with this library; if not, write to the Free Software 069// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 070// 071// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 072// jataylor@hairyfatguy.com 073//------------------------------------------------------------------------------ 074 075public class TooltipJS 076{ 077 //########################################################################## 078 // PRIVATE FIELDS 079 //########################################################################## 080 081 private int mDelay = 500; 082 private int mXOffset = 10; 083 private int mYOffset = 20; 084 private int mMaxWidth = 300; 085 private String mBorder = "1px solid #666666"; 086 private String mFont = "arial,sans-serif"; 087 private String mFontSize = "11px"; 088 private String mFontColor = "#006600"; 089 private String mBgColor = "#eeffee"; 090 private int mPadding = 3; 091 private String mShadowColor = "#000000"; 092 private int mShadowOffset = 3; 093 private boolean mAddOnMouseMove = false; 094 095 private String mCachedJs; 096 097 //########################################################################## 098 // CONSTRUCTORS 099 //########################################################################## 100 101 //-------------------------------------------------------------------------- 102 public TooltipJS() 103 { 104 } 105 106 //########################################################################## 107 // PUBLIC METHODS 108 //########################################################################## 109 110 //-------------------------------------------------------------------------- 111 public TooltipJS setDelay(int inValue) 112 { 113 if (inValue != mDelay) 114 { 115 mDelay = inValue; 116 mCachedJs = null; // Invalidate the cache. 117 } 118 return this; 119 } 120 121 //-------------------------------------------------------------------------- 122 public TooltipJS setXOffset(int inValue) 123 { 124 if (inValue != mXOffset) 125 { 126 mXOffset = inValue; 127 mCachedJs = null; // Invalidate the cache. 128 } 129 return this; 130 } 131 132 //-------------------------------------------------------------------------- 133 public TooltipJS setYOffset(int inValue) 134 { 135 if (inValue != mYOffset) 136 { 137 mYOffset = inValue; 138 mCachedJs = null; // Invalidate the cache. 139 } 140 return this; 141 } 142 143 //-------------------------------------------------------------------------- 144 public TooltipJS setBorder(String inValue) 145 { 146 if (null == inValue) 147 { 148 throw new RuntimeException("The border cannot be set to null!"); 149 } 150 151 if (! inValue.equals(mBorder)) 152 { 153 mBorder = inValue; 154 mCachedJs = null; // Invalidate the cache. 155 } 156 return this; 157 } 158 159 //-------------------------------------------------------------------------- 160 public TooltipJS setFont(String inValue) 161 { 162 if (null == inValue) 163 { 164 throw new RuntimeException("The font cannot be set to null!"); 165 } 166 167 if (! inValue.equals(mFont)) 168 { 169 mFont = inValue; 170 mCachedJs = null; // Invalidate the cache. 171 } 172 return this; 173 } 174 175 //-------------------------------------------------------------------------- 176 public TooltipJS setFontSize(String inValue) 177 { 178 if (null == inValue) 179 { 180 throw new RuntimeException("The font size cannot be set to null!"); 181 } 182 183 if (! inValue.equals(mFontSize)) 184 { 185 mFontSize = inValue; 186 mCachedJs = null; // Invalidate the cache. 187 } 188 return this; 189 } 190 191 //-------------------------------------------------------------------------- 192 public TooltipJS setFontColor(String inValue) 193 { 194 if (null == inValue) 195 { 196 throw new RuntimeException("The font color cannot be set to null!"); 197 } 198 199 if (! inValue.equals(mFontColor)) 200 { 201 mFontColor = inValue; 202 mCachedJs = null; // Invalidate the cache. 203 } 204 return this; 205 } 206 207 //-------------------------------------------------------------------------- 208 public TooltipJS setBackgroundColor(String inValue) 209 { 210 if (null == inValue) 211 { 212 throw new RuntimeException("The background color cannot be set to null!"); 213 } 214 215 if (! inValue.equals(mBgColor)) 216 { 217 mBgColor = inValue; 218 mCachedJs = null; // Invalidate the cache. 219 } 220 return this; 221 } 222 223 //-------------------------------------------------------------------------- 224 public TooltipJS setPadding(int inValue) 225 { 226 if (inValue != mPadding) 227 { 228 mPadding = inValue; 229 mCachedJs = null; // Invalidate the cache. 230 } 231 return this; 232 } 233 234 //-------------------------------------------------------------------------- 235 public TooltipJS setShadowColor(String inValue) 236 { 237 if (null == inValue) 238 { 239 throw new RuntimeException("The shadow color cannot be set to null!"); 240 } 241 242 if (! inValue.equals(mShadowColor)) 243 { 244 mShadowColor = inValue; 245 mCachedJs = null; // Invalidate the cache. 246 } 247 return this; 248 } 249 250 //-------------------------------------------------------------------------- 251 252 /** 253 Sets the suggested maximum width for tooltips. If content cannot be 254 squeezed into this width, such as is sometimes the case with Pre's, tables, etc., 255 the the tooltip will grow. It will always enclose all of the content. 256 * @param inValue 257 */ 258 public TooltipJS setMaxWidth(int inValue) 259 { 260 if (inValue != mMaxWidth) 261 { 262 mMaxWidth = inValue; 263 mCachedJs = null; // Invalidate the cache. 264 } 265 return this; 266 } 267 268 //-------------------------------------------------------------------------- 269 public TooltipJS setShadowOffset(int inValue) 270 { 271 if (inValue != mShadowOffset) 272 { 273 mShadowOffset = inValue; 274 mCachedJs = null; // Invalidate the cache. 275 } 276 return this; 277 } 278 279 //-------------------------------------------------------------------------- 280 /** 281 Move the tooltip via onmousemove(). 282 */ 283 // Changing the value does not affect the cached js. 284 public TooltipJS setMouseMove(boolean inValue) 285 { 286 mAddOnMouseMove = inValue; 287 return this; 288 } 289 290 //-------------------------------------------------------------------------- 291 /** 292 * Tooltips can be added to any tag which supports onmouseover and onmouseout. 293 * You will also need to add generateJS() to the javascript in the page's <head> tag. 294 * @param inTag the tag to which the onmouseover and onmouseout attributes will 295 * be set to display a popup tooltip. 296 * @param inValue the text or HTML to display in the tooltip. 297 */ 298 public void addTooltip(XMLNode inTag, String inValue) 299 { 300// String safeString = StringUtil.replaceAll(inValue, "'", "\\'"); 301// String safeString = XMLUtil.escapeAttributeValue(inValue); 302 String safeString = StringUtil.replaceAll(inValue, "\n", "\\n"); 303 safeString = StringUtil.replaceAll(safeString, "\r", "\\r"); 304 safeString = StringUtil.replaceAll(safeString, "'", "'"); 305 safeString = StringUtil.replaceAll(safeString, "\"", """); 306 307 308 // Firefox (as of 3.0.*) still only recognized 'evt' and not 'event' 309 // Safari seems to recognize both. 310 String eventName = (inTag instanceof SvgNode ? "evt" : "event"); 311 312 String currentValue = inTag.getAttributeValue(HTML.ONMOUSEOVER); 313 inTag.setAttribute(HTML.ONMOUSEOVER, (currentValue != null ? currentValue + ";" : "") 314 + "showTooltip(" 315 + eventName + ", '" 316 + safeString + "');"); 317 318 if (mAddOnMouseMove) 319 { 320 currentValue = inTag.getAttributeValue(HTML.ONMOUSEMOVE); 321 inTag.setAttribute(HTML.ONMOUSEMOVE, (currentValue != null ? currentValue + ";" : "") 322 + "moveTooltip(" + eventName + ");"); 323 } 324 325 currentValue = inTag.getAttributeValue(HTML.ONMOUSEOUT); 326 inTag.setAttribute(HTML.ONMOUSEOUT, (currentValue != null ? currentValue + ";" : "") 327 + "hideTooltip();"); 328 } 329 330 //-------------------------------------------------------------------------- 331 /** 332 * Creates a tooltip using the tag's 'title' attribute as the tooltip text. 333 * @param inTag the tag to which the onmouseover and onmouseout attributes will 334 * be added in order to display the popup tooltip. 335 */ 336 public void addTitleTooltip(XMLNode inTag) 337 { 338 String currentValue = inTag.getAttributeValue(HTML.ONMOUSEOVER); 339 inTag.setAttribute(HTML.ONMOUSEOVER, (currentValue != null ? currentValue + ";" : "") 340 + "showTitleTooltip(event, this)"); 341 342 if (mAddOnMouseMove) 343 { 344 currentValue = inTag.getAttributeValue(HTML.ONMOUSEMOVE); 345 inTag.setAttribute(HTML.ONMOUSEMOVE, (currentValue != null ? currentValue + ";" : "") 346 + "moveTooltip(event)"); 347 } 348 349 currentValue = inTag.getAttributeValue(HTML.ONMOUSEOUT); 350 inTag.setAttribute(HTML.ONMOUSEOUT, (currentValue != null ? currentValue + ";" : "") 351 + "hideTitleTooltip()"); 352 } 353 354 //-------------------------------------------------------------------------- 355 public String generateJS() 356 { 357 if (null == mCachedJs) 358 { 359 Map<String, String> tokenSubstitutionMap = new HashMap<String, String>(); 360 tokenSubstitutionMap.put("TOOLTIP_DELAY", mDelay + ""); 361 tokenSubstitutionMap.put("TOOLTIP_XOFFSET", mXOffset + ""); 362 tokenSubstitutionMap.put("TOOLTIP_YOFFSET", mYOffset + ""); 363 tokenSubstitutionMap.put("TOOLTIP_BORDER", mBorder + ""); 364 tokenSubstitutionMap.put("TOOLTIP_FONT", mFont + ""); 365 tokenSubstitutionMap.put("TOOLTIP_FONT_SIZE", mFontSize + ""); 366 tokenSubstitutionMap.put("TOOLTIP_FONT_COLOR", mFontColor + ""); 367 tokenSubstitutionMap.put("TOOLTIP_BGCOLOR", mBgColor + ""); 368 tokenSubstitutionMap.put("TOOLTIP_PADDING", mPadding + ""); 369 tokenSubstitutionMap.put("TOOLTIP_MAX_WIDTH", mMaxWidth + ""); 370 tokenSubstitutionMap.put("TOOLTIP_SHADOW_COLOR", mShadowColor + ""); 371 tokenSubstitutionMap.put("TOOLTIP_SHADOW_OFFSET", mShadowOffset + ""); 372 373 mCachedJs = JsUtil.getJSResourceAsString("tooltip.js", tokenSubstitutionMap); 374 } 375 376 return mCachedJs; 377 } 378}