Subversion Repositories Applications.papyrus

Rev

Rev 1318 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1318 alexandre_ 1
/*
2
	Copyright (c) 2004-2006, The Dojo Foundation
3
	All Rights Reserved.
4
 
5
	Licensed under the Academic Free License version 2.1 or above OR the
6
	modified BSD license. For more information on Dojo licensing, see:
7
 
8
		http://dojotoolkit.org/community/licensing.shtml
9
*/
10
 
1422 alexandre_ 11
 
12
 
1318 alexandre_ 13
dojo.provide("dojo.widget.html.loader");
14
dojo.require("dojo.widget.HtmlWidget");
15
dojo.require("dojo.io.*");
16
dojo.require("dojo.lang.common");
17
dojo.require("dojo.lang.extras");
18
dojo.require("dojo.experimental");
19
dojo.experimental("dojo.widget.html.loader");
20
dojo.widget.html.loader = new (function () {
21
	this.toString = function () {
22
		return "dojo.widget.html.loader";
23
	};
24
	var _loader = this;
25
	dojo.addOnLoad(function () {
26
		dojo.experimental(_loader.toString());
27
		var undo = dojo.evalObjPath("dojo.undo.browser");
28
		if (djConfig["preventBackButtonFix"] && undo && !undo.initialState) {
29
			undo.setInitialState(new trackerObj);
30
		}
31
	});
32
	var logger = {};
33
	var trackerObj = function (id, data) {
34
		this.id = id;
35
		this.data = data;
36
	};
37
	trackerObj.prototype.handle = function (type) {
38
		if (typeof dojo == "undefined") {
39
			return;
40
		}
41
		var wg = dojo.widget.byId(this.id);
42
		if (wg) {
43
			wg.setContent(this.data, true);
44
		}
45
	};
46
	this._log = function (widget, data) {
47
		if (widget.trackHistory) {
48
			if (!logger[widget.widgetId]) {
49
				logger[widget.widgetId] = {childrenIds:[], stack:[data]};
50
			}
51
			var children = logger[widget.widgetId].childrenIds;
52
			while (children && children.length) {
53
				delete logger[children.pop()];
54
			}
55
			for (var child in widget.children) {
56
				logger[widget.widgetId].childrenIds = child.widgetId;
57
			}
58
			dojo.undo.browser.addToHistory(new trackerObj(widget.widgetId, dojo.lang.shallowCopy(data, true)));
59
		}
60
	};
61
	var undef = dojo.lang.isUndefined;
62
	var isFunc = dojo.lang.isFunction;
63
	function handleDefaults(e, handler, useAlert) {
64
		if (!handler) {
65
			handler = "onContentError";
66
		}
67
		if (dojo.lang.isString(e)) {
68
			e = {_text:e};
69
		}
70
		if (!e._text) {
71
			e._text = e.toString();
72
		}
73
		e.toString = function () {
74
			return this._text;
75
		};
76
		if (typeof e.returnValue != "boolean") {
77
			e.returnValue = true;
78
		}
79
		if (typeof e.preventDefault != "function") {
80
			e.preventDefault = function () {
81
				this.returnValue = false;
82
			};
83
		}
84
		this[handler](e);
85
		if (e.returnValue) {
86
			if (useAlert) {
87
				alert(e.toString());
88
			} else {
89
				this.loader.callOnUnLoad.call(this, false);
90
				this.onSetContent(e.toString());
91
			}
92
		}
93
	}
94
	function downloader(bindArgs) {
95
		for (var x in this.bindArgs) {
96
			bindArgs[x] = (undef(bindArgs[x]) ? this.bindArgs[x] : undefined);
97
		}
98
		var cache = this.cacheContent;
99
		if (undef(bindArgs.useCache)) {
100
			bindArgs.useCache = cache;
101
		}
102
		if (undef(bindArgs.preventCache)) {
103
			bindArgs.preventCache = !cache;
104
		}
105
		if (undef(bindArgs.mimetype)) {
106
			bindArgs.mimetype = "text/html";
107
		}
108
		this.loader.bindObj = dojo.io.bind(bindArgs);
109
	}
110
	function stackRunner(st) {
111
		var err = "", func = null;
112
		var scope = this.scriptScope || dojo.global();
113
		while (st.length) {
114
			func = st.shift();
115
			try {
116
				func.call(scope);
117
			}
118
			catch (e) {
119
				err += "\n" + func + " failed: " + e;
120
			}
121
		}
122
		if (err.length) {
123
			var name = (st == this.loader.addOnLoads) ? "addOnLoad" : "addOnUnLoad";
124
			handleDefaults.call(this, name + " failure\n " + err, "onExecError", true);
125
		}
126
	}
127
	function stackPusher(st, obj, func) {
128
		if (typeof func == "undefined") {
129
			st.push(obj);
130
		} else {
131
			st.push(function () {
132
				obj[func]();
133
			});
134
		}
135
	}
136
	function refreshed() {
137
		this.onResized();
138
		this.onLoad();
139
		this.isLoaded = true;
140
	}
141
	function asyncParse(data) {
142
		if (this.executeScripts) {
143
			this.onExecScript.call(this, data.scripts);
144
		}
145
		if (this.parseContent) {
146
			this.onContentParse.call(this);
147
		}
148
		refreshed.call(this);
149
	}
150
	function runHandler() {
151
		if (dojo.lang.isFunction(this.handler)) {
152
			this.handler(this, this.containerNode || this.domNode);
153
			refreshed.call(this);
154
			return false;
155
		}
156
		return true;
157
	}
158
	this.htmlContentBasicFix = function (s, url) {
159
		var titles = [], styles = [];
160
		var regex = /<title[^>]*>([\s\S]*?)<\/title>/i;
161
		var match, attr;
162
		while (match = regex.exec(s)) {
163
			titles.push(match[1]);
164
			s = s.substring(0, match.index) + s.substr(match.index + match[0].length);
165
		}
166
		regex = /(?:<(style)[^>]*>([\s\S]*?)<\/style>|<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>)/i;
167
		while (match = regex.exec(s)) {
168
			if (match[1] && match[1].toLowerCase() == "style") {
169
				styles.push(dojo.html.fixPathsInCssText(match[2], url));
170
			} else {
171
				if (attr = match[3].match(/href=(['"]?)([^'">]*)\1/i)) {
172
					styles.push({path:attr[2]});
173
				}
174
			}
175
			s = s.substring(0, match.index) + s.substr(match.index + match[0].length);
176
		}
177
		return {"s":s, "titles":titles, "styles":styles};
178
	};
179
	this.htmlContentAdjustPaths = function (s, url) {
180
		var tag = "", str = "", tagFix = "", path = "";
181
		var attr = [], origPath = "", fix = "";
182
		var regexFindTag = /<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i;
183
		var regexFindAttr = /\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i;
184
		var regexProtocols = /^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/;
185
		while (tag = regexFindTag.exec(s)) {
186
			str += s.substring(0, tag.index);
187
			s = s.substring((tag.index + tag[0].length), s.length);
188
			tag = tag[0];
189
			tagFix = "";
190
			while (attr = regexFindAttr.exec(tag)) {
191
				path = "";
192
				origPath = attr[3];
193
				switch (attr[1].toLowerCase()) {
194
				  case "src":
195
				  case "href":
196
					if (regexProtocols.exec(origPath)) {
197
						path = origPath;
198
					} else {
199
						path = (new dojo.uri.Uri(url, origPath).toString());
200
					}
201
					break;
202
				  case "style":
203
					path = dojo.html.fixPathsInCssText(origPath, url);
204
					break;
205
				  default:
206
					path = origPath;
207
				}
208
				fix = " " + attr[1] + "=" + attr[2] + path + attr[2];
209
				tagFix += tag.substring(0, attr.index) + fix;
210
				tag = tag.substring((attr.index + attr[0].length), tag.length);
211
			}
212
			str += tagFix + tag;
213
		}
214
		return str + s;
215
	};
216
	this.htmlContentScripts = function (s, collectScripts) {
217
		var scripts = [], requires = [], match = [];
218
		var attr = "", tmp = null, tag = "", sc = "", str = "";
219
		var regex = /<script([^>]*)>([\s\S]*?)<\/script>/i;
220
		var regexSrc = /src=(['"]?)([^"']*)\1/i;
221
		var regexDojoJs = /.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/;
222
		var regexInvalid = /(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g;
223
		var regexRequires = /dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix)|defineNamespace)\((['"]).*?\1\)\s*;?/;
224
		while (match = regex.exec(s)) {
225
			if (this.executeScripts && match[1]) {
226
				if (attr = regexSrc.exec(match[1])) {
227
					if (regexDojoJs.exec(attr[2])) {
228
						dojo.debug("Security note! inhibit:" + attr[2] + " from  beeing loaded again.");
229
					} else {
230
						scripts.push({path:attr[2]});
231
					}
232
				}
233
			}
234
			if (match[2]) {
235
				sc = match[2].replace(regexInvalid, "");
236
				if (!sc) {
237
					continue;
238
				}
239
				while (tmp = regexRequires.exec(sc)) {
240
					requires.push(tmp[0]);
241
					sc = sc.substring(0, tmp.index) + sc.substr(tmp.index + tmp[0].length);
242
				}
243
				if (collectScripts) {
244
					scripts.push(sc);
245
				}
246
			}
247
			s = s.substr(0, match.index) + s.substr(match.index + match[0].length);
248
		}
249
		if (collectScripts) {
250
			var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*\S=(['"])[^>]*[^\.\]])scriptScope([^>]*>)/;
251
			str = "";
252
			while (tag = regex.exec(s)) {
253
				tmp = ((tag[2] == "'") ? "\"" : "'");
254
				str += s.substring(0, tag.index);
255
				s = s.substr(tag.index).replace(regex, "$1dojo.widget.byId(" + tmp + this.widgetId + tmp + ").scriptScope$3");
256
			}
257
			s = str + s;
258
		}
259
		return {"s":s, "requires":requires, "scripts":scripts};
260
	};
261
	this.splitAndFixPaths = function (args) {
262
		if (!args.url) {
263
			args.url = "./";
264
		}
265
		url = new dojo.uri.Uri(location, args.url).toString();
266
		var ret = {"xml":"", "styles":[], "titles":[], "requires":[], "scripts":[], "url":url};
267
		if (args.content) {
268
			var tmp = null, content = args.content;
269
			if (args.adjustPaths) {
270
				content = _loader.htmlContentAdjustPaths.call(this, content, url);
271
			}
272
			tmp = _loader.htmlContentBasicFix.call(this, content, url);
273
			content = tmp.s;
274
			ret.styles = tmp.styles;
275
			ret.titles = tmp.titles;
276
			if (args.collectRequires || args.collectScripts) {
277
				tmp = _loader.htmlContentScripts.call(this, content, args.collectScripts);
278
				content = tmp.s;
279
				ret.requires = tmp.requires;
280
				ret.scripts = tmp.scripts;
281
			}
282
			var match = [];
283
			if (args.bodyExtract) {
284
				match = content.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
285
				if (match) {
286
					content = match[1];
287
				}
288
			}
289
			ret.xml = content;
290
		}
291
		return ret;
292
	};
293
	this.hookUp = function (args) {
294
		var widget = args.widget;
295
		if (dojo.lang.isString(widget)) {
296
			if (args.mixin) {
297
				dojo.raise(this.toString() + ", cant use mixin when widget is a string");
298
			}
299
			widget = dojo.evalObjPath(widget);
300
		}
301
		if (!widget || !(widget instanceof dojo.widget.HtmlWidget)) {
302
			dojo.raise(this.toString() + " Widget isn't defined or isn't a HtmlWidget instance");
303
		}
304
		if (widget.loader && widget.setUrl) {
305
			return;
306
		}
307
		var widgetProto = (args.mixin) ? widget : widget.constructor.prototype;
308
		widget.loader = {isLoaded:false, styleNodes:[], addOnLoads:[], addOnUnLoads:[], callOnUnLoad:(function (canCall) {
309
			return function (after) {
310
				this.abort();
311
				if (canCall) {
312
					this.onUnLoad();
313
				}
314
				canCall = after;
315
			};
316
		})(false), bindObj:null, unHook:(function (w, wg) {
317
			var oldProps = {isContainer:w.isContainer, adjustPats:w.adjustPaths, href:w.href, extractContent:w.extractContent, parseContent:w.parseContent, cacheContent:w.cacheContent, bindArgs:w.bindArgs, preload:w.preload, refreshOnShow:w.refreshOnShow, handler:w.handler, trackHistory:w.trackHistory, executeScripts:w.executeScripts, scriptScope:w.scriptScope, postCreate:w.postCreate, show:w.show, refresh:w.refresh, loadContents:w.loadContents, abort:w.abort, destroy:w.destroy, onLoad:w.onLoad, onUnLoad:w.onUnLoad, addOnLoad:w.addOnLoad, addOnUnLoad:w.addOnUnLoad, onDownloadStart:w.onDownloadStart, onDownloadEnd:w.onDownloadEnd, onDownloadError:w.onDownloadError, onContentError:w.onContentError, onExecError:w.onExecError, onSetContent:w.onSetContent, setUrl:w.setUrl, setContent:w.setContent, onContentParse:w.onContentParse, onExecScript:w.onExecScript, setHandler:w.setHandler};
318
			return function () {
319
				if (wg.abort) {
320
					wg.abort();
321
				}
322
				if ((w != wg) && (dojo.widget.byType(wg.widgetType).length > 1)) {
323
					return;
324
				}
325
				for (var x in oldProps) {
326
					if (oldProps[x] === undefined) {
327
						delete w[x];
328
						continue;
329
					}
330
					w[x] = oldProps[x];
331
				}
332
				delete wg._loader_defined;
333
				delete wg.loader;
334
			};
335
		})(widgetProto, widget)};
336
		if (widgetProto._loader_defined || widget._loader_defined) {
337
			return;
338
		}
339
		dojo.mixin(widgetProto, {isContainer:true, adjustPaths:undef(widgetProto.adjustPaths) ? true : widgetProto.adjustPaths, href:undef(widgetProto.href) ? "" : widgetProto.href, extractContent:undef(widgetProto.extractContent) ? true : widgetProto.extractContent, parseContent:undef(widgetProto.parseContent) ? true : widgetProto.parseContent, cacheContent:undef(widgetProto.cacheContent) ? true : widgetProto.cacheContent, bindArgs:undef(widgetProto.bindArgs) ? {} : widgetProto.bindArgs, preload:undef(widgetProto.preload) ? false : widgetProto.preload, refreshOnShow:undef(widgetProto.refreshOnShow) ? false : widgetProto.refreshOnShow, handler:undef(widgetProto.handler) ? "" : widgetProto.handler, executeScripts:undef(widgetProto.executeScripts) ? false : widgetProto.executeScripts, trackHistory:undef(widgetProto.tracHistory) ? false : widgetProto.trackHistory, scriptScope:null});
340
		widgetProto.postCreate = (function (postCreate) {
341
			return function () {
342
				if (widgetProto.constructor.superclass.postCreate != postCreate) {
343
					postCreate.apply(this, arguments);
344
				} else {
345
					widgetProto.constructor.superclass.postCreate.apply(this, arguments);
346
				}
347
				if (this.handler !== "") {
348
					this.setHandler(this.handler);
349
				}
350
				if (this.isShowing() || this.preload) {
351
					this.loadContents();
352
					if (!this.href) {
353
						_loader._log(this, (this.domNode || this.containerNode).innerHTML);
354
					}
355
				}
356
			};
357
		})(widgetProto.postCreate);
358
		widgetProto.show = (function (show) {
359
			return function () {
360
				if (this.refreshOnShow) {
361
					this.refresh();
362
				} else {
363
					this.loadContents();
364
				}
365
				if ((widgetProto.constructor.superclass.show == show) || !isFunc(show)) {
366
					widgetProto.constructor.superclass.show.apply(this, arguments);
367
				} else {
368
					show.apply(this, arguments);
369
				}
370
			};
371
		})(widgetProto.show);
372
		widgetProto.destroy = (function (destroy) {
373
			return function (destroy) {
374
				this.onUnLoad();
375
				this.abort();
376
				this.loader.unHook();
377
				if ((widgetProto.constructor.superclass.destroy != destroy) && isFunc(destroy)) {
378
					destroy.apply(this, arguments);
379
				} else {
380
					widgetProto.constructor.superclass.destroy.apply(this, arguments);
381
				}
382
			};
383
		})(widgetProto.destroy);
384
		if (!widgetProto.refresh) {
385
			widgetProto.refresh = function () {
386
				this.loader.isLoaded = false;
387
				this.loadContents();
388
			};
389
		}
390
		if (!widgetProto.loadContents) {
391
			widgetProto.loadContents = function () {
392
				if (this.loader.isLoaded) {
393
					return;
394
				}
395
				if (isFunc(this.handler)) {
396
					runHandler.call(this);
397
				} else {
398
					if (this.href !== "") {
399
						handleDefaults.call(this, "Loading...", "onDownloadStart");
400
						var self = this, url = this.href;
401
						downloader.call(this, {url:url, load:function (type, data, xhr) {
402
							self.onDownloadEnd.call(self, url, data);
403
						}, error:function (type, err, xhr) {
404
							var e = {responseText:xhr.responseText, status:xhr.status, statusText:xhr.statusText, responseHeaders:(xhr.getAllResponseHeaders) ? xhr.getAllResponseHeaders() : [], _text:"Error loading '" + url + "' (" + xhr.status + " " + xhr.statusText + ")"};
405
							handleDefaults.call(self, e, "onDownloadError");
406
							self.onLoad();
407
						}});
408
					}
409
				}
410
			};
411
		}
412
		if (!widgetProto.abort) {
413
			widgetProto.abort = function () {
414
				if (!this.loader || !this.loader.bindObj || !this.loader.bindObj.abort) {
415
					return;
416
				}
417
				this.loader.bindObj.abort();
418
				this.loader.bindObj = null;
419
			};
420
		}
421
		if (!widgetProto.onLoad) {
422
			widgetProto.onLoad = function () {
423
				stackRunner.call(this, this.loader.addOnLoads);
424
				this.loader.isLoaded = true;
425
			};
426
		}
427
		if (!widgetProto.onUnLoad) {
428
			widgetProto.onUnLoad = function () {
429
				stackRunner.call(this, this.loader.addOnUnLoads);
430
				delete this.scriptScope;
431
			};
432
		}
433
		if (!widgetProto.addOnLoad) {
434
			widgetProto.addOnLoad = function (obj, func) {
435
				stackPusher.call(this, this.loader.addOnLoads, obj, func);
436
			};
437
		}
438
		if (!widgetProto.addOnUnLoad) {
439
			widgetProto.addOnUnLoad = function (obj, func) {
440
				stackPusher.call(this, this.loader.addOnUnLoads, obj, func);
441
			};
442
		}
443
		if (!widgetProto.onExecError) {
444
			widgetProto.onExecError = function () {
445
			};
446
		}
447
		if (!widgetProto.onContentError) {
448
			widgetProto.onContentError = function () {
449
			};
450
		}
451
		if (!widgetProto.onDownloadError) {
452
			widgetProto.onDownloadError = function () {
453
			};
454
		}
455
		if (!widgetProto.onDownloadStart) {
456
			widgetProto.onDownloadStart = function (onDownloadStart) {
457
			};
458
		}
459
		if (!widgetProto.onDownloadEnd) {
460
			widgetProto.onDownloadEnd = function (url, data) {
461
				var args = {content:data, url:url, adjustPaths:this.adjustPaths, collectScripts:this.executeScripts, collectRequires:this.parseContent, bodyExtract:this.extractContent};
462
				data = _loader.splitAndFixPaths.call(this, args);
463
				this.setContent(data);
464
			};
465
		}
466
		if (!widgetProto.onSetContent) {
467
			widgetProto.onSetContent = function (cont) {
468
				this.destroyChildren();
469
				var styleNodes = this.loader.styleNodes;
470
				while (styleNodes.length) {
471
					var st = styleNodes.pop();
472
					if (st && st.parentNode) {
473
						st.parentNode.removeChild(st);
474
					}
475
				}
476
				var node = this.containerNode || this.domNode;
477
				while (node.firstChild) {
478
					try {
479
						dojo.event.browser.clean(node.firstChild);
480
					}
481
					catch (e) {
482
					}
483
					node.removeChild(node.firstChild);
484
				}
485
				try {
486
					if (typeof cont != "string") {
487
						node.appendChild(cont);
488
					} else {
489
						try {
490
							node.innerHTML = cont;
491
						}
492
						catch (e) {
493
							var tmp;
494
							(tmp = dojo.doc().createElement("div")).innerHTML = cont;
495
							while (tmp.firstChild) {
496
								node.appendChild(tmp.removeChild(tmp.firstChild));
497
							}
498
						}
499
					}
500
				}
501
				catch (e) {
502
					e._text = "Could'nt load content: " + e;
503
					var useAlert = (this.loader._onSetContent_err == e._text);
504
					this.loader._onSetContent_err = e._text;
505
					handleDefaults.call(this, e, "onContentError", useAlert);
506
				}
507
			};
508
		}
509
		if (!widgetProto.setUrl) {
510
			widgetProto.setUrl = function (url) {
511
				this.href = url;
512
				this.loader.isLoaded = false;
513
				if (this.preload || this.isShowing()) {
514
					this.loadContents();
515
				}
516
			};
517
		}
518
		if (!widgetProto.setContent) {
519
			widgetProto.setContent = function (data, dontLog) {
520
				this.loader.callOnUnLoad.call(this, true);
521
				if (!data || dojo.html.isNode(data)) {
522
					this.onSetContent(data);
523
					refreshed.call(this);
524
				} else {
525
					if (typeof data.xml != "string") {
526
						this.href = "";
527
						var args = {content:data, url:this.href, adjustPaths:this.adjustPaths, collectScripts:this.executeScripts, collectRequires:this.parseContent, bodyExtract:this.extractContent};
528
						data = _loader.splitAndFixPaths.call(this, args);
529
					} else {
530
						if (data.url != "./") {
531
							this.url = data.url;
532
						}
533
					}
534
					this.onSetContent(data.xml);
535
					for (var i = 0, styles = data.styles; i < styles.length; i++) {
536
						if (styles[i].path) {
537
							this.loader.styleNodes.push(dojo.html.insertCssFile(styles[i].path));
538
						} else {
539
							this.loader.styleNodes.push(dojo.html.insertCssText(styles[i]));
540
						}
541
					}
542
					if (this.parseContent) {
543
						for (var i = 0, requires = data.requires; i < requires.length; i++) {
544
							try {
545
								eval(requires[i]);
546
							}
547
							catch (e) {
548
								e._text = "dojo.widget.html.loader.hookUp: error in package loading calls, " + (e.description || e);
549
								handleDefaults.call(this, e, "onContentError", true);
550
							}
551
						}
552
					}
553
					if (dojo.hostenv.isXDomain && data.requires.length) {
554
						dojo.addOnLoad(function () {
555
							asyncParse.call(this, data);
556
							if (!dontLog) {
557
								_loader._log(this, data);
558
							}
559
						});
560
						dontLog = true;
561
					} else {
562
						asyncParse.call(this, data);
563
					}
564
				}
565
				if (!dontLog) {
566
				}
567
			};
568
		}
569
		if (!widgetProto.onContentParse) {
570
			widgetProto.onContentParse = function () {
571
				var node = this.containerNode || this.domNode;
572
				var parser = new dojo.xml.Parse();
573
				var frag = parser.parseElement(node, null, true);
574
				dojo.widget.getParser().createSubComponents(frag, this);
575
			};
576
		}
577
		if (!widgetProto.onExecScript) {
578
			widgetProto.onExecScript = function (scripts) {
579
				var self = this, tmp = "", code = "";
580
				for (var i = 0; i < scripts.length; i++) {
581
					if (scripts[i].path) {
582
						var url = scripts[i].path;
583
						downloader.call(this, {"url":url, "load":function (type, scriptStr) {
584
							(function () {
585
								tmp = scriptStr;
586
								scripts[i] = scriptStr;
587
							}).call(self);
588
						}, "error":function (type, error) {
589
							error._text = type + " downloading remote script";
590
							handleDefaults.call(self, error, "onExecError", true);
591
						}, "mimetype":"text/plain", "sync":true});
592
						code += tmp;
593
					} else {
594
						code += scripts[i];
595
					}
596
				}
597
				try {
598
					delete this.scriptScope;
599
					this.scriptScope = new (new Function("_container_", code + "; return this;"))(self);
600
				}
601
				catch (e) {
602
					e._text = "Error running scripts from content:\n" + (e.description || e.toString());
603
					handleDefaults.call(this, e, "onExecError", true);
604
				}
605
			};
606
		}
607
		if (!widgetProto.setHandler) {
608
			widgetProto.setHandler = function (handler) {
609
				var fcn = dojo.lang.isFunction(handler) ? handler : window[handler];
610
				if (!isFunc(fcn)) {
611
					handleDefaults.call(this, "Unable to set handler, '" + handler + "' not a function.", "onExecError", true);
612
					return;
613
				}
614
				this.handler = function () {
615
					return fcn.apply(this, arguments);
616
				};
617
			};
618
		}
619
		widgetProto._loader_defined = true;
620
	};
621
})();
622