001package com.hfg.javascript; 002 003import java.awt.Color; 004import java.util.ArrayList; 005import java.util.HashMap; 006import java.util.List; 007import java.util.Map; 008 009import com.hfg.html.HTML; 010import com.hfg.html.HTMLTag; 011import com.hfg.html.Link; 012import com.hfg.html.attribute.HTMLColor; 013import com.hfg.util.StringBuilderPlus; 014import com.hfg.util.StringUtil; 015import com.hfg.xml.XMLUtil; 016 017//------------------------------------------------------------------------------ 018/** 019 Widget for creating a popup menu that can be used in an href attribute (a link 020 or an Area object) or an onclick() handler. 021 <p> 022 See <a href='doc-files/PopupMenuJSTest.html' target='_parent'>this page</a> for examples. 023 </p> 024 <pre> 025 HTMLDoc doc = new HTMLDoc(); 026 doc.setDoctype(Doctype.XHTML_1_0_TRANSITIONAL); 027 HTML html = new HTML("PopupMenuJS Test"); 028 doc.setRootTag(html); 029 030 Body body = html.getBody(); 031 032 body.br(3); 033 034 // Add the CSS classes needed 035 html.getHead().addStyle(PopupMenuJS.generateCommonCSS()); 036 // Add the javascript needed 037 html.getHead().addJavascript(PopupMenuJS.generateCommonJavascript()); 038 039 PopupMenuJS menu3 = new PopupMenuJS(); 040 menu3.setMenuTitle("Test Menu #2"); 041 menu3.addLink(new Link("http://localhost.com/URL7", "Nifty Site")); 042 menu3.addLink(new Link("URL8", "Click Me!")); 043 menu3.addLink(new Link()); 044 menu3.addLink(new Link("javascript:alert('Hello World!');", "Hello World!")); 045 // Add the menu definition to the page's javascript 046 html.getHead().addJavascript(menu3.generateMenuJavascript()); 047 // Attach the menu to the desired tag 048 menu3.attachToTag(body.addLink("javascript:void(0)", "Link Example")); 049 050 </pre> 051 @author J. Alex Taylor, hairyfatguy.com 052 */ 053//------------------------------------------------------------------------------ 054// com.hfg XML/HTML Coding Library 055// 056// This library is free software; you can redistribute it and/or 057// modify it under the terms of the GNU Lesser General Public 058// License as published by the Free Software Foundation; either 059// version 2.1 of the License, or (at your option) any later version. 060// 061// This library is distributed in the hope that it will be useful, 062// but WITHOUT ANY WARRANTY; without even the implied warranty of 063// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 064// Lesser General Public License for more details. 065// 066// You should have received a copy of the GNU Lesser General Public 067// License along with this library; if not, write to the Free Software 068// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 069// 070// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 071// [email protected] 072//------------------------------------------------------------------------------ 073 074public class PopupMenuJS 075{ 076 private String mMenuId; 077 private List<Link> mLinks; 078 private String mTitle; 079 private boolean mPin; 080 081 private static String sFont = "Arial,sans-serif"; 082 private static String sFontSize = ".8em"; 083 private static boolean sDefaultPin = false; 084 private static HTMLColor sMenuColor = new HTMLColor(Color.decode("#99ffff")); 085 private static HTMLColor sHeaderColor = new HTMLColor(Color.decode("#000066")); 086 private static String sCachedJs; 087 private static String sCachedCss; 088 089 private static int sIndex = 1; 090 091 //########################################################################## 092 // CONSTRUCTORS 093 //########################################################################## 094 095 //-------------------------------------------------------------------------- 096 public PopupMenuJS() 097 { 098 super(); 099 mMenuId = "_HfgPopup" + sIndex++; 100 setPin(sDefaultPin); 101 } 102 103 //########################################################################## 104 // PUBLIC METHODS 105 //########################################################################## 106 107 //-------------------------------------------------------------------------- 108 public static void setFont(String inValue) 109 { 110 sFont = inValue; 111 sCachedCss = null; 112 } 113 114 //-------------------------------------------------------------------------- 115 public static void setFontSize(String inValue) 116 { 117 sFont = inValue; 118 sCachedCss = null; 119 } 120 121 //-------------------------------------------------------------------------- 122 public static void setDefaultPin(boolean inValue) 123 { 124 sDefaultPin = inValue; 125 } 126 127 //-------------------------------------------------------------------------- 128 /** 129 Specify whether or not to 'pin' the menu once it is opened. 130 */ 131 public PopupMenuJS setPin(boolean inValue) 132 { 133 mPin = inValue; 134 return this; 135 } 136 137 //-------------------------------------------------------------------------- 138 public static void setDefaultMenuColor(Color inValue) 139 { 140 sMenuColor = new HTMLColor(inValue); 141 sCachedCss = null; 142 } 143 144 //-------------------------------------------------------------------------- 145 public static void setDefaultHeaderColor(Color inValue) 146 { 147 sHeaderColor = new HTMLColor(inValue); 148 sCachedCss = null; 149 } 150 151 //-------------------------------------------------------------------------- 152 public static String generateCommonCSS() 153 { 154 if (null == sCachedCss) 155 { 156 Map<String, String> tokenSubstitutionMap = new HashMap<String, String>(); 157 tokenSubstitutionMap.put("FONT", sFont); 158 tokenSubstitutionMap.put("FONT_SIZE", sFontSize); 159 tokenSubstitutionMap.put("HEADER_COLOR", sHeaderColor.toString()); 160 tokenSubstitutionMap.put("MENU_COLOR", sMenuColor.toString()); 161 162 sCachedCss = JsUtil.getJSResourceAsString("popupMenu.css", tokenSubstitutionMap); 163 } 164 165 return sCachedCss; 166 } 167 168 //-------------------------------------------------------------------------- 169 /** 170 Generates the generic javascript methods for creating a popup menu. 171 */ 172 public static synchronized String generateCommonJavascript() 173 { 174 if (null == sCachedJs) 175 { 176 Map<String, String> tokenSubstitutionMap = new HashMap<String, String>(); 177 178 sCachedJs = JsUtil.getJSResourceAsString("popupMenu.js", tokenSubstitutionMap); 179 } 180 181 return sCachedJs; 182 } 183 184 //-------------------------------------------------------------------------- 185 public String getDisplayMenuJavascript() 186 { 187 return "javascript:hfg.js.PopupMenu.display(event, " + mMenuId + ");"; 188 } 189 //-------------------------------------------------------------------------- 190 /** 191 * Popup menus can be added to any tag which supports onmouseover and onmouseout. 192 * You will also need to add generateJS() to the javascript in the page's <head> tag. 193 * @param inTag the tag to which the onclick() or onmouseover() attribute will 194 * be set to display a menu. 195 */ 196 public void attachToTag(HTMLTag inTag) 197 { 198 String currentValue = inTag.getAttributeValue(HTML.ONCLICK); 199 inTag.setAttribute(HTML.ONCLICK, 200 (currentValue != null ? currentValue + ";" : "") + "hfg.js.PopupMenu.display(event, " + mMenuId + ")"); 201 202// currentValue = inTag.getAttributeValue(HTML.CLASS); 203// inTag.setAttribute(HTML.CLASS, (currentValue != null ? currentValue + " " : "") + "hoverboard"); 204 } 205 206 //-------------------------------------------------------------------------- 207 public PopupMenuJS setMenuTitle(String inValue) 208 { 209 mTitle = inValue; 210 return this; 211 } 212 213 //-------------------------------------------------------------------------- 214 /** 215 Add a link to the popup menu. 216 */ 217 public PopupMenuJS addLink(Link inLink) 218 { 219 if (inLink != null) 220 { 221 if (null == mLinks) mLinks = new ArrayList<Link>(); 222 mLinks.add(inLink); 223 } 224 return this; 225 } 226 227 //-------------------------------------------------------------------------- 228 /** 229 Add a divider to the popup menu. 230 */ 231 public PopupMenuJS addDivider() 232 { 233 if (null == mLinks) mLinks = new ArrayList<Link>(); 234 mLinks.add(new Link()); 235 236 return this; 237 } 238 239 //-------------------------------------------------------------------------- 240 /** 241 Add a divider to the popup menu. 242 */ 243 public PopupMenuJS addDivider(String inTitle) 244 { 245 if (null == mLinks) mLinks = new ArrayList<Link>(); 246 mLinks.add(new Link("", inTitle)); 247 248 return this; 249 } 250 251 //--------------------------------------------------------------------------- 252 public String generateMenuJavascript() 253 { 254 StringBuilderPlus buffer = new StringBuilderPlus(); 255/* 256 buffer.appendln("var " + mMenuId + " = ["); 257 258 if (mTitle != null) 259 { 260 buffer.appendln("['title', " + StringUtil.singleQuote(XMLUtil.escapeApos(mTitle)) + "],"); 261 } 262 263 buffer.appendln("['pin', " + (mPin ? "1" : "0") + "],"); 264 265 if (mLinks != null) 266 { 267 for (int i = 0; i < mLinks.size(); i++) 268 { 269 Link link = mLinks.get(i); 270 if (StringUtil.isSet(link.getURL())) 271 { 272 buffer.append("['link', '" + link.getContent() + "', '" + link.getURL() + "']"); 273 } 274 else 275 { 276 buffer.append("['divider'" + (StringUtil.isSet(link.getContent()) ? ", '" + link.getContent() + "'" : "") + "]"); 277 } 278 279 buffer.appendln((i < mLinks.size() - 1 ? "," : "")); 280 } 281 } 282 283 buffer.appendln("]"); 284*/ 285 286 buffer.append("var " + mMenuId + " = { 'config': {"); 287 buffer.append("'pin': " + StringUtil.singleQuote(mPin ? "1" : "0")); 288 if (StringUtil.isSet(mTitle)) 289 { 290 buffer.append(", 'title': " + StringUtil.singleQuote(XMLUtil.escapeApos(mTitle))); 291 } 292 293 buffer.appendln("}, 'content': ["); 294 295 if (mLinks != null) 296 { 297 for (int i = 0; i < mLinks.size(); i++) 298 { 299 Link link = mLinks.get(i); 300 if (StringUtil.isSet(link.getURL())) 301 { 302// buffer.append("['link', '" + link.getContent() + "', '" + link.getURL() + "']"); 303 link = (Link) link.clone(); 304 link.setContent("• " + link.getContent()); 305 link.addClass("hfgmenu"); 306 buffer.append("['link', '" + StringUtil.replaceAll(link.toHTML(), "'", "\\'") + "']"); 307 } 308 else 309 { 310 buffer.append("['divider'" + (StringUtil.isSet(link.getContent()) ? ", '" + link.getContent() + "'" : "") + "]"); 311 } 312 313 buffer.appendln((i < mLinks.size() - 1 ? "," : "")); 314 } 315 } 316 317 buffer.appendln("]}"); 318 319 return buffer.toString(); 320 } 321}