blob: f3c0915abdef3ea23f5e4101052e30e3f2066d17 [file] [log] [blame]
/**
* @file bootstrap1.js
*
* summary: First file that is loaded that 'bootstraps' the entire dojo library suite.
* note: Must run before hostenv_*.js file.
*
* @author Copyright 2004 Mark D. Anderson (mda@discerning.com)
* TODOC: should the copyright be changed to Dojo Foundation?
* @license Licensed under the Academic Free License 2.1 http://www.opensource.org/licenses/afl-2.1.php
*
* $Id: bootstrap1.js 6824 2006-12-06 09:34:32Z alex $
*/
// TODOC: HOW TO DOC THE BELOW?
// @global: djConfig
// summary:
// Application code can set the global 'djConfig' prior to loading
// the library to override certain global settings for how dojo works.
// description: The variables that can be set are as follows:
// - isDebug: false
// - allowQueryConfig: false
// - baseScriptUri: ""
// - baseRelativePath: ""
// - libraryScriptUri: ""
// - iePreventClobber: false
// - ieClobberMinimal: true
// - locale: undefined
// - extraLocale: undefined
// - preventBackButtonFix: true
// - searchIds: []
// - parseWidgets: true
// TODOC: HOW TO DOC THESE VARIABLES?
// TODOC: IS THIS A COMPLETE LIST?
// note:
// 'djConfig' does not exist under 'dojo.*' so that it can be set before the
// 'dojo' variable exists.
// note:
// Setting any of these variables *after* the library has loaded does nothing at all.
// TODOC: is this still true? Release notes for 0.3 indicated they could be set after load.
//
//TODOC: HOW TO DOC THIS?
// @global: dj_global
// summary:
// an alias for the top-level global object in the host environment
// (e.g., the window object in a browser).
// description:
// Refer to 'dj_global' rather than referring to window to ensure your
// code runs correctly in contexts other than web browsers (eg: Rhino on a server).
var dj_global = this;
//TODOC: HOW TO DOC THIS?
// @global: dj_currentContext
// summary:
// Private global context object. Where 'dj_global' always refers to the boot-time
// global context, 'dj_currentContext' can be modified for temporary context shifting.
// dojo.global() returns dj_currentContext.
// description:
// Refer to dojo.global() rather than referring to dj_global to ensure your
// code runs correctly in managed contexts.
var dj_currentContext = this;
// ****************************************************************
// global public utils
// TODOC: DO WE WANT TO NOTE THAT THESE ARE GLOBAL PUBLIC UTILS?
// ****************************************************************
function dj_undef(/*String*/ name, /*Object?*/ object){
//summary: Returns true if 'name' is defined on 'object' (or globally if 'object' is null).
//description: Note that 'defined' and 'exists' are not the same concept.
return (typeof (object || dj_currentContext)[name] == "undefined"); // Boolean
}
// make sure djConfig is defined
if(dj_undef("djConfig", this)){
var djConfig = {};
}
//TODOC: HOW TO DOC THIS?
// dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
if(dj_undef("dojo", this)){
var dojo = {};
}
dojo.global = function(){
// summary:
// return the current global context object
// (e.g., the window object in a browser).
// description:
// Refer to 'dojo.global()' rather than referring to window to ensure your
// code runs correctly in contexts other than web browsers (eg: Rhino on a server).
return dj_currentContext;
}
// Override locale setting, if specified
dojo.locale = djConfig.locale;
//TODOC: HOW TO DOC THIS?
dojo.version = {
// summary: version number of this instance of dojo.
major: 0, minor: 4, patch: 1, flag: "",
revision: Number("$Rev$".match(/[0-9]+/)[0]),
toString: function(){
with(dojo.version){
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
}
}
}
dojo.evalProp = function(/*String*/ name, /*Object*/ object, /*Boolean?*/ create){
// summary: Returns 'object[name]'. If not defined and 'create' is true, will return a new Object.
// description:
// Returns null if 'object[name]' is not defined and 'create' is not true.
// Note: 'defined' and 'exists' are not the same concept.
if((!object)||(!name)) return undefined; // undefined
if(!dj_undef(name, object)) return object[name]; // mixed
return (create ? (object[name]={}) : undefined); // mixed
}
dojo.parseObjPath = function(/*String*/ path, /*Object?*/ context, /*Boolean?*/ create){
// summary: Parse string path to an object, and return corresponding object reference and property name.
// description:
// Returns an object with two properties, 'obj' and 'prop'.
// 'obj[prop]' is the reference indicated by 'path'.
// path: Path to an object, in the form "A.B.C".
// context: Object to use as root of path. Defaults to 'dojo.global()'.
// create: If true, Objects will be created at any point along the 'path' that is undefined.
var object = (context || dojo.global());
var names = path.split('.');
var prop = names.pop();
for (var i=0,l=names.length;i<l && object;i++){
object = dojo.evalProp(names[i], object, create);
}
return {obj: object, prop: prop}; // Object: {obj: Object, prop: String}
}
dojo.evalObjPath = function(/*String*/ path, /*Boolean?*/ create){
// summary: Return the value of object at 'path' in the global scope, without using 'eval()'.
// path: Path to an object, in the form "A.B.C".
// create: If true, Objects will be created at any point along the 'path' that is undefined.
if(typeof path != "string"){
return dojo.global();
}
// fast path for no periods
if(path.indexOf('.') == -1){
return dojo.evalProp(path, dojo.global(), create); // mixed
}
//MOW: old 'with' syntax was confusing and would throw an error if parseObjPath returned null.
var ref = dojo.parseObjPath(path, dojo.global(), create);
if(ref){
return dojo.evalProp(ref.prop, ref.obj, create); // mixed
}
return null;
}
dojo.errorToString = function(/*Error*/ exception){
// summary: Return an exception's 'message', 'description' or text.
// TODO: overriding Error.prototype.toString won't accomplish this?
// ... since natively generated Error objects do not always reflect such things?
if(!dj_undef("message", exception)){
return exception.message; // String
}else if(!dj_undef("description", exception)){
return exception.description; // String
}else{
return exception; // Error
}
}
dojo.raise = function(/*String*/ message, /*Error?*/ exception){
// summary: Common point for raising exceptions in Dojo to enable logging.
// Throws an error message with text of 'exception' if provided, or
// rethrows exception object.
if(exception){
message = message + ": "+dojo.errorToString(exception);
}else{
message = dojo.errorToString(message);
}
// print the message to the user if hostenv.println is defined
try { if(djConfig.isDebug){ dojo.hostenv.println("FATAL exception raised: "+message); } } catch (e) {}
throw exception || Error(message);
}
//Stub functions so things don't break.
//TODOC: HOW TO DOC THESE?
dojo.debug = function(){};
dojo.debugShallow = function(obj){};
dojo.profile = { start: function(){}, end: function(){}, stop: function(){}, dump: function(){} };
function dj_eval(/*String*/ scriptFragment){
// summary: Perform an evaluation in the global scope. Use this rather than calling 'eval()' directly.
// description: Placed in a separate function to minimize size of trapped evaluation context.
// note:
// - JSC eval() takes an optional second argument which can be 'unsafe'.
// - Mozilla/SpiderMonkey eval() takes an optional second argument which is the
// scope object for new symbols.
return dj_global.eval ? dj_global.eval(scriptFragment) : eval(scriptFragment); // mixed
}
dojo.unimplemented = function(/*String*/ funcname, /*String?*/ extra){
// summary: Throw an exception because some function is not implemented.
// extra: Text to append to the exception message.
var message = "'" + funcname + "' not implemented";
if (extra != null) { message += " " + extra; }
dojo.raise(message);
}
dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
// summary: Log a debug message to indicate that a behavior has been deprecated.
// extra: Text to append to the message.
// removal: Text to indicate when in the future the behavior will be removed.
var message = "DEPRECATED: " + behaviour;
if(extra){ message += " " + extra; }
if(removal){ message += " -- will be removed in version: " + removal; }
dojo.debug(message);
}
dojo.render = (function(){
//TODOC: HOW TO DOC THIS?
// summary: Details rendering support, OS and browser of the current environment.
// TODOC: is this something many folks will interact with? If so, we should doc the structure created...
function vscaffold(prefs, names){
var tmp = {
capable: false,
support: {
builtin: false,
plugin: false
},
prefixes: prefs
};
for(var i=0; i<names.length; i++){
tmp[names[i]] = false;
}
return tmp;
}
return {
name: "",
ver: dojo.version,
os: { win: false, linux: false, osx: false },
html: vscaffold(["html"], ["ie", "opera", "khtml", "safari", "moz"]),
svg: vscaffold(["svg"], ["corel", "adobe", "batik"]),
vml: vscaffold(["vml"], ["ie"]),
swf: vscaffold(["Swf", "Flash", "Mm"], ["mm"]),
swt: vscaffold(["Swt"], ["ibm"])
};
})();
// ****************************************************************
// dojo.hostenv methods that must be defined in hostenv_*.js
// ****************************************************************
/**
* The interface definining the interaction with the EcmaScript host environment.
*/
/*
* None of these methods should ever be called directly by library users.
* Instead public methods such as loadModule should be called instead.
*/
dojo.hostenv = (function(){
// TODOC: HOW TO DOC THIS?
// summary: Provides encapsulation of behavior that changes across different 'host environments'
// (different browsers, server via Rhino, etc).
// description: None of these methods should ever be called directly by library users.
// Use public methods such as 'loadModule' instead.
// default configuration options
var config = {
isDebug: false,
allowQueryConfig: false,
baseScriptUri: "",
baseRelativePath: "",
libraryScriptUri: "",
iePreventClobber: false,
ieClobberMinimal: true,
preventBackButtonFix: true,
delayMozLoadingFix: false,
searchIds: [],
parseWidgets: true
};
if (typeof djConfig == "undefined") { djConfig = config; }
else {
for (var option in config) {
if (typeof djConfig[option] == "undefined") {
djConfig[option] = config[option];
}
}
}
return {
name_: '(unset)',
version_: '(unset)',
getName: function(){
// sumary: Return the name of the host environment.
return this.name_; // String
},
getVersion: function(){
// summary: Return the version of the hostenv.
return this.version_; // String
},
getText: function(/*String*/ uri){
// summary: Read the plain/text contents at the specified 'uri'.
// description:
// If 'getText()' is not implemented, then it is necessary to override
// 'loadUri()' with an implementation that doesn't rely on it.
dojo.unimplemented('getText', "uri=" + uri);
}
};
})();
dojo.hostenv.getBaseScriptUri = function(){
// summary: Return the base script uri that other scripts are found relative to.
// TODOC: HUH? This comment means nothing to me. What other scripts? Is this the path to other dojo libraries?
// MAYBE: Return the base uri to scripts in the dojo library. ???
// return: Empty string or a path ending in '/'.
if(djConfig.baseScriptUri.length){
return djConfig.baseScriptUri;
}
// MOW: Why not:
// uri = djConfig.libraryScriptUri || djConfig.baseRelativePath
// ??? Why 'new String(...)'
var uri = new String(djConfig.libraryScriptUri||djConfig.baseRelativePath);
if (!uri) { dojo.raise("Nothing returned by getLibraryScriptUri(): " + uri); }
// MOW: uri seems to not be actually used. Seems to be hard-coding to djConfig.baseRelativePath... ???
var lastslash = uri.lastIndexOf('/'); // MOW ???
djConfig.baseScriptUri = djConfig.baseRelativePath;
return djConfig.baseScriptUri; // String
}