PageSourceSearch

https://www.uprrmuseum.org/cs/resources/sitestudio/ssajax/ssajax.js

js uprrmuseum.org collected 2026-09-24 09:22:59 UTC 27,372 bytes, 740 lines download raw bytes

1/////////////////////////////////////////////////////////////////////////////
2// 
3// Solution  : SiteStudio
4// Project   : Site Studio Ajax Library (SSAjax)
5//
6// FileName  : ssajax.js
7// FileType  : Javascript
8// Author    : Jake Gordon
9// Created   : January 2006
10// Version   : 11gR1+ (11.1.1.9.0)
11//
12// Comments  : 
13//
14// Copyright : Oracle, Incorporated Confidential and Proprietary
15//
16//             This computer program contains valuable, confidential and proprietary
17//             information. Disclosure, use, or reproduction without the written
18//             authorization of Stellent is prohibited. This unpublished
19//             work by Stellent is protected by the laws of the United States
20//             and other countries. If publication of the computer program should occur,
21//             the following notice shall apply:
22//
23//             Copyright (c) 1997-2001 IntraNet Solutions, Incorporated. All rights reserved.
24//             Copyright (c) 2001-2007 Stellent, Incorporated. All rights reserved.
25//             Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
26//
27/////////////////////////////////////////////////////////////////////////////
28
29SSAjax = new Object(); // namespace object
30SSAjax.XML = new Object(); // namespace object
31
32SSAjax.Strings = new Array(); // localized strings array (will be populated by loading locale specific ssajax.strings.js file)
33
34//***************************************************************************
35//***************************************************************************
36//************************** ENVIRONMENT VARIABLES **************************
37//***************************************************************************
38//***************************************************************************
39
40SSAjax.IS_OPERA = (navigator.userAgent.toLowerCase().indexOf("opera") > -1);
41SSAjax.IS_FIREFOX = (navigator.userAgent.toLowerCase().indexOf("gecko") > -1) && (navigator.userAgent.toLowerCase().indexOf("firefox") > -1);
42SSAjax.IS_NETSCAPE = (navigator.userAgent.toLowerCase().indexOf("gecko") > -1) && (navigator.userAgent.toLowerCase().indexOf("netscape") > -1);
43SSAjax.IS_SAFARI = ((navigator.userAgent.toLowerCase().indexOf("applewebkit") > -1) || (navigator.userAgent.toLowerCase().indexOf("apple") > -1));
44SSAjax.IS_IE = ((navigator.userAgent.toLowerCase().indexOf("msie") > -1) || (navigator.userAgent.toLowerCase().indexOf("trident/") > -1)) && !SSAjax.IS_OPERA;
45SSAjax.IS_IE11 = SSAjax.IS_IE && (navigator.userAgent.toLowerCase().indexOf("msie") < 0);
46
47SSAjax.IS_MOZILLA = (navigator.userAgent.toLowerCase().indexOf("mozilla") > -1) && !SSAjax.IS_IE && !SSAjax.IS_OPERA && !SSAjax.IS_FIREFOX && !SSAjax.IS_NETSCAPE;
48
49SSAjax.IS_WINDOWS = (navigator.platform.toLowerCase().indexOf('win') > -1);
50SSAjax.IS_MAC = (navigator.platform.toLowerCase().indexOf('mac') > -1);
51SSAjax.IS_LINUX = (navigator.platform.toLowerCase().indexOf('linux') > -1);
52
53SSAjax.IS_STRICT = (document.compatMode == 'CSS1Compat');
54SSAjax.IS_QUIRKS = (document.compatMode == 'BackCompat');
55
56SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL1 = document.implementation && document.implementation.hasFeature;
57SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL2 = document.implementation && document.implementation.createDocument;
58SSAjax.HAS_DOM_XPATH_LEVEL3 = SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL1 && document.implementation.hasFeature("XPath", "3.0");
59
60//***************************************************************************
61//***************************************************************************
62//************************ JAVASCRIPT TYPE UTILITIES ************************
63//***************************************************************************
64//***************************************************************************
65
66var _U = "undefined";
67
68SSAjax.IsString = function(obj) { return (typeof obj == 'string'); }
69SSAjax.IsNumber = function(obj) { return (typeof obj == 'number'); }
70SSAjax.IsBoolean = function(obj) { return (typeof obj == 'boolean'); }
71SSAjax.IsArray = function(obj) { return (obj instanceof Array); }
72SSAjax.IsFunction = function(obj) { return (typeof obj == 'function'); }
73SSAjax.IsUndefined = function(obj) { return (typeof obj == 'undefined'); }
74SSAjax.IsNull = function(obj) { return (obj == null); }
75SSAjax.IsNotValid = function(obj) { return (SSAjax.IsNull(obj) || SSAjax.IsUndefined(obj)); }
76SSAjax.IsValid = function(obj) { return (!SSAjax.IsNull(obj) && !SSAjax.IsUndefined(obj)); }
77
78SSAjax.ToBool = function(obj, def)
79{
80    if (SSAjax.IsValid(obj))
81    {
82        return ((obj == 1) || (obj == true) || (obj == "1") || (obj.toString().toLowerCase() == "true") || (
82obj.toString().toLowerCase() == 'yes'));
83    }
84    
85    return (SSAjax.IsBoolean(def) ? def : false);
86};
87
88SSAjax.ToInt = function(obj, def)
89{
90    if (SSAjax.IsValid(obj))
91    {
92        var x = parseInt(obj);
93        if (!isNaN(x))
94        {
95            return x;
96        }
97    }
98
99    return (SSAjax.IsNumber(def) ? def : 0);
100}
101
102SSAjax.ToString = function(obj, def)
103{
104    if (SSAjax.IsValid(obj))
105    {
106        return obj.toString();
107    }
108    
109    return (SSAjax.IsString(def) ? def : '');
110}
111
112//***************************************************************************
113//***************************************************************************
114//************************ X-BROWSER IMPLEMENTATIONS ************************
115//***************************************************************************
116//***************************************************************************
117
118//
119// x-browser way to create a blank XML DOM Document
120//
121if (SSAjax.IS_IE && SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL2)
122{
123    SSAjax.CreateXMLDocument = function() { return document.implementation.createDocument("", "", null); }
124}
125
126if (SSAjax.IS_IE) // Always use the ActiveX
127{
128    SSAjax.CreateXMLDocument = function() { return new ActiveXObject("Msxml2.DOMDocument"); }
129}
130
131//
132// if NodeType enumeration doesn't exist, then provide it
133//
134if(!window.Node || !Node.ELEMENT_NODE)
135{
136    var Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5,  ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12};
137};
138
139//
140// if XMLHttpRequest is not implemented, but this is IE, then provide our own XMLHttpRequest using MSXML
141//
142if (!window.XMLHttpRequest && SSAjax.IS_IE)
143{
144    XMLHttpRequest = function() { return new ActiveXObject("Msxml2.XMLHTTP"); }
145}
146
147//
148// if XMLSerializer is not implemented, but I can create a DOM Document that has an .xml property, then provide our own XMLSerializer
149//
150if (!window.XMLSerializer && SSAjax.CreateXMLDocument && ("xml" in SSAjax.CreateXMLDocument()))
151{
152    XMLSerializer = function(){};
153    XMLSerializer.prototype.serializeToString = function(oNode) { return oNode.xml; };
154}
155
156//***************************************************************************
157
158window.getXMLSerializer = function(){};
159window.getXMLSerializer.prototype.serializeToString = function(oNode)
160{
161	if (SSAjax.IS_IE)
162	{
163		return oNode.xml;
164	}
165	else
166	{
167		return (new XMLSerializer()).serializeToString(oNode);
168	}
169};
170
171//
172// if DOMParser does not exist, but I can create a DOM Document that has a .loadXML method, then provide our own DOMParser
173//
174
175SSAjax.ParseXmlFromString = function(xml, contentType)
176{
177   var doc = SSAjax.CreateXMLDocument();
178   doc.resolveExternals = false;
179   doc.loadXML(xml);
180
181   // Some versions of the MSXML parser (namely MSXML3) will use zero-based
182   // indexing for its xpath expressions (contrary to the xpath spec) unless
183   // you set the "SelectionLanguage" to "XPath".  For example the expression:
184   //     foo[1]
185   // would actually return the second foo element instead of the first.
186	if ("setProperty" in doc)
187	{
188		doc.setProperty("SelectionLanguage", "XPath");
189	}
190
191   return doc;
192};
193
194//***************************************************************************
195
196if (!window.DOMParser && SSAjax.CreateXMLDocument && ("loadXML" in SSAjax.CreateXMLDocument()))
197{
198    DOMParser = function() {};
199    DOMParser.prototype.parseFromString = function(xml, contentType)
200    {
201        return SSAjax.ParseXmlFromString(xml, contentType);
202    }
203}
204
205//***************************************************************************
206
207window.getDOMParser = function() {};
208window.getDOMParser.prototype.parseFromString = function(xml, contentType)
209{
210	if (window.DOMParser && SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL2 && !("selectNodes" in document.implementation.createDocument("", "", null)))
211	{
212		return SSAjax.ParseXmlFromString(xml, contentType);
213	}
214	else
215	{
216		return (new DOMParser()).parseFromString(xml, contentType);
217	}
218};
219
220//***************************************************************************
221
222//
223// provide our own Node.selectNodes() method if necessary
224//
225if (SSAjax.CreateXMLDocument && ("selectNodes" in SSAjax.CreateXMLDocument()))
226{
227    SSAjax.HAS_SELECT_NODES = true; // most likely IE
228}
229else if (SSAjax.HAS_DOM_XPATH_LEVEL3)
230{
231    SSAjax.HAS_SELECT_NODES = true; // most likely MOZILLA
232    
233    XMLDocument.prototype.selectNodes = Node.prototype.selectNodes = function(expr)
234    {
235        var doc = (this.ownerDocument ? this.ownerDocument : this);
236        var nsResolver = doc._namespaces ? function(prefix) { return doc._namespaces[prefix]; } 
237                                                : doc.createNSResolver(doc.documentElement);
238
239        var nodes = doc.evaluate(expr, this, nsResolver, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
240
241        var nodelist = new Array();
242        while (node = nodes.iterateNext()) { nodelist.push(node); }
243        return nodelist;
244    }
245
246    XMLDocument.prototype.selectSingleNode = Node.prototype.selectSingleNode = function(expr)
247    {
248        var nodeList = this.selectNodes("(" + expr + ")[1]"); // only need the first matching node (xpath uses 1-based offsets)
249        if (nodeList.length > 0)
250            return nodeList[0];
251        else
252            return null;
253    }
254}
255else
256{
257    SSAjax.HAS_SELECT_NODES = false;
258}
259
260//***************************************************************************
261//***************************************************************************
262//******************************* XML METHODS *******************************
263//***************************************************************************
264//***************************************************************************
265
266SSAjax.XML.SetXPathNamespaces = function(dom, ns)
267{
268    if (SSAjax.IS_IE)
269    {
270        dom.setProperty("SelectionLanguage", "XPath");
271        dom.setProperty("SelectionNamespaces", ns);
272    }
273    else
274    {
275        // store all prefix:uri pairs in an array in the DOM object for use during .selectSingleNode / .selectNodes() methods
276        var namespaces = ns.indexOf(" ") > -1 ? ns.split(" ") : new Array(ns);
277        dom._namespaces = new Array(namespaces.length);
278        for (var i = 0 ; i < namespaces.length ; i++)
279        {
280            var thisNamespace = namespaces[i];
281            var colonPos = thisNamespace.indexOf(":");
282            var assignPos = thisNamespace.indexOf("=");
283            if (colonPos == 5 && assignPos > colonPos+2)
284            {
285                var prefix = thisNamespace.substring(colonPos+1, assignPos);
286                var uri = thisNamespace.substring(assignPos+2, thisNamespace.length-1);
287                dom._namespaces[prefix] = uri;
288            }
289        }
290    }
291}
292
293SSAjax.XML.GetPreviousSiblingElement = function(domNode)
294{
295    var n = domNode.previousSibling;
296    while (SSAjax.IsValid(n) && (n.nodeType != Node.ELEMENT_NODE))
297    {
298        n = n.previousSibling;
299    }
300    return n;
301}
302
303SSAjax.XML.GetNextSiblingElement = function(domNode)
304{
305    var n = domNode.nextSibling;
306    while (SSAjax.IsValid(n) && (n.nodeType != 1/*Node.ELEMENT_NODE*/))
307        n = n.nextSibling;
308    return n;
309}
310
311SSAjax.XML.GetNextOrPreviousOrParentElement = function(domNode)
312{
313    var next = SSAjax.XML.GetNextSiblingElement(domNode);
314    if (SSAjax.IsValid(next))
315        return next;
316
317    var previous = SSAjax.XML.GetPreviousSiblingElement(domNode);
318    if (SSAjax.IsValid(previous))
319        return previous;
320        
321    return domNode.parentNode;
322}
323
324//***************************************************************************
325//***************************************************************************
326//***************************** STRING METHODS ******************************
327//***************************************************************************
328//***************************************************************************
329
330String.prototype.StripCharacters = function(badchars)
331{
332    // build up regular expression [\a\b\c\d\e] (assuming str = "abcde")
333    var test = new Array();
334    test.push('[');
335    for (var i = 0 ; i < badchars.length ; i++)
336    {
337        test.push('\\');
338        test.push(badchars.charAt(i));
339    }
340    test.push(']');
341    return this.replace(new RegExp(test.join(''), 'gi'), '');
342}
343
344String.prototype.FindOneOf = function(str)
345{
346    for (var i = 0 ; i < str.length ; i++)
347    {
348        var pos = this.indexOf(str.charAt(i));
349        if (pos > -1)
350            return pos;
351    }
352    return -1;
353}
354
355String.CompareNoCase = function(str1, str2)
356{
357    return (SSAjax.IsString(str1) && SSAjax.IsString(str2) && (str1.toLowerCase() == str2.toLowerCase()));
358}
359
360String.Trim = function(str)
361{ 
362    return str.replace(/^\s*/, '').replace(/\s*$/, ''); 
363} 
364
365//***************************************************************************
366//***************************************************************************
367//***************************** ARRAY METHODS *******************************
368//***************************************************************************
369//***************************************************************************
370
371Array.prototype.RemoveAt = function(index)
372{
373    return this.slice(0, index).concat(this.slice(index+1));
374} 
375
376//***************************************************************************
377//***************************************************************************
378//***************************** UTILITY METHODS *****************************
379//***************************************************************************
380//***************************************************************************
381
382SSAjax.Escape = function(sXml)
383{
384    if (sXml)
385    {
386        return sXml.replace(/&/g, "&amp;")
387                   .replace(/</g, "&lt;")
388                    .replace(/>/g, "&gt;")
389                    .replace(/"/g, "&quot;")
390                    .replace(/'/g, "&apos;");
391    }
392    else
393    {
394        return "";
395    }
396}
397
398SSAjax.Unescape = function(sXml)
399{
400    if (sXml)
401    {
402        return sXml.replace(/&apos;/g,"'")
403                    .replace(/&quot;/g,"\"")
404                    .replace(/&gt;/g,">")
405                    .replace(/&lt;/g,"<")
406                    .replace(/&amp;/g,"&");
407    }
408    else
409    {
410        return "";
411    }
412}
413
414//***************************************************************************
415
416SSAjax.Serialize = function(obj)
417{
418    if (obj)
419    {
420        if (obj.innerHTML)
421        {
422            return obj.innerHTML;
423        }
424        else if (XMLSerializer)
425        {
426            return (new getXMLSerializer()).serializeToString(obj);
427        }
428        else if (obj.toString)
429        {
430            return obj.toString();
431        }
432    }
433
434    return "";
435}
436
437//***************************************************************************
438
439SSAjax.GetUrlHash = function()
440{
441    var pos = document.location.hash.indexOf('#');
442    if (pos >= 0)
443        return document.location.hash.substr(pos+1);
444    else
445        return document.location.hash;
446}
447
448SSAjax.SetUrlHash = function(value)
449{
450    document.location.hash = value;
451}
452
453//***************************************************************************
454//***************************************************************************
455//************************* EASY STARTUP METHODS ****************************
456//***************************************************************************
457//***************************************************************************
458
459SSAjax.Startup = function(features, init, uninit, userLanguageId)
460{
461    SSAjax.userLanguageId = SSAjax.ToString(userLanguageId, 'en');
462
463    if (!SSAjax.IsValid(SSAjax.Startup.features))
464    {
465        SSAjax.Startup.features = (SSAjax.IsValid(features) ? features : SSAjax.Features.NONE);
466        SSAjax.Startup.init = new Array(init);
467        SSAjax.Startup.uninit = new Array(uninit);
468    }
469    else
470    {
471        SSAjax.Startup.features = SSAjax.Startup.features | (SSAjax.IsValid(features) ? features : SSAjax.Features.NONE);
472        SSAjax.Startup.init.push(init);
473        SSAjax.Startup.uninit.push(uninit);
474    }
475        
476    if (window.addEventListener)
477    {
478        window.addEventListener('load', SSAjax.Initialize, false);
479        window.addEventListener('unload', SSAjax.Uninitialize, false);
480    }
481    else if (window.attachEvent)
482    {
483        window.attachEvent('onload', SSAjax.Initialize);
484        window.attachEvent('onunload', SSAjax.Uninitialize);
485    }
486    else
487    {
488        window['onload'] = SSAjax.Initialize;
489        window['onunload'] = SSAjax.Uninitialize;
490    }
491}
492
493SSAjax.Initialize = function()
494{
495    if (SSAjax.IsValid(SSAjax.Startup.features) && (SSAjax.Startup.features != SSAjax.Features.NONE))
496    {
497        SSAjax.LoadFeatures(SSAjax.Startup.features, SSAjax.Initialize2);
498    }
499    else
500    {
501        SSAjax.Initialize2();
502    }
503}
504SSAjax.Initialize2 = function()
505{    
506    for (var i = 0 ; i < SSAjax.Startup.init.length ; i++)
507        if (SSAjax.IsValid(SSAjax.Startup.init[i]))
508            SSAjax.Startup.init[i]();
509}
510
511SSAjax.Uninitialize = function()
512{
513    for (var i = 0 ; i < SSAjax.Startup.uninit.length ; i++)
514        if (SSAjax.IsValid(SSAjax.Startup.uninit[i]))
515            SSAjax.Startup.uninit[i]();
516}
517
518//***************************************************************************
519//***************************************************************************
520//******************** DYNAMIC FEATURE LOADING METHODS **********************
521//***************************************************************************
522//***************************************************************************
523
524SSAjax.Features = {
525    NONE: 0,
526    DOMDRAG: 1,
527    HTTP: 1,
528    IDC: 2,
529    DHTML: 4,
530    DHTML_PROGRESSBAR: 8,
531    DHTML_MESSAGEBOX: 16,
532    DHTML_COMBOBOX: 32,
533    DHTML_TREECTRL: 64,
534    DHTML_TABCTRL: 128,
535    DHTML_MENU: 256,
536    DHTML_CONSOLE: 512,
537
538    ALL: 1+2+4+8+16+32+64+128+256+512
539};
540
541SSAjax.IsFeatureSet = function(features, feature) { return ((features & feature) == feature); }
542SSAjax.IsFeatureOn = function(feature)
543{
544    switch(feature)
545    {
546        case SSAjax.Features.NONE:              return true;
547        case SSAjax.Features.DOMDRAG:           return (typeof Drag != _U) && SSAjax.IsValid(Drag);
548        case SSAjax.Features.HTTP:              return SSAjax.IsValid(SSAjax.Http);
549        case SSAjax.Features.IDC:               return SSAjax.IsValid(SSAjax.Idc);
550        case SSAjax.Features.DHTML:             return SSAjax.IsValid(SSAjax.DHTML);
551        case SSAjax.Features.DHTML_PROGRESSBAR: return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.ProgressBar);
552        case SSAjax.Features.DHTML_MESSAGEBOX:  return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.MessageBox);
553        case SSAjax.Features.DHTML_COMBOBOX:    return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.ComboBox);
554        case SSAjax.Features.DHTML_TREECTRL:    return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.TreeCtrl);
555        case SSAjax.Features.DHTML_TABCTRL:     return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.TabCtrl);
556        case SSAjax.Features.DHTML_MENU:        return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.Menu);
557        case SSAjax.Features.DHTML_CONSOLE:     return SSAjax.IsValid(SSAjax.DHTML) && SSAjax.IsValid(SSAjax.DHTML.Console);
558    }
559    
560    return false;
561}
562SSAjax.IsFeatureSetButNotOn = function(features, feature) { return SSAjax.IsFeatureSet(features, feature) && !SSAjax.IsFeatureOn(feature); }
563
564
565SSAjax.LoadFeatures = function(features, callback)
566{
567    if (SSAjax.IsFeatureSet(features, SSAjax.Features.IDC))
568    {
569        features = (features | SSAjax.Features.HTTP);
570    }
571    
572    if (SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_PROGRE
572SSBAR) ||
573        SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_MESSAGEBOX) ||
574        SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_COMBOBOX) ||
575        SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_TREECTRL) ||
576        SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_TABCTRL) ||
577        SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_MENU) ||
578        SSAjax.IsFeatureSet(features, SSAjax.Features.DHTML_CONSOLE))
579    {
580        features = (features | SSAjax.Features.DHTML);
581    }
582    
583    SSAjax.path = SSAjax.GetPathToScript('ssajax.js');
584    
585    var scripts = new Array();
586    
587    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.HTTP)) scripts.push(SSAjax.path + 'ssajax.http.js');
588    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.IDC)) scripts.push(SSAjax.path + 'ssajax.idc.js');
589    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML)) scripts.push(SSAjax.path + 'ssajax.dhtml.js');
590    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_PROGRESSBAR)) scripts.push(SSAjax.path + 'ssajax.dhtml.progressbar.js');
591    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_MESSAGEBOX)) scripts.push(SSAjax.path + 'ssajax.dhtml.messagebox.js');
592    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_COMBOBOX)) scripts.push(SSAjax.path + 'ssajax.dhtml.combobox.js');
593    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_TREECTRL)) scripts.push(SSAjax.path + 'ssajax.dhtml.treectrl.js');
594    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_TABCTRL)) scripts.push(SSAjax.path + 'ssajax.dhtml.tabctrl.js');
595    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_MENU)) scripts.push(SSAjax.path + 'ssajax.dhtml.menu.js');
596    if (SSAjax.IsFeatureSetButNotOn(features, SSAjax.Features.DHTML_CONSOLE)) scripts.push(SSAjax.path + 'ssajax.dhtml.console.js');
597
598    if (SSAjax.IsNotValid(SSAjax.Strings.language))
599    {
600        scripts.push(SSAjax.path + 'lang/en/ssajax.strings.js');
601        scripts.push(SSAjax.path + 'lang/' + SSAjax.userLanguageId + '/ssajax.strings.js');
602    }
603
604    if (scripts.length > 0)
605        SSAjax.LoadMultipleScripts(scripts, callback);
606    else
607        callback();
608}
609
610//***************************************************************************
611//***************************************************************************
612//********************* DYNAMIC SCRIPT LOADING METHODS **********************
613//***************************************************************************
614//***************************************************************************
615
616SSAjax.LoadMultipleScripts = function(arrSrc, callback, n)
617{
618    n = (SSAjax.IsValid(n) ? n : 0);
619
620    if (n < arrSrc.length)
621        SSAjax.LoadScript(arrSrc[n], function() { SSAjax.LoadMultipleScripts(arrSrc, callback, n+1); });
622    else
623        callback();
624}
625
626//***************************************************************************
627
628SSAjax.LoadScript = function(src, callback)
629{
630    var head = document.getElementsByTagName('head')[0];
631    var s = document.createElement('script');
632    head.appendChild(s);
633
634    if (SSAjax.IS_IE && !SSAjax.IS_IE11)
635    {
636        s.onreadystatechange = SSAjax.LoadScriptCompleteIE;
637    }
638    else
639    {
640        s.onload = SSAjax.LoadScriptCompleteW3C;
641        s.onerror = SSAjax.LoadScriptCompleteW3C;
642    }
643
644    SSAjax.LoadScript.callback = callback;
645    
646    s.type = 'text/javascript';
647    s.src = src;
648}
649
650SSAjax.LoadScriptCompleteIE = function(e)
651{
652    var s = window.event.srcElement;
653    if (s.readyState != 'loaded')
654        return;
655
656    SSAjax.LoadScript.callback(s);
657}
658
659SSAjax.LoadScriptCompleteW3C = function(e)
660{
661    var s = e.currentTarget;
662    SSAjax.LoadScript.callback(s);
663}
664
665//***************************************************************************
666//***************************************************************************
667//******************************** DEBUGGING ********************************
668//***************************************************************************
669//***************************************************************************
670
671SSAjax.WriteBrowserInfo = function()
672{
673    var arr = new Array();
674    var n = 0;
675    
676    if (SSAjax.IS_IE) arr[n++] = "IE";
677    if (SSAjax.IS_MOZILLA) arr[n++] = "Mozilla";
678    if (SSAjax.IS_OPERA) arr[n++] = "Opera";
679    if (SSAjax.IS_SAFARI) arr[n++] = "Safari";
680    if (SSAjax.IS_FIREFOX) arr[n++] = "Firefox";
681    if (SSAjax.IS_NETSCAPE) arr[n++] = "Netscape";
682    
683    if (SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL1) arr[n++] = "HAS_DOM_IMPLEMENTATION_LEVEL1";
684    if (SSAjax.HAS_DOM_IMPLEMENTATION_LEVEL2) arr[n++] = "HAS_DOM_IMPLEMENTATION_LEVEL2";
685    if (SSAjax.HAS_DOM_XPATH_LEVEL3) arr[n++] = "HAS_DOM_XPATH_LEVEL3";
686    
687    document.write("Browser is");
688    if (n > 0)
689    {
690        for (x = 0 ; x < n ; x++)
691        {
692            if (x == 0)
693                document.write(" ");
694            else
695                document.write(", ");
696            document.write(arr[x]);
697        }
698    }
699    else
700    {
701        document.write(" Unknown");
702    }
703    document.write(" (UserAgent = " + navigator.userAgent + ")");
704}
705
706//***************************************************************************
707
708SSAjax.GetPathToScript = function(name)
709{
710    var scripts = document.getElementsByTagName('script');
711    for (var i = 0 ; i < scripts.length ; i++)
712    {
713        var pos = scripts[i].src.indexOf(name);
714        if (pos >= 0)
715            return scripts[i].src.substr(0, pos);
716    }
717    
718    return null;
719}
720
721
722//***************************************************************************
723
724SSAjax.GetString = function(key)
725{
726	var argValues = SSAjax.GetString.arguments;
727	var argCount = argValues.length;
728	var value = SSAjax.Strings[key];
729	if (value == null)
730		return key;
731
732	for (var i=1; i<argCount; i++)
733	{
734		var regexp = eval("/{" + i + "[.!}]*}/g");
735		value = value.replace(regexp, argValues[i]);
736		regexp = eval("/{" + i + "q[.!}]*}/g");
737		value = value.replace(regexp, "\'" + argValues[i] + "\'");
738	}
739	return value;
740}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.