summaryrefslogtreecommitdiff
path: root/lib/dojo/lib/backCompat.js
blob: 101f4e520123882db9ef4f3f830494b915029adf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
	Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
	Available via Academic Free License >= 2.1 OR the modified BSD license.
	see: http://dojotoolkit.org/license for details
*/


// AMD module id = dojo/lib/backCompat
//
// This module defines those dojo properties/methods that are defined by
// dojo/_base/_loader/loader and are still needed when loading with and
// AMD loader (when loading with an AMD loader, dojo/_base/_loader/loader
// is never loaded).
//
// note: this module is relevant only when loading dojo with an AMD loader;
// it is never evaluated otherwise.

define(["require", "dojo/_base/_loader/bootstrap"], function(require, dojo){
	// the following dojo properties do not exist in the AMD-loaded version of dojo 1.x:
	var names= [
		"_moduleHasPrefix",
		"_loadPath",
		"_loadUri",
		"_loadUriAndCheck",
		"loaded",
		"_callLoaded",
		"_getModuleSymbols",
		"_loadModule",
		"require",
		"provide",
		"platformRequire",
		"requireIf",
		"requireAfterIf",
		"registerModulePath"
	], i, name;
	for(i = 0; i<names.length;){
		name = names[i++];
		dojo[name] = (function(name) {
			return function(){
				console.warn("dojo." + name + " not available when using an AMD loader.");
			};
		})(name);
	}

	// define dojo.addOnLoad in terms of the DOMContentLoaded detection available from the AMD loaders
	// (requirejs and bdBuild). Note that the behavior of this feature is slightly different compared to the dojo
	// v1.x sync loader. There, the onload queue is fired upon detecting both DOMContentLoaded *and* all
	// demanded modules have arrived. It is impossible to simulate this behavior with requirejs since it does
	// not publish its internal status (it is possible with bdLoad).
	// TODO: consider taking ownership of this API back from the loader.
	// TODO: consider requesting requirejs publish more enough internal state to determine if all demanded
	// modules have been defined.
	var
		argsToArray = function(args) {
			var result = [], i;
			for(i = 0; i<args.length;){
				result.push(args[i++]);
			}
			return result;
		},

		simpleHitch = function(context, callback){
			if(callback){
				return (typeof callback=="string") ?
					function(){context[callback]();} :
					function(){callback.call(context);};
			}else{
				return context;
			}
		};
	dojo.ready = dojo.addOnLoad = function(context, callback){
		require.ready(callback ? simpleHitch(context, callback) : context);
	};
	dojo.addOnLoad(function() {
		dojo.postLoad = dojo.config.afterOnLoad = true;
	});
	var dca = dojo.config.addOnLoad;
	if(dca){
		dojo.addOnLoad[(dca instanceof Array ? "apply" : "call")](dojo, dca);
	}

	// TODO: in the dojo 1.x sync loader the array dojo._loaders holds the queue of callbacks to be executed
	// upon DOMContentLoaded. This queue is manipulated directly by dojo/uacss, dojo/parser, dijit/_base/wia
	// and others (at least in dojox). This is also impossible to simulate universally across all AMD loaders.
	// The following will at least accept client code accessing dojo._loaders , dojo._loaders.unshift, and
	// dojo._loaders.splice--which is all that exists in the current dojo/dijit code stacks.
	var
		loaders = dojo._loaders = [],
		runLoaders = function(){
			var temp= loaders.slice(0);
			Array.prototype.splice.apply(loaders, [0, loaders.length]);
			while(temp.length){
				temp.shift().call();
			};
		};
	loaders.unshift = function() {
		Array.prototype.unshift.apply(loaders, argsToArray(arguments));
		require.ready(runLoaders);
	};
	loaders.splice = function() {
		Array.prototype.splice.apply(loaders, argsToArray(arguments));
		require.ready(runLoaders);
	};

	//TODO: put unload handling in a separate module
	var unloaders = dojo._unloaders = [];
	dojo.unloaded = function(){
		while(unloaders.length){
			unloaders.pop().call();
		}
	};

	//TODO: kill this low-value function when it is exorcised from dojo
	dojo._onto = function(arr, obj, fn){
		arr.push(fn ? simpleHitch(obj, fn) : obj);
	};

	//TODO: kill this when the bootstrap is rewritten to not include DOMContentLoaded detection
	// (it should probably be just a module) for now, just sink the detection; leverage the
	// AMD loaders to handle DOMContentLoaded detection
	dojo._modulesLoaded = function(){};

	//TODO: kill this when we understand its purpose relative to AMD
	dojo.loadInit = function(init){
		init();
	};

	var amdModuleName= function(moduleName){
		return moduleName.replace(/\./g, "/");
	};

	dojo.getL10nName = function(moduleName, bundleName, locale){
		locale = locale ? locale.toLowerCase() : dojo.locale;
		moduleName = "i18n!" + amdModuleName(moduleName);
		return (/root/i.test(locale)) ?
			(moduleName + "/nls/" + bundleName) :
			(moduleName + "/nls/"	 + locale + "/" + bundleName);
	};

	dojo.requireLocalization = function(moduleName, bundleName, locale){
		// NOTE: locales other than the locale specified in dojo.locale need to be specifically
		// declared as a module dependency when using AMD.
		if(require.vendor!="altoviso.com"){
			locale = !locale || locale.toLowerCase() === dojo.locale ? "root" :  locale;
		}
		return require(dojo.getL10nName(moduleName, bundleName, locale));
	};

	dojo.i18n= {
		getLocalization: dojo.requireLocalization,
		normalizeLocale: function(locale){
			var result = locale ? locale.toLowerCase() : dojo.locale;
			if(result == "root"){
				result = "ROOT";
			}
			return result;
		}
	};

	//TODO: dojo._Url seems rarely used and long to be part of the boostrap; consider moving
	//note: this routine cut and paste from dojo/_base/_loader/loader
	var
		ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
		ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
	dojo._Url = function(){
		var n = null,
			_a = arguments,
			uri = [_a[0]];
		// resolve uri components relative to each other
		for(var i = 1; i<_a.length; i++){
			if(!_a[i]){ continue; }

			// Safari doesn't support this.constructor so we have to be explicit
			// FIXME: Tracked (and fixed) in Webkit bug 3537.
			//		http://bugs.webkit.org/show_bug.cgi?id=3537
			var relobj = new dojo._Url(_a[i]+""),
				uriobj = new dojo._Url(uri[0]+"");

			if(
				relobj.path == "" &&
				!relobj.scheme &&
				!relobj.authority &&
				!relobj.query
			){
				if(relobj.fragment != n){
					uriobj.fragment = relobj.fragment;
				}
				relobj = uriobj;
			}else if(!relobj.scheme){
				relobj.scheme = uriobj.scheme;

				if(!relobj.authority){
					relobj.authority = uriobj.authority;

					if(relobj.path.charAt(0) != "/"){
						var path = uriobj.path.substring(0,
							uriobj.path.lastIndexOf("/") + 1) + relobj.path;

						var segs = path.split("/");
						for(var j = 0; j < segs.length; j++){
							if(segs[j] == "."){
								// flatten "./" references
								if(j == segs.length - 1){
									segs[j] = "";
								}else{
									segs.splice(j, 1);
									j--;
								}
							}else if(j > 0 && !(j == 1 && segs[0] == "") &&
								segs[j] == ".." && segs[j-1] != ".."){
								// flatten "../" references
								if(j == (segs.length - 1)){
									segs.splice(j, 1);
									segs[j - 1] = "";
								}else{
									segs.splice(j - 1, 2);
									j -= 2;
								}
							}
						}
						relobj.path = segs.join("/");
					}
				}
			}

			uri = [];
			if(relobj.scheme){
				uri.push(relobj.scheme, ":");
			}
			if(relobj.authority){
				uri.push("//", relobj.authority);
			}
			uri.push(relobj.path);
			if(relobj.query){
				uri.push("?", relobj.query);
			}
			if(relobj.fragment){
				uri.push("#", relobj.fragment);
			}
		}

		this.uri = uri.join("");

		// break the uri into its main components
		var r = this.uri.match(ore);

		this.scheme = r[2] || (r[1] ? "" : n);
		this.authority = r[4] || (r[3] ? "" : n);
		this.path = r[5]; // can never be undefined
		this.query = r[7] || (r[6] ? "" : n);
		this.fragment	 = r[9] || (r[8] ? "" : n);

		if(this.authority != n){
			// server based naming authority
			r = this.authority.match(ire);

			this.user = r[3] || n;
			this.password = r[4] || n;
			this.host = r[6] || r[7]; // ipv6 || ipv4
			this.port = r[9] || n;
		}
	};

	dojo._Url.prototype.toString = function(){ return this.uri; };

	dojo.moduleUrl = function(module, url){
		if(!module){
		 //TODO: don't understand why this would ever be so, but that's the logic in loader
		 return null;
		}
		module = amdModuleName(module) + (url ? ("/" + url) : "");
		var
			type= "",
			match= module.match(/(.+)(\.[^\/]*)$/);
		if (match) {
			module= match[1];
			type= match[2];
		}
		return new dojo._Url(require.nameToUrl(module, type)); // dojo._Url
	};

	return dojo;
});