001package com.hfg.html; 002 003import com.hfg.xml.XMLComment; 004import com.hfg.xml.XMLCDATA; 005import com.hfg.util.mime.MimeType; 006import com.hfg.util.StringUtil; 007import com.hfg.xml.XMLNode; 008 009import java.nio.charset.Charset; 010 011//------------------------------------------------------------------------------ 012/** 013 * Represents a script (<script>) tag. 014 * 015 * @author J. Alex Taylor, hairyfatguy.com 016 */ 017//------------------------------------------------------------------------------ 018// com.hfg XML/HTML Coding Library 019// 020// This library is free software; you can redistribute it and/or 021// modify it under the terms of the GNU Lesser General Public 022// License as published by the Free Software Foundation; either 023// version 2.1 of the License, or (at your option) any later version. 024// 025// This library is distributed in the hope that it will be useful, 026// but WITHOUT ANY WARRANTY; without even the implied warranty of 027// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 028// Lesser General Public License for more details. 029// 030// You should have received a copy of the GNU Lesser General Public 031// License along with this library; if not, write to the Free Software 032// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 033// 034// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 035// jataylor@hairyfatguy.com 036//------------------------------------------------------------------------------ 037 038/* 039For XHTML or XML the script should be escaped like so: 040<script> 041 <![CDATA[ 042 ... unescaped script content ... 043 ]]> 044 </script> 045 046 However, older browser (such as IE5 on Mac) won't take kindly to this. 047 IE6 doesn't seem to like such escaping in returned AJAX content. 048*/ 049public class Script extends HTMLTag 050{ 051 private boolean mUseCDATA = true; 052 private XMLCDATA mCDATA; 053 054 //########################################################################## 055 // PUBLIC FIELDS 056 //########################################################################## 057 058 public static final String JAVASCRIPT = "JavaScript"; 059 public static final String JAVASCRIPT1_1 = "JavaScript1.1"; 060 public static final String JAVASCRIPT1_2 = "JavaScript1.2"; 061 public static final String JAVASCRIPT1_3 = "JavaScript1.3"; 062 public static final String VBSCRIPT = "VBScript"; 063 064 //########################################################################## 065 // CONSTRUCTORS 066 //########################################################################## 067 068 //-------------------------------------------------------------------------- 069 public Script() 070 { 071 super(HTML.SCRIPT); 072 // Force the use of a closing tag. Some browsers will barf if they see an 073 // empty script tag in the HTML. Not necessary for XHTML but oh, well. 074 setContent(""); 075 } 076 077 //-------------------------------------------------------------------------- 078 public Script(MimeType inType) 079 { 080 this(); 081 setType(inType); 082 } 083 084 //-------------------------------------------------------------------------- 085 public Script(String inContent) 086 { 087 this(); 088 addContent(inContent); 089 } 090 091 //-------------------------------------------------------------------------- 092 public Script(CharSequence inContent) 093 { 094 this(); 095 addContent(inContent); 096 } 097 098 //-------------------------------------------------------------------------- 099 public Script(XMLNode inXMLNode) 100 { 101 this(); 102 initFromXMLNode(inXMLNode); 103 } 104 105 //########################################################################## 106 // PUBLIC METHODS 107 //########################################################################## 108 109 //-------------------------------------------------------------------------- 110 /** 111 Defaults to true. 112 */ 113 public Script useCDATA(boolean inValue) 114 { 115 if (inValue != mUseCDATA) 116 { 117 String content = getContent(); 118 mUseCDATA = inValue; 119 120 if (! mUseCDATA) 121 { 122 clearSubtags(); 123 mCDATA = null; 124 } 125 126 setContent(content); 127 } 128 129 return this; 130 } 131 132 //-------------------------------------------------------------------------- 133 /** 134 Sets the script language. 135 @deprecated Use setType() - The 'language' attribute has been deprecated 136 in favor of 'type' in the html standard. 137 */ 138 public Script setLanguage(String inValue) 139 { 140 setAttribute(HTML.LANGUAGE, inValue); 141 142 return this; 143 } 144 145 //-------------------------------------------------------------------------- 146 /** 147 Sets the charset. 148 @param inValue the charset of the referenced script. 149 @return this Script object - for method chaining 150 */ 151 public Script setCharset(Charset inValue) 152 { 153 setAttribute(HTML.CHARSET, inValue.displayName()); 154 return this; 155 } 156 157 //-------------------------------------------------------------------------- 158 /** 159 Sets the script type. 160 */ 161 public Script setType(MimeType inValue) 162 { 163 return setType(inValue.toString()); 164 } 165 166 //-------------------------------------------------------------------------- 167 /** 168 Sets the script type. 169 */ 170 public Script setType(String inValue) 171 { 172 setAttribute(HTML.TYPE, inValue); 173 174 if (inValue != null 175 && inValue.equalsIgnoreCase(MimeType.TEXT_JAVASCRIPT.toString())) 176 { 177 // TODO: Is this necessary? 178 getCDATA().setHideWithCommentsForLegacyBrowsers(true); 179 } 180 181 return this; 182 } 183 184 //-------------------------------------------------------------------------- 185 /** 186 When set, this boolean attribute provides a hint to the user agent that the 187 script is not going to generate any document content (e.g., no "document.write" 188 in javascript) and thus, the user agent can continue parsing and rendering. 189 */ 190 public Script setDefer(boolean inValue) 191 { 192 setAttribute(HTML.DEFER, inValue); 193 194 return this; 195 } 196 197 //-------------------------------------------------------------------------- 198 /** 199 Specifies the location of an external script. 200 */ 201 public Script setSrc(String inValue) 202 { 203 setAttribute(HTML.SRC, inValue); 204 205 return this; 206 } 207 208 //-------------------------------------------------------------------------- 209 @Override 210 public Script setContent(CharSequence inContent) 211 { 212 clearContent(); 213 214 addContent(inContent); 215 216 return this; 217 } 218 219 //-------------------------------------------------------------------------- 220 public Script appendln(CharSequence inContent) 221 { 222 addContent(inContent + "\n"); 223 return this; 224 } 225 226 //-------------------------------------------------------------------------- 227 @Override 228 public Script addContent(CharSequence inContent) 229 { 230 if (StringUtil.isSet(inContent)) 231 { 232 if (mUseCDATA) 233 { 234 getCDATA().addContent(inContent); 235 } 236 else 237 { 238 super.addContentWithoutEscaping(inContent); 239 } 240 } 241 else 242 { 243 super.addContent(inContent); 244 } 245 246 return this; 247 } 248 249 //-------------------------------------------------------------------------- 250 @Override 251 public void clearContent() 252 { 253 if (mCDATA != null) mCDATA.clearContent(); 254 super.clearContent(); 255 } 256 257 //-------------------------------------------------------------------------- 258 @Override 259 public boolean hasContent() 260 { 261 boolean result = true; 262 if (mUseCDATA) 263 { 264 result = mCDATA != null && mCDATA.hasContent(); 265 } 266 else 267 { 268 result = super.hasContent(); 269 } 270 271 return result; 272 } 273 274 //-------------------------------------------------------------------------- 275 @Override 276 public String getContent() 277 { 278 String result = ""; 279 if (mUseCDATA) 280 { 281 if (mCDATA != null) result = mCDATA.getContent(); 282 } 283 else 284 { 285 result = super.getContent(); 286 } 287 288 return result; 289 } 290 291 //########################################################################## 292 // PRIVATE METHODS 293 //########################################################################## 294 295 //-------------------------------------------------------------------------- 296 private XMLCDATA getCDATA() 297 { 298 if (null == mCDATA) 299 { 300 XMLComment commentTag = new XMLComment("//"); 301 addSubtag(commentTag); 302 mCDATA = new XMLCDATA("\n"); 303 addSubtag(mCDATA); 304 } 305 306 return mCDATA; 307 } 308}