001package com.hfg.javascript;
002
003
004//------------------------------------------------------------------------------
005/**
006 * Repository of reusable javascript snippets.
007 * <div>
008 * The generateDomSearchJS() function produces the DOMSearch javascript which allows
009 * more flexible DOM element selection with search scoping capability.
010 * </div>
011 * <div>
012 * Ex: <span class='code'>DOMSearch(inElement).getElementsByTagNameAndAttribute(inTagName, inAttriubtePattern, inAttriubteValuePattern)</span>
013 * </div>
014 * <div>
015 * <ul>
016 *  <li><span class='code'>inElement</span> is the DOM Element object which is the root element from which to search.
017 *      [No argument defaults to <span class='code'>document</span>]</li>
018 *  <li><span class='code'>inTagName</span> is the tag name used to limit the search.
019 *      Use <span class='code'>'*'</span> to specify all tag types.</li>
020 *  <li><span class='code'>inAttributePattern</span> is the Pattern to use for matching
021 * to attribute names. <span class='code'>'width'</span> would match elements with a 'width'
022 * attribute but would also match 'shoeWidth' (matches are case insensitive). To return just
023 * elements containing a 'width' attribute, a pattern of <span class='code'>'^width$'</span>
024 * should be used.</li>
025 *  <li><span class='code'>inAttributeValuePattern</span> is the Pattern to use for matching
026 * to attribute values. [No argument defaults to <span class='code'>'.*'</span> which matches all values.]</li>
027 * </ul>
028 * </div>
029 * <div>
030 * Sometimes it would be nice to use the same id for more than element in the page but
031 * where the id would be unique within a portion of the page's DOM. While <span class='code'>getElementById()</span>
032 * is only available on the document object, <span class='code'>DOMSearch(inElement).getElementById(inId)</span>
033 * can be used to scope to only a portion of the DOM tree.
034 * </div>
035 * <div>
036 * The raw DOMSearch() javascript can be seen <a href='resources/DOMSearch.js' target='_parent'>here</a>.
037 * </div>
038 * <div>
039 * See <a href='doc-files/CommonJSTest.html' target='_parent'>this page</a> for some simple examples.
040 * </div>
041 * @author J. Alex Taylor, hairyfatguy.com
042 */
043//------------------------------------------------------------------------------
044// com.hfg XML/HTML Coding Library
045//
046// This library is free software; you can redistribute it and/or
047// modify it under the terms of the GNU Lesser General Public
048// License as published by the Free Software Foundation; either
049// version 2.1 of the License, or (at your option) any later version.
050//
051// This library is distributed in the hope that it will be useful,
052// but WITHOUT ANY WARRANTY; without even the implied warranty of
053// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
054// Lesser General Public License for more details.
055//
056// You should have received a copy of the GNU Lesser General Public
057// License along with this library; if not, write to the Free Software
058// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
059//
060// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
061// jataylor@hairyfatguy.com
062//------------------------------------------------------------------------------
063
064public class CommonJS
065{
066
067   //##########################################################################
068   // PRIVATE FIELDS
069   //##########################################################################
070
071   private static String sCachedBrowserDetectionJS;
072
073   //##########################################################################
074   // PUBLIC METHODS
075   //##########################################################################
076
077   //--------------------------------------------------------------------------
078   public static String generateBrowserDetectionJS()
079   {
080      if (null == sCachedBrowserDetectionJS)
081      {
082         initializeBrowserDetectionJS();
083      }
084
085      return sCachedBrowserDetectionJS;
086   }
087
088   //--------------------------------------------------------------------------
089   public static String generateDomSearchJS()
090   {
091      return JsUtil.getJSResourceAsString("DOMSearch.js");
092   }
093
094   //--------------------------------------------------------------------------
095   public static String generateXMLHttpRequestJS()
096   {
097      return JsUtil.getJSResourceAsString("XMLHttpRequester.js");
098   }
099
100   //##########################################################################
101   // PRIVATE METHODS
102   //##########################################################################
103
104
105   //--------------------------------------------------------------------------
106   private static void initializeBrowserDetectionJS()
107   {
108      StringBuffer js = new StringBuffer();
109
110      js.append("function Browser() {\n");
111      js.append("  var ua= navigator.userAgent;\n");
112      js.append("  this.ua = ua;\n");
113      js.append("  ua = ua.toLowerCase();\n");
114      js.append("\n");
115      js.append("  // DOM support?\n");
116      js.append("  this.isDOM1 = (Boolean(document.getElementById));\n");
117      js.append("  this.isDOM2Event = (Boolean(document.addEventListener)\n");
118      js.append("                      && Boolean(document.removeEventListener));\n");
119      js.append("  // CSS compatibility mode?\n");
120      js.append("  this.mode = document.compatMode ? document.compatMode : 'BackCompat';\n");
121      js.append("\n");
122      js.append("  // Browser name\n");
123      js.append("  this.isSafari    = (ua.indexOf('safari') != - 1);\n");
124      js.append("  this.isGecko     = (ua.indexOf('gecko') != -1 && !this.isSafari);\n");
125      js.append("  this.isMozilla   = (this.isGecko && ua.indexOf('gecko/') + 14 == ua.length);\n");
126      js.append("  this.isNS        = ( (this.isGecko) ? (ua.indexOf('netscape') != -1)\n");
127      js.append("                                       : ( (ua.indexOf('mozilla') != -1) \n");
128      js.append("                                           && (ua.indexOf('spoofer') == -1)\n");
129      js.append("                                           && (ua.indexOf('compatible') == -1)\n");
130      js.append("                                           && (ua.indexOf('opera') == -1)\n");
131      js.append("                                           && (ua.indexOf('safari') == -1)\n");
132      js.append("                                           && (ua.indexOf('webtv') == -1)\n");
133      js.append("                                           && (ua.indexOf('hotjava') == -1) ) );\n");
134      js.append("  this.isIE        = ( (ua.indexOf('msie') != -1)\n");
135      js.append("                      && (ua.indexOf('opera') == -1) \n");
136      js.append("                      && (ua.indexOf('webtv') == -1) );\n");
137      js.append("  this.isOpera     = (ua.indexOf('opera') != -1);\n");
138      js.append("  this.isKonqueror = (ua.indexOf('konqueror') != -1 && !this.isSafari);\n");
139      js.append("  this.isICab      = (ua.indexOf('icab') != -1);\n");
140      js.append("  this.isAOL       = (ua.indexOf('aol') != -1);\n");
141      js.append("  this.isOMNI      = (ua.indexOf('omni') != -1);\n");
142      js.append("\n");
143      js.append("  // Spoofing and compatible browsers\n");
144      js.append("  this.isIECompatible = ( (ua.indexOf('msie') != -1) && !this.isIE);\n");
145      js.append("  this.isNSCompatible = ( (ua.indexOf('mozilla') != -1) && !this.isNS && !this.isMozilla);\n");
146      js.append("\n");
147      js.append("  // Browser version\n");
148      js.append("  this.version = parseFloat(navigator.appVersion);\n");
149      js.append("\n");
150      js.append("  // correct version number\n");
151      js.append("  if (this.isNS && this.isGecko) {\n");
152      js.append("    this.version = parseFloat( ua.substring( ua.lastIndexOf('/') + 1 ) );\n");
153      js.append("  }\n");
154      js.append("  else if (this.isIE && this.version >= 4) {\n");
155      js.append("    this.version = parseFloat( ua.substring( ua.indexOf('msie ') + 5 ) );\n");
156      js.append("  }\n");
157      js.append("  else if (this.isMozilla) {\n");
158      js.append("    this.version = parseFloat( ua.substring( ua.indexOf('rv:') + 3 ) );\n");
159      js.append("  }\n");
160      js.append("  else if (this.isSafari) {\n");
161      js.append("    this.version = parseFloat( ua.substring( ua.lastIndexOf('/') + 1 ) );\n");
162      js.append("  }\n");
163      js.append("  else if (this.isOpera) {\n");
164      js.append("    if (ua.indexOf('opera/') != -1) {\n");
165      js.append("      this.version = parseFloat( ua.substring( ua.indexOf('opera/') + 6 ) );\n");
166      js.append("    }\n");
167      js.append("    else {\n");
168      js.append("      this.version = parseFloat( ua.substring( ua.indexOf('opera ') + 6 ) );\n");
169      js.append("    }\n");
170      js.append("  }\n");
171      js.append("  else if (this.isKonqueror) {\n");
172      js.append("    this.version = parseFloat( ua.substring( ua.indexOf('konqueror/') + 10 ) );\n");
173      js.append("  }\n");
174      js.append("  else if (this.isICab) {\n");
175      js.append("    if (ua.indexOf('icab/') != -1) {\n");
176      js.append("      this.version = parseFloat( ua.substring( ua.indexOf('icab/') + 6 ) );\n");
177      js.append("    }\n");
178      js.append("    else {\n");
179      js.append("      this.version = parseFloat( ua.substring( ua.indexOf('icab ') + 6 ) );\n");
180      js.append("    }\n");
181      js.append("  }\n");
182      js.append("\n");
183      js.append("  this.versionMajor = parseInt(this.version);\n");
184      js.append("  this.geckoVersion = ( (this.isGecko) ? ua.substring( (ua.lastIndexOf('gecko/') + 6), (ua.lastIndexOf('gecko/') + 14) ) : -1 );\n");
185      js.append("\n");
186      js.append("  // Platform\n");
187      js.append("  this.Win   = (ua.indexOf('win') != -1);\n");
188      js.append("  this.Win32 = (this.Win && ( ua.indexOf('95') != -1 || ua.indexOf('98') != -1 || ua.indexOf('nt') != -1 || ua.indexOf('win32') != -1 || ua.indexOf('32bit') != -1 || ua.indexOf('xp') != -1) );\n");
189      js.append("  this.MacOS = (ua.indexOf('mac') != -1);\n");
190      js.append("  this.Unix  = (ua.indexOf('unix') != -1 || ua.indexOf('sunos') != -1 || ua.indexOf('bsd') != -1 || ua.indexOf('x11') != -1);\n");
191      js.append("  this.Linux = (ua.indexOf('linux') != -1);\n");
192      js.append("\n");
193      js.append("  // Specific browser shortcuts\n");
194      js.append("  this.isNS4x = (this.isNS && this.versionMajor == 4);\n");
195      js.append("  this.isNS40x = (this.isNS4x && this.version < 4.5);\n");
196      js.append("  this.isNS47x = (this.isNS4x && this.version >= 4.7);\n");
197      js.append("  this.isNS4up = (this.isNS && this.version >= 4);\n");
198      js.append("  this.isNS6x = (this.isNS && this.versionMajor == 6);\n");
199      js.append("  this.isNS6up = (this.isNS && this.versionMajor >= 6);\n");
200      js.append("  this.isNS7x = (this.isNS && this.versionMajor == 7);\n");
201      js.append("  this.isNS7up = (this.isNS && this.versionMajor >= 7);\n");
202      js.append("\n");
203      js.append("  this.isIE4x = (this.isIE && this.versionMajor == 4);\n");
204      js.append("  this.isIE4up = (this.isIE && this.versionMajor >= 4);\n");
205      js.append("  this.isIE5x = (this.isIE && this.versionMajor == 5);\n");
206      js.append("  this.isIE55 = (this.isIE && this.version == 5.5);\n");
207      js.append("  this.isIE5up = (this.isIE && this.versionMajor >= 5);\n");
208      js.append("  this.isIE6x = (this.isIE && this.versionMajor == 6);\n");
209      js.append("  this.isIE6up = (this.isIE && this.versionMajor >= 6);\n");
210      js.append("\n");
211      js.append("  this.isIE4xMac = (this.isIE4x && this.isMacOS);\n");
212      js.append("\n");
213      js.append("  // To display all the fields in this object\n");
214      js.append("  this.write = writeMethod;\n");
215      js.append("\n");
216      js.append("  function writeMethod() {\n");
217      js.append("    document.writeln('<pre>');\n");
218      js.append("    for(var x in this)\n");
219      js.append("      // Print the value of ea. field (skipping methods).\n");
220      js.append("      if (!this[x].arguments)\n");
221      js.append("        document.writeln(padString('browser.' + x, 22) + ' = ' + this[x]);\n");
222      js.append("    document.writeln('<\\/pre>');\n");
223      js.append("  }\n");
224      js.append("\n");
225      js.append("  function padString(inString, targetLength) {\n");
226      js.append("    var spacesNeeded = targetLength - inString.length\n");
227      js.append("\n");
228      js.append("    for (var i = 0; i < spacesNeeded; i++) {\n");
229      js.append("      inString += ' '\n");
230      js.append("    }\n");
231      js.append("    return inString;\n");
232      js.append("  }\n");
233      js.append("}\n");
234      js.append("var browser = new Browser();\n");
235
236      sCachedBrowserDetectionJS = js.toString();
237   }
238
239   //--------------------------------------------------------------------------
240   private static void line(StringBuffer inBuffer, String inLine)
241   {
242      inBuffer.append(inLine + "\n");
243   }
244
245}