if
(
typeof
dojo
==
"
undefined
"
){
/*
*
* @文件 bootstrap1.js
*
* 摘要: 整套Dojo库载入的第一个文件。
// ****************************************************************
// note: 必须运行于hostenv_*.js文件之前。 (说的是src目录下的文件,它们从都是从此文档的分割出去的)
// ****************************************************************
*
* @作者 Copyright 2004 Mark D. Anderson (mda@discerning.com)
* TODOC: 可以在Dojo基础上做改动吗?
* @许可协议 在Academic Free License 2.1 (http://www.opensource.org/licenses/afl-2.1.php)许可协议下。
*
* $Id: bootstrap1.js 4342 2006-06-11 23:03:30Z alex $
*/
//
TODOC: HOW TO DOC THE BELOW?
//
@全局: djConfig
//
摘要:
//
载入库时,应用程序代码可以先设置全局变量"djConfig"来取消某个Dojo运作方式的全局设定。
//
说明: 可以设定如下全局变量:
//
- isDebug: false
//
- allowQueryConfig: false
//
- baseScriptUri: ""
//
- baseRelativePath: ""
//
- libraryScriptUri: ""
//
- iePreventClobber: false
//
- ieClobberMinimal: true
//
- preventBackButtonFix: true
//
- searchIds: []
//
- parseWidgets: true
//
TODOC: HOW TO DOC THESE VARIABLES?
//
TODOC: IS THIS A COMPLETE LIST?
//
注意:
//
在有"dojo.*"时,"djConfig"不存在。因此,在"dojo"变量存在前可以被设定。
//
注意:
//
在载入库之后设定这些变量,都不起任何作用。
//
TODOC: 现在仍然如此吗? 版本0.3的发行说明指出载入后仍可设定。.
//
//
TODOC: HOW TO DOC THIS?
//
@全局: dj_global
//
摘要:
//
主环境的顶层全局对象的别名
//
(例如:浏览器的window对象)。
//
说明:
//
使用"dj_global"而不是window对象,是为了保证你的代码在上下文中可以正确运行,而不是指哪些浏览器。(eg: Rhino on a server).
var
dj_global
=
this
;
function
dj_undef(
/*
String
*/
name,
/*
Object?
*/
object){
//
摘要: 如果在"object"对象上定义了为参数"name"的属性,返回false (或者在全局范围,"object"对象为null)。
//
说明: 注意定义和存在是两个不同的概念。
if
(object
==
null
){ object
=
dj_global; }
//
如果object不是一个对象时发生异常。
return
(
typeof
object[name]
==
"
undefined
"
);
//
Boolean
}
//
确保定义了djConfig
if
(dj_undef(
"
djConfig
"
)){
var
djConfig
=
{};
}
//
TODOC: HOW TO DOC THIS?
//
dojo是我们使用库中几乎所有公共标志的根变量 —— 确保定义
if
(dj_undef(
"
dojo
"
)){
var
dojo
=
{};
}
//
TODOC: HOW TO DOC THIS?
dojo.version
=
{
//
摘要: 当前dojo实例的版本号。
major:
0
, minor:
3
, patch:
1
, flag:
""
,
revision: Number(
"
$Rev: 4342 $
"
.match(
/
[
0
-
9
]
+/
)[
0
]),
//
找到字符串中的数字匹配返回的字符串数组的第1个元素,并转化成数值类型
toString:
function
(){
with
(dojo.version){
return
major
+
"
.
"
+
minor
+
"
.
"
+
patch
+
flag
+
"
(
"
+
revision
+
"
)
"
;
//
String
}
}
}
dojo.evalProp
=
function
(
/*
String
*/
name,
/*
Object
*/
object,
/*
Boolean?
*/
create){
//
摘要: 返回"object[name]". 如果没有定义并且"create"为true, 会返回一个新对象。
//
说明:
//
如果没有定义"object[name]"并且"create"不为true,返回null。
//
注意: 定义和存在是两个不同的概念。
//
注意: 对象的属性也是对象。
return
(object
&&
!
dj_undef(name, object)
?
object[name] : (create
?
(object[name]
=
{}) : undefined));
//
mixed
}
dojo.parseObjPath
=
function
(
/*
String
*/
path,
/*
Object?
*/
context,
/*
Boolean?
*/
create){
//
摘要: 解析字符串path并成返回一个对象,它带有对应的对象引用及属性名称。
//
说明:
//
返回一个带有"obj"和"prop"两个属性的对象。
//
参照"path"指出"obj[prop]"。
//
path: 一个对象的Path是以"A.B.C"的形式。
//
context: 作用类似根目录的对象,默认是"dj_global"。
//
create: 如果为true,就会沿"path",为那些没有定义的点创建一些新对象。
var
object
=
(context
!=
null
?
context : dj_global);
var
names
=
path.split(
'
.
'
);
var
prop
=
names.pop();
//
弹出数组的最后一个元素并返回,并将数组长度减1。
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){
//
摘要: Return the value of object at 'path' in the global scope, without using 'eval()'.
//
摘要: 返回全局范围内在"path"上的对象的值,没有使用"eval()"。
//
path: 一个对象的Path是以"A.B.C"的形式。
//
create: 如果为true,就会沿"path",为那些没有定义的点创建一些新对象。
if
(
typeof
path
!=
"
string
"
){
return
dj_global;
}
//
没有句点号的快速路径
if
(path.indexOf(
'
.
'
)
==
-
1
){
return
dojo.evalProp(path, dj_global, create);
//
mixed
}
//
MOW: 过去的"with"句法有些混乱。并且,如果parseObjPath返回了null,还会抛出一个错误。
var
ref
=
dojo.parseObjPath(path, dj_global, create);
if
(ref){
return
dojo.evalProp(ref.prop, ref.obj, create);
//
mixed
}
return
null
;
}
//
****************************************************************
//
global public utils (全局公有调用)
//
TODOC: DO WE WANT TO NOTE THAT THESE ARE GLOBAL PUBLIC UTILS? (我们需要记住这些是公有调用吗?)
//
****************************************************************
dojo.errorToString
=
function
(
/*
Error
*/
exception){
//
摘要: 返回异常的 'message', 'note' or text.
//
TODO: 如果没有Error.prototype.toString将不能实现吗?
//
... 因为这是生来造成的错误,所以对象不就总是招来这些事吗?
if
(
!
dj_undef(
"
message
"
, exception)){
return
exception.message;
//
String
}
else
if
(
!
dj_undef(
"
note
"
, exception)){
return
exception.note;
//
String
}
else
{
return
exception;
//
Error
}
}
dojo.raise
=
function
(
/*
String
*/
message,
/*
Error?
*/
exception){
//
摘要: 抛出一个错误消息。如果被支持,还在文字的后面附加上"exception"的内容。
//
注意: 还会使用"dojo.hostenv.println"向用户打出消息的内容。
if
(exception){
message
=
message
+
"
:
"
+
dojo.errorToString(exception);
}
//
如果使用"dojo.hostenv.println",能向用户打出消息。
try
{ dojo.hostenv.println(
"
FATAL:
"
+
message); }
catch
(e) {}
throw
Error(message);
}
//
已经废除的一些方法,所以不起作用了
//
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){
//
摘要: 使用全局范围内的评估方法。这没有直接调用"eval()"。
//
说明: 放在一个单独的方法里,减小评估上下文的大小。
//
注意:
//
- JSC eval() 给出了可选的第二个参数,可以取"unsafe"。
//
- Mozilla/SpiderMonkey eval() 给出了一个可选的第二个参数,作为新代码符号所属的特定范围的对象。
return
dj_global.eval
?
dj_global.eval(scriptFragment) : eval(scriptFragment);
//
mixed
}
dojo.unimplemented
=
function
(
/*
String
*/
funcname,
/*
String?
*/
extra){
//
摘要: 抛出由于某个方法没有实现而产生的异常
//
extra: 附加在异常消息message后的内容。
var
message
=
"
'
"
+
funcname
+
"
' not implemented
"
;
if
(extra
!=
null
) { message
+=
"
"
+
extra; }
dojo.raise(message);
}
dojo.deprecated
=
function
(
/*
String
*/
behaviour,
/*
String?
*/
extra,
/*
String?
*/
removal){
//
摘要: 记录指出一个已经被反对的做法的调试信息。
//
extra: 附加在异常消息message后的内容。
//
removal: 指出会在将来什么时候移除这个做法。
var
message
=
"
DEPRECATED:
"
+
behaviour;
if
(extra){ message
+=
"
"
+
extra; }
if
(removal){ message
+=
"
-- will be removed in version:
"
+
removal; }
dojo.debug(message);
}
dojo.inherits
=
function
(
/*
Function
*/
subclass,
/*
Function
*/
superclass){
//
摘要: 在两个类间建立继承。
if
(
typeof
superclass
!=
'
function
'
){
dojo.raise(
"
dojo.inherits: superclass argument [
"
+
superclass
+
"
] must be a function (subclass: [
"
+
subclass
+
"
']
"
);
}
subclass.prototype
=
new
superclass();
subclass.prototype.constructor
=
subclass;
subclass.superclass
=
superclass.prototype;
//
被反对的: super是一个保留字, 使用 'superclass'
subclass[
'
super
'
]
=
superclass.prototype;
}
dojo.render
=
(
function
(){
//
TODOC: HOW TO DOC THIS?
//
摘要: 描述当前环境的支持、操作系统和浏览器的细节。
//
TODOC: 这是许多人要交互的一些东西吗? 如果是, 我们也许应该给出建有结构的文档...
function
vscaffold(prefs, names){
var
tmp
=
{
capable:
false
,
support: {
builtin:
false
,
plugin:
false
},
prefixes: prefs
};
for
(
var
prop
in
names){
tmp[prop]
=
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 (dojo.hostenv 的这些方法必须在hostenv_*.js被定义)
//
****************************************************************
/*
*
* The interface definining the interaction with the EcmaScript host environment.
* 定义ECMAScript主机环境的交互接口
*/
/*
* 所有这些方法都不能被库的用户所直接调用。
* 作为替代,应该调用如"loadModule"这样的公共方法。
*/
dojo.hostenv
=
(
function
(){
//
TODOC: HOW TO DOC THIS?
//
摘要: Provides encapsulation of behavior that changes across different 'host environments'
//
摘要: 提供在不同"主机环境"(如不同的浏览器,server via Rhino等)下,会有所变化的行为的简化信息。
//
说明: 所有这写方法都不能被库的用户所直接调用。
//
调用如"loadModule"这样的公共方法。
//
默认的配置选项
var
config
=
{
isDebug:
false
,
allowQueryConfig:
false
,
baseScriptUri:
""
,
baseRelativePath:
""
,
libraryScriptUri:
""
,
iePreventClobber:
false
,
ieClobberMinimal:
true
,
preventBackButtonFix:
true
,
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
(){
//
摘要: 返回主机环境的名称.
return
this
.name_;
//
String
},
getVersion:
function
(){
//
摘要: 返回主机环境的版本.
return
this
.version_;
//
String
},
getText:
function
(
/*
String
*/
uri){
//
摘要: 读取指定的"uri"上的纯文本内容。
//
说明:
//
If 'getText()' is not implemented, then it is necessary to override
//
'loadUri()' with an implementation that doesn't rely on it.
//
如果"getText()"没有被实现,那就需要去除不需依赖"loadUri()"的实现。
dojo.unimplemented(
'
getText
'
,
"
uri=
"
+
uri);
}
};
})();
dojo.hostenv.getBaseScriptUri
=
function
(){
//
摘要: 返回与找到其他脚本文件相联系的基本脚本文件的URI。
//
TODOC: 啊? 我不明白这个注释。 什么其他的脚本? 这个文件是其他Dojo库文件的路径?
//
MAYBE: 返回Dojo库的脚本文件的基本URI ???
//
返回: 空字符串或者以"/"结尾的路径。
if
(djConfig.baseScriptUri.length){
return
djConfig.baseScriptUri;
}
//
MOW: 为什么不这样:
//
uri = djConfig.libraryScriptUri || djConfig.baseRelativePath
//
??? 而是 new String(...)'
var
uri
=
new
String(djConfig.libraryScriptUri
||
djConfig.baseRelativePath);
if
(
!
uri) { dojo.raise(
"
Nothing returned by getLibraryScriptUri():
"
+
uri); }
//
MOW: URI好像没有被真的使用。是不是作了djConfig.baseRelativePath的硬性编码(hard-coding )... ???
var
lastslash
=
uri.lastIndexOf(
'
/
'
);
//
MOW ???
djConfig.baseScriptUri
=
djConfig.baseRelativePath;
return
djConfig.baseScriptUri;
//
String
}