Project

General

Profile

1
/*
2
License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
3
$Id$
4
*/
5

    
6
/** get a time stamp at start of the page load */
7
var mbTimerStart = new Date();
8

    
9
/** the global config object */
10
var config;
11

    
12
/** URL of Mapbuilder's lib/ directory. */
13
var baseDir;
14

    
15
/** mapbuilder environement settings, defaults to a .xml extension but is 
16
  auto-configured by the ant build script to .jsp for tomcat environment 
17
  the URL to this file will be pre-pended with the baseDir value.
18
*/
19
var mbServerConfig = "mapbuilderConfig.xml";
20
var mbNsUrl = "http://mapbuilder.sourceforge.net/mapbuilder";
21

    
22
// LoadState Constants
23
var MB_UNLOADED=0;    // Scripts not loaded yet
24
var MB_LOAD_CORE=1;   // Loading scripts loaded defined in Mapbuilder
25
var MB_LOAD_CONFIG=2; // Loading scripts loaded defined in Config
26
var MB_LOADED=3;      // All scripts loaded
27

    
28
/**
29
 * This Object bootstraps the Mapbuilder libraries by loading the core
30
 * script files.
31
 * When Config.js is loaded, the script files for objects described in the
32
 * Mapbuilder config file are loaded.
33
 * Objects which have dependencies will trigger the dependancies to load
34
 * when they are loaded.
35
 *
36
 * @constructor
37
 * @author Cameron Shorter
38
 * @requires Config
39
 * @requires Listener
40
 * @requires ModelBase
41
 * @requires Sarissa
42
 * @requires Util
43
 */
44
function Mapbuilder() {
45

    
46
  /**
47
   * Determines which Mapbuilder scripts are loading.
48
   * TBD: Is it possible to use enumerated types in JS?
49
   */
50
  this.loadState=MB_UNLOADED;
51

    
52
  /** Array of objects that are loading.  Don't continue initialisation until
53
   * all objects have loaded. */
54
  this.loadingScripts=new Array();
55

    
56
  /** Timer to periodically check if scripts have loaded. */
57
  this.scriptsTimer=null;
58

    
59
  /**
60
   * Called periodically and moves onto the next loadState when this round of
61
   * scripts have loaded.
62
   * For IE clients, object.readyState is used to check if scripts are loaded.
63
   * Mozilla works fine without this function - I think it is single threaded.
64
   */
65
  this.checkScriptsLoaded=function() {
66
    if (document.readyState!=null){
67
      // IE client
68

    
69
      // Scripts are removed from array when they have loaded
70
      while(this.loadingScripts.length>0
71
        &&(this.loadingScripts[0].readyState=="loaded"
72
          ||this.loadingScripts[0].readyState=="complete"
73
          ||this.loadingScripts[0].readyState==null))
74
      {
75
        this.loadingScripts.shift();
76
      }
77
      if (this.loadingScripts.length==0){
78
        this.setLoadState(this.loadState+1);
79
      }
80
    }
81
    else{
82
      // Mozilla client
83
      if(this.loadState==MB_LOAD_CORE && config!=null){
84
        // Config has finished loading
85
        this.setLoadState(MB_LOAD_CONFIG);
86
      }
87
    }
88
  }
89

    
90
  /**
91
   * Move onto loading the next set of scripts.
92
   * @param newState The new loading state.
93
   */
94
  this.setLoadState=function(newState){
95
    this.loadState=newState;
96
    switch (newState){
97
      case MB_LOAD_CORE:
98
        this.loadScript(baseDir+"/util/sarissa/Sarissa.js");
99
        //this.loadScript(baseDir+"/util/sarissa/sarissa_dhtml.js");
100
        this.loadScript(baseDir+"/util/sarissa/sarissa_ieemu_xpath.js");
101
        //this.loadScript(baseDir+"/util/sarissa/sarissa_ieemu_xslt.js");//all deprecated
102
        this.loadScript(baseDir+"/util/Util.js");
103
        this.loadScript(baseDir+"/util/Listener.js");
104
        this.loadScript(baseDir+"/model/ModelBase.js");
105
        this.loadScript(baseDir+"/model/Config.js");
106
        break;
107
      case MB_LOAD_CONFIG:
108
        if(document.readyState){
109
          // IE
110
          config=new Config(mbConfigUrl);
111
          config.loadConfigScripts();
112
        }else{
113
          // Mozilla
114
          this.setLoadState(MB_LOADED);
115
        }
116
        break;
117
      case MB_LOADED:
118
        clearInterval(this.scriptsTimer);
119
          
120
        /*
121
         *  Test for XSLT support
122
         *  if not, redirect to an appropriate message.
123
         */
124
        if (typeof XSLTProcessor != "undefined") {
125
           var UA = navigator.userAgent;
126
           var AV = navigator.appVersion;
127

    
128
           // KHTML browsers should be detected by the typeof comparison
129
           //khtml = ((AV.indexOf("Konqueror") >= 0)||(AV.indexOf("Safari") >= 0)) ? true : false;
130

    
131
           // Opera slips through the cracks
132
           opera = UA.indexOf("Opera") == -1 ? false : true;
133

    
134
           if (opera) {
135
               window.location = baseDir+"/util/noxslt.html";
136
           }
137
        } else {
138
           window.location = baseDir+"/util/noxslt.html";
139
        }
140

    
141
        break;
142
    }
143
  }
144

    
145
  /**
146
   * Dynamically load a script file if it has not already been loaded.
147
   * @param url The url of the script.
148
   */
149
  this.loadScript=function(url){
150
    if(!document.getElementById(url)){
151
      var script = document.createElement('script');
152
      script.defer = false;   //not sure of effect of this?
153
      script.type = "text/javascript";
154
      script.src = url;
155
      script.id = url;
156
      document.getElementsByTagName('head')[0].appendChild(script);
157
      this.loadingScripts.push(script);
158
    }
159
  }
160

    
161
  /**
162
   * Internal function to load scripts for components that don't have <scriptfile>
163
   * specified in the config file.
164
   * @param xPath Xpath match of components from the Config file.
165
   * @param dir The directory the script is located in.
166
   */
167
  this.loadScriptsFromXpath=function(nodes,dir) {
168
    //var nodes = this.doc.selectNodes(xPath);
169
    for (var i=0; i<nodes.length; i++) {
170
      if (nodes[i].selectSingleNode("mb:scriptFile")==null){
171
        scriptFile = baseDir+"/"+dir+nodes[i].nodeName+".js";
172
        this.loadScript(scriptFile);
173
      }
174
    }
175
  }
176

    
177
  //derive the baseDir value by looking for the script tag that loaded this file
178
  var head = document.getElementsByTagName('head')[0];
179
  var nodes = head.childNodes;
180
  for (var i=0; i<nodes.length; ++i ){
181
    var src = nodes.item(i).src;
182
    if (src) {
183
      var index = src.indexOf("/Mapbuilder.js");
184
      if (index>=0) {
185
        baseDir = src.substring(0, index);
186
      }
187
    }
188
  }
189

    
190
  // Start loading core scripts.
191
  this.setLoadState(MB_LOAD_CORE);
192

    
193
  // Start a timer which periodically calls checkScriptsLoaded().
194
  this.scriptsTimer=setInterval('mapbuilder.checkScriptsLoaded()',100);
195
}
196

    
197
/**
198
 * copied from sarissa, a function to check browser security setting in IE, 
199
 * opens a help page if ActiveX objects are disabled.
200
 */
201
function checkIESecurity()
202
{
203
  var testPrefixes = ["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"];
204
  // found progID flag
205
  var bFound = false;
206
  for(var i=0; i < testPrefixes.length && !bFound; i++) {
207
    try {
208
      var oDoc = new ActiveXObject(testPrefixes[i]);
209
      bFound = true;
210
    }
211
    catch (e) {
212
      //trap; try next progID
213
    }
214
  }
215
  if (!bFound) window.open("/mapbuilder/docs/help/IESetup.html");  //TBD: set this URL in config
216
}
217

    
218
if (navigator.userAgent.toLowerCase().indexOf("msie") > -1) checkIESecurity();
219
var mapbuilder=new Mapbuilder();
220

    
221
/**
222
 * Initialise Mapbuilder if script has been loaded, else wait to be called
223
 * again.
224
 */
225
function mapbuilderInit(){
226
  if(mapbuilder && mapbuilder.loadState==MB_LOADED){
227
    clearInterval(mbTimerId);
228
    config.parseConfig(config);
229
    config.callListeners("init");
230
    var mbTimerStop = new Date();
231
    //alert("load time:"+(mbTimerStop.getTime()-mbTimerStart.getTime()) );
232
    if (window.mbInit) window.mbInit();
233
    config.callListeners("loadModel");
234
  }
235
}
236

    
237
/** Timer used when checking if scripts have loaded. */
238
var mbTimerId;
239

    
240
/**
241
 * Mapbuilder's main initialisation script.
242
 * This should be called from the main html file using:
243
 *   <body onload="mbDoLoad()">
244
 * @param initFunction Optional - A function reference that will be called after 
245
 * config.init() has been called.  This is to give application code a chance to
246
 * do initialization and be guaranteed that all objects exist (inlcuding config).
247
 */
248
function mbDoLoad(initFunction) {
249
  // See if scripts have been loaded every 100msecs, then call config.init().
250
  mbTimerId=setInterval('mapbuilderInit()',100);
251
  if (initFunction) window.mbInit = initFunction;
252
}
(2-2/3)