/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.html.loader");

dojo.require("dojo.widget.HtmlWidget");
dojo.require("dojo.io.*");
dojo.require("dojo.lang.common");
dojo.require("dojo.lang.extras");

dojo.require("dojo.experimental");
dojo.experimental("dojo.widget.html.loader");

// as this is a singleton dojo.declare doesn't buy us anything here
dojo.widget.html.loader = new (function(){
	// summary:
	// 	loading stuff moved out of contentpane to make it directly accessible by other widgets
	this.toString = function(){ return "dojo.widget.html.loader"; }
	var _loader = this;

	// back/forward tracking
	dojo.addOnLoad(function(){
		dojo.experimental(_loader.toString());
		var undo = dojo.evalObjPath("dojo.undo.browser");
		if(djConfig["preventBackButtonFix"] && undo && !undo.initialState){
			undo.setInitialState(new trackerObj);
		}
	});

	var logger = {};
	var trackerObj = function(id, data){
		this.id = id;
		this.data = data
	};
	trackerObj.prototype.handle = function(type){
		if(typeof dojo == 'undefined'){ return; } // wtf? how can dojo become undef?
		var wg = dojo.widget.byId(this.id);
		if(wg){ wg.setContent(this.data, true); }
	};

	this._log = function(widget, data){
		// if a loader widget B is a child of loader widget A
		// we need to destroy all of B's undo if we switch content
		if(widget.trackHistory){
			if(!logger[widget.widgetId]){
				logger[widget.widgetId] = { childrenIds: [], stack:[data] };
			}var children = logger[widget.widgetId].childrenIds;
			while(children && children.length){
				delete logger[children.pop()];
			}
			for(var child in widget.children){
				logger[widget.widgetId].childrenIds = child.widgetId;
			}
			dojo.undo.browser.addToHistory(new trackerObj(widget.widgetId, dojo.lang.shallowCopy(data, true)));
		}
	}

	// shortCuts
	var undef = dojo.lang.isUndefined;
	var isFunc = dojo.lang.isFunction;



	/************ private needed functions, no need to be part of widget API ***********/
	// useful if user wants to prevent default behaviour ie: _setContent("Error...")
	function handleDefaults(e, handler, useAlert){
		if(!handler){ handler = "onContentError"; }
		if(dojo.lang.isString(e)){ e = {_text: e}; }
		if(!e._text){ e._text = e.toString(); }
		e.toString = function(){ return this._text; };
		if(typeof e.returnValue != "boolean"){
			e.returnValue = true;
		}
		if(typeof e.preventDefault != "function"){
			e.preventDefault = function(){ this.returnValue = false; };
		}
		// call our handler
		this[handler](e);
		if(e.returnValue){
			if(useAlert){
				alert(e.toString());
			}else{
				this.loader.callOnUnLoad.call(this, false);
				this.onSetContent(e.toString());
			}
		}
	};

	// set up downloader, used by both scripts and content
	function downloader(bindArgs) {
		for(var x in this.bindArgs){
			bindArgs[x] = (undef(bindArgs[x]) ? this.bindArgs[x] : undefined);
		}
		var cache = this.cacheContent;
		if(undef(bindArgs.useCache)){ bindArgs.useCache = cache; }
		if(undef(bindArgs.preventCache)){ bindArgs.preventCache = !cache; }
		if(undef(bindArgs.mimetype)){ bindArgs.mimetype = "text/html"; }
		this.loader.bindObj = dojo.io.bind(bindArgs);
	};

	// runs addOnLoad/addOnUnLoad functions
	function stackRunner(st){
		var err = "", func = null;
		var scope = this.scriptScope || dojo.global();
		while(st.length){
			func = st.shift();
			try{
				func.call(scope);
			}catch(e){
				err += "\n"+func+" failed: "+e;
			}
		}
		if(err.length){
			var name = (st== this.loader.addOnLoads) ? "addOnLoad" : "addOnUnLoad";
			handleDefaults.call(this, name+" failure\n "+err, "onExecError", true);
		}
	};

	// push addOnLoad and addOnUnLoad functions onto stack
	function stackPusher(st, obj, func){
		if(typeof func == 'undefined') {
			st.push(obj);
		}else{
			st.push(function(){ obj[func](); });
		}
	};

	// code saver, collects onLoad, onResized and isLoaded
	function refreshed(){
		this.onResized();
		this.onLoad();
		this.isLoaded = true;
	};

	// runs scripts and starts the content parser
	function asyncParse(data){
		if(this.executeScripts){
			this.onExecScript.call(this, data.scripts);
		}
		if(this.parseContent){
			this.onContentParse.call(this);
		}
		refreshed.call(this);
	};

	// run java function
	function runHandler(){
		//FIXME: current behaviour is to return false if handler is there; is that intended?
		if(dojo.lang.isFunction(this.handler)) {
			this.handler(this, this.containerNode||this.domNode);
			refreshed.call(this);
			return false;
		}
		return true;
	};

	// divided up splitAndFixPaths in different parts
	this.htmlContentBasicFix = function(/*string*/s, /*string||dojo.uri.Uri*/url){
		// summary:
		//	strips out <style, <link rel=stylesheet and <title tags
		//	intended to take out tags that might cause DOM faults
		var titles = [], styles = [];
		/************** <title> ***********/
		// khtml can't attach a <style> or <title> node as child of body
		var regex = /<title[^>]*>([\s\S]*?)<\/title>/i;
		var match, attr;
		while(match = regex.exec(s)){
			titles.push(match[1]);
			s = s.substring(0, match.index) + s.substr(match.index + match[0].length);
		};
		/****************  cut out all <style> and <link rel="stylesheet" href=".."> **************/
		regex = /(?:<(style)[^>]*>([\s\S]*?)<\/style>|<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>)/i;
		while(match = regex.exec(s)){
			if(match[1] && match[1].toLowerCase() == "style"){
				styles.push(dojo.html.fixPathsInCssText(match[2],url));
			}else if(attr = match[3].match(/href=(['"]?)([^'">]*)\1/i)){
				styles.push({path: attr[2]});
			}
			s = s.substring(0, match.index) + s.substr(match.index + match[0].length);
		};
		return {'s': s, 'titles': titles, 'styles': styles};//object
	};

	this.htmlContentAdjustPaths = function(/*string*/s, /*string||dojo.uri.Uri*/url){
		// summary:
		//	adjusts relative paths in content to be relative to current page
		var tag = "", str = "", tagFix = "", path = "";
		var attr = [], origPath = "", fix = "";

		// attributepaths one tag can have multiple paths example:
		// <input src="..." style="url(..)"/> or <a style="url(..)" href="..">
		// strip out the tag and run fix on that.
		// this guarantees that we won't run replace on another tag's attribute + it was easier do
		var regexFindTag = /<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i;
		var regexFindAttr = /\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i;
		// these are the supported protocols, all other is considered relative
		var regexProtocols = /^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/;

		while(tag = regexFindTag.exec(s)){
			str += s.substring(0, tag.index);
			s = s.substring((tag.index + tag[0].length), s.length);
			tag = tag[0];

			// loop through attributes
			tagFix = '';
			while(attr = regexFindAttr.exec(tag)){
				path = ""; origPath = attr[3];
				switch(attr[1].toLowerCase()){
					case "src":// falltrough
					case "href":
						if(regexProtocols.exec(origPath)){
							path = origPath;
						} else {
							path = (new dojo.uri.Uri(url, origPath).toString());
						}
						break;
					case "style":// style
						path = dojo.html.fixPathsInCssText(origPath, url);
						break;
					default:
						path = origPath;
				}

				fix = " " + attr[1] + "=" + attr[2] + path + attr[2];

				// slices up tag before next attribute check
				tagFix += tag.substring(0, attr.index) + fix;
				tag = tag.substring((attr.index + attr[0].length), tag.length);
			}
			str += tagFix + tag;
		}
		return str+s; // string
	};


	this.htmlContentScripts = function(/*string*/s, /*boolean*/collectScripts){
		// summary:
		// 	handles scripts and dojo .require(...) etc calls
		// NOTE: we need to go through here even if we have executeScripts=false
		//		 and if we have parseWidgets true
		var scripts = [], requires = [], match = [];
		var attr = "", tmp = null, tag = "", sc = "", str = "";

		/***************** cut out all <script> tags, push them into scripts array ***************/
		var regex = /<script([^>]*)>([\s\S]*?)<\/script>/i;
		var regexSrc = /src=(['"]?)([^"']*)\1/i;
		var regexDojoJs = /.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/;
		var regexInvalid = /(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g;
		var regexRequires = /dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix)|defineNamespace)\((['"]).*?\1\)\s*;?/;

		while(match = regex.exec(s)){
			if(this.executeScripts && match[1]){
				if(attr = regexSrc.exec(match[1])){
					// remove a dojo.js or dojo.js.uncompressed.js from remoteScripts
					// we declare all files named dojo.js as bad, regardless of path
					if(regexDojoJs.exec(attr[2])){
						dojo.debug("Security note! inhibit:"+attr[2]+" from  beeing loaded again.");
					}else{
						scripts.push({path: attr[2]});
					}
				}
			}
			if(match[2]){
				// remove all invalid variables etc like djConfig and dojo.hostenv.writeIncludes()
				sc = match[2].replace(regexInvalid, "");
				if(!sc){ continue; }

				// cut out all dojo .require (...) calls, if we have execute
				// scripts false widgets don't get their require calls
				// takes out possible widgetpackage registration as well
				while(tmp = regexRequires.exec(sc)){
					requires.push(tmp[0]);
					sc = sc.substring(0, tmp.index) + sc.substr(tmp.index + tmp[0].length);
				}
				if(collectScripts){
					scripts.push(sc);
				}
			}
			s = s.substr(0, match.index) + s.substr(match.index + match[0].length);
		}
		/******** scan for scriptScope in html eventHandlers
					and replace with link to this widget *********/
		if(collectScripts){
			var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*\S=(['"])[^>]*[^\.\]])scriptScope([^>]*>)/;
			str = "";
			while(tag = regex.exec(s)){
				tmp = ((tag[2]=="'") ? '"': "'");
				str += s.substring(0, tag.index);
				s = s.substr(tag.index).replace(regex, "$1dojo.widget.byId("+ tmp + this.widgetId + tmp + ").scriptScope$3");
			}
			s = str + s;
		}
		return {'s': s, 'requires': requires, 'scripts': scripts}; // object
	};


	this.splitAndFixPaths = function(/*object*/args){
		// summary:
		//	pathfixes, require calls, css stuff and neccesary content clean
		// args:
		//	content 		string
		//	url 			string? or dojo.uri.Uri that that pulled the content in, for path adjust
		//	adjustPaths		boolean, if true adjust relative paths in content to match this page
		//	collectScripts	boolean, if true it takes out all <script and <script src=.. tags and collects
		//					 dojo.require calls in a separate array, useful for eval
		//	collectRequires	boolean, if true and collectScripts is false it still collects scripts along with
		//					 dojo.require calls
		//	bodyExtract		boolean, if true only return content inside of the body tag

		// return:			{xml: string,
		//					styles: array, remote style get object {path: /*string*/url}
		//					requires: array,
		//					scripts: array, remote scripts get object {path: /*string*/url}
		//					url: string}
		if(!args.url) { args.url = "./"; } // point to this page if not set
		// make sure back/forward buttons don't mess up url.
		url = new dojo.uri.Uri(location, args.url).toString();
		var ret = {'xml': 	"",
				'styles':	[],
				'titles':	[],
				'requires':	[],
				'scripts':	[],
				'url':		url };

		if(args.content){ // make sure we don't run regexes on empty content
			var tmp = null, content = args.content;
			if(args.adjustPaths){
				content = _loader.htmlContentAdjustPaths.call(this, content, url);
			}

			tmp = _loader.htmlContentBasicFix.call(this, content, url);
			content = tmp.s;
			ret.styles = tmp.styles;
			ret.titles = tmp.titles;

			if(args.collectRequires || args.collectScripts){
				tmp = _loader.htmlContentScripts.call(this, content, args.collectScripts);
				content = tmp.s;
				ret.requires = tmp.requires;
				ret.scripts = tmp.scripts;
			}

			/********* extract content *********/
			var match = [];
			if(args.bodyExtract){
				match = content.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
				if(match) { content = match[1]; }
			}
			ret.xml = content;
		}
		return ret;// object
	};


	// the all important startup function
	this.hookUp = function(/*object*/args){
		// summary:
		// 	mixin or extend loader into a widget
		// args:
		//	widget: widget reference
		//	mixin: boolean, default false
		// 		if mixin true, it will only extend the current widget, not its prototype
		var widget = args.widget;
		if(dojo.lang.isString(widget)){
			if(args.mixin){
				dojo.raise(this.toString()+", cant use mixin when widget is a string");
			 }
			widget = dojo.evalObjPath(widget);
		}
		if(!widget || !(widget instanceof dojo.widget.HtmlWidget)){
			dojo.raise(this.toString()+" Widget isn't defined or isn't a HtmlWidget instance");
		}
		// make sure we don't mixin more than once
		if(widget.loader && widget.setUrl){ return; }

		// extend widget prototype or mixin this widget instance
		var widgetProto = (args.mixin) ? widget : widget.constructor.prototype;

		/********************************************
		** per widgetImpl variables, mixin into widget
		********************************************/
		// stuff it into a loader obj
		widget.loader = {
			isLoaded: false,
			styleNodes:  [],
			addOnLoads: [],
			addOnUnLoads: [],
			callOnUnLoad:(function(canCall){
							return function(after){ this.abort();
								if(canCall){ this.onUnLoad(); }
								canCall = after;
							};
						})(false),
			bindObj: null,
			// to disconnect widget
			unHook: (function(w, wg){
				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,
					// functions
					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
				};
				return function(){
					if(wg.abort){ wg.abort(); }
					// make sure we don't unhook prototype if there are more widgets of this type left
					if((w != wg) && (dojo.widget.byType(wg.widgetType).length>1)){ return; }
					for(var x in oldProps){
						if(oldProps[x]===undefined){
							delete w[x]; continue;
						}
						w[x] = oldProps[x];
					}
					delete wg._loader_defined;
					delete wg.loader;
				};
			})(widgetProto, widget)
		};

		// make sure we don't do this more than once per widget/widgetprototype
		if(widgetProto._loader_defined || widget._loader_defined){ return; }

		/**************** private variables *********************/

		// loading options, prototype parts of widget's mixin to prototype
		dojo.mixin(widgetProto, {
			// always set to a containerwidget
			isContainer: true,
			// fix relative paths in content to fit into this page
			adjustPaths: 	undef(widgetProto.adjustPaths) ? true : widgetProto.adjustPaths,
			// only usable on construction, use setUrl or setContent after that
			href: 			undef(widgetProto.href) ? "" : widgetProto.href,
			// extract visible content from inside of <body> .... </body>
			extractContent: undef(widgetProto.extractContent) ? true : widgetProto.extractContent,
			// construct all widgets that is in content
			// FIXME: rename to parseWidgets?
			parseContent: 	undef(widgetProto.parseContent) ? true : widgetProto.parseContent,
			// use io binds javascript cache, or if false, prevent browsercache
			cacheContent: 	undef(widgetProto.cacheContent) ? true : widgetProto.cacheContent,
			// specify  specific  io.bind arguments such as transport and useCache
			bindArgs:		undef(widgetProto.bindArgs) ? {} : widgetProto.bindArgs,
			// force load even if widget isn't shown (lazyload setting)
			preload: 		undef(widgetProto.preload) ? false : widgetProto.preload,
			// reload content automatically onShow, use with cacheContent = flase
			refreshOnShow:	undef(widgetProto.refreshOnShow) ? false : widgetProto.refreshOnShow,
			// name of java function which should generate content
			handler: 		undef(widgetProto.handler) ? "" : widgetProto.handler,
			// if true scripts in content will be evaled after content is innerHTML'ed
			executeScripts: undef(widgetProto.executeScripts) ? false : widgetProto.executeScripts,
			// log contents (back/forward support)
			trackHistory:	undef(widgetProto.tracHistory) ? false : widgetProto.trackHistory,
			scriptScope: null // always overwrite
		});

		/****************************************************
		******* public functions, becomes part of widget's API
		*****************************************************/

		/*********** Public functions that wigets cant overide **********/
		// set up postCreate, call originalcode before our own
		widgetProto.postCreate = (function(postCreate){
			return function(){
				if(widgetProto.constructor.superclass.postCreate != postCreate){
					postCreate.apply(this, arguments);
				}else{
					widgetProto.constructor.superclass.postCreate.apply(this, arguments);
				}
				if(this.handler!==""){ this.setHandler(this.handler); }
				if(this.isShowing() || this.preload){
					this.loadContents();
					if(!this.href){ // back/forward save initial state
						_loader._log(this,(this.domNode||this.containerNode).innerHTML);
					}
				}
			}
		})(widgetProto.postCreate);

		// set up onShow listener, call original code after this block
		widgetProto.show = (function(show){
			return function(){
				// if refreshOnShow is true, reload the contents every time; otherwise, load only the first time
				if(this.refreshOnShow){
					this.refresh();
				}else{
					this.loadContents();
				}
				if((widgetProto.constructor.superclass.show == show) || !isFunc(show)){
					widgetProto.constructor.superclass.show.apply(this, arguments);
				}else{
					show.apply(this, arguments);
				}
			};
		})(widgetProto.show);

		// destroy cleanups, original code in the middle
		widgetProto.destroy = (function(destroy){
			return function(destroy){
				this.onUnLoad();
				this.abort();
				this.loader.unHook();
				if((widgetProto.constructor.superclass.destroy != destroy) && isFunc(destroy)){
					destroy.apply(this, arguments);
				}else{
					widgetProto.constructor.superclass.destroy.apply(this, arguments);
				}
			}
		})(widgetProto.destroy);


		/******* Public functions that widgets can overide *****/
		// set up a refresh function
		if(!widgetProto.refresh){
			widgetProto.refresh = function(){
				this.loader.isLoaded = false;
				this.loadContents();
			};
		}

		// set up html loading contents
		if(!widgetProto.loadContents){
			widgetProto.loadContents = function(){
				if(this.loader.isLoaded){ return; }
				// javafunction
				if(isFunc(this.handler)){
					runHandler.call(this);
				}else if(this.href !== ""){
					handleDefaults.call(this, "Loading...", "onDownloadStart");
					var self = this, url = this.href;
					downloader.call(this, {
						url: url,
						load: function(type, data, xhr){
							self.onDownloadEnd.call(self, url, data);
						},
						error: function(type, err, xhr){
							// XHR insnt a normal JS object, copy esentials
							var e = {
								responseText: xhr.responseText,
								status: xhr.status,
								statusText: xhr.statusText,
								responseHeaders: (xhr.getAllResponseHeaders) ? xhr.getAllResponseHeaders():[],
								_text: "Error loading '" + url + "' (" + xhr.status + " "+  xhr.statusText + ")"
							};
							handleDefaults.call(self, e, "onDownloadError");
							self.onLoad();
						}
					});
				}
			};
		}

		// set up abort
		if(!widgetProto.abort){
			widgetProto.abort = function(){
				if(!this.loader || !this.loader.bindObj || !this.loader.bindObj.abort){ return; }
				this.loader.bindObj.abort();
				this.loader.bindObj = null;
			};
		}

		// onLoad
		if(!widgetProto.onLoad){
			widgetProto.onLoad = function(){
				stackRunner.call(this, this.loader.addOnLoads);
				this.loader.isLoaded = true;
			};
		}

		// onUnLoad, original code in the middle
		if(!widgetProto.onUnLoad){
			widgetProto.onUnLoad = function(){
				stackRunner.call(this, this.loader.addOnUnLoads);
				delete this.scriptScope;
			}
		}

		// add to onLoad queue
		if(!widgetProto.addOnLoad){
			widgetProto.addOnLoad = function(obj, func){
				stackPusher.call(this, this.loader.addOnLoads, obj, func);
			};
		}

		// add to onUnLoad queue
		if(!widgetProto.addOnUnLoad){
			widgetProto.addOnUnLoad = function(obj, func){
				stackPusher.call(this, this.loader.addOnUnLoads, obj, func);
			}
		}

		// script or java errors, preventDefault-able
		if(!widgetProto.onExecError){
			widgetProto.onExecError = function(){/*stub*/};
		}

		// called on DOM faults, require fault etc in content, preventDefault-able
		if(!widgetProto.onContentError){
			widgetProto.onContentError = function(){/*stub*/};
		}

		// called when download error occurs, preventDefault-able
		if(!widgetProto.onDownloadError){
			widgetProto.onDownloadError = function(){/*stub*/};
		}

		// called before download starts, preventDefault-able
		if(!widgetProto.onDownloadStart){
			widgetProto.onDownloadStart = function(onDownloadStart){/*stub*/};
		}

		// called when download is finished successfully
		if(!widgetProto.onDownloadEnd){
			widgetProto.onDownloadEnd = function(url, data){
				var args =  {content: data,
							url: url,
							adjustPaths: this.adjustPaths,
							collectScripts: this.executeScripts,
							collectRequires: this.parseContent,
							bodyExtract: this.extractContent };
				data = _loader.splitAndFixPaths.call(this, args);
				this.setContent(data);
			}
		}

		// previously called _setContent, widget defined onSetContent can modify content or cancel
		if(!widgetProto.onSetContent){
			widgetProto.onSetContent = function(cont){
				this.destroyChildren();

				// remove old stylenodes from HEAD
				var styleNodes = this.loader.styleNodes;
				while(styleNodes.length){
					var st = styleNodes.pop();
					if(st && st.parentNode){
						st.parentNode.removeChild(st);
					}
				}

				var node = this.containerNode || this.domNode;
				while(node.firstChild){
					try{
						dojo.event.browser.clean(node.firstChild);
					}catch(e){}
					node.removeChild(node.firstChild);
				}
				try{
					if(typeof cont != "string"){
						node.appendChild(cont);
					}else{
						try{// hack to deal with domfaults, ie. appending div to tablenodes
							node.innerHTML = cont;
						}catch(e){var tmp;
							(tmp = dojo.doc().createElement("div")).innerHTML = cont;
							while(tmp.firstChild){
								node.appendChild(tmp.removeChild(tmp.firstChild));
							}
						}
					}
				}catch(e){
					e._text = "Could'nt load content: "+e;
					var useAlert = (this.loader._onSetContent_err == e._text); // make sure we don't loop
					this.loader._onSetContent_err = e._text;
					handleDefaults.call(this, e, "onContentError", useAlert);
				}
			};
		}

		if(!widgetProto.setUrl){
			widgetProto.setUrl = function(url){
				this.href = url;
				this.loader.isLoaded = false;
				if ( this.preload || this.isShowing() ){
					this.loadContents();
				}
			}
		}

		if(!widgetProto.setContent){
			widgetProto.setContent = function(data, dontLog){
				this.loader.callOnUnLoad.call(this, true);

				if(!data||dojo.html.isNode(data)){
					this.onSetContent(data);
					refreshed.call(this);
				}else{
					// need to run splitAndFixPaths? ie. manually setting content
					// adjustPaths is taken care of inside splitAndFixPaths
					if(typeof data.xml != 'string'){
						this.href = ""; // so we can refresh safely
						var args =  {content: data,
							url: this.href,
							adjustPaths: this.adjustPaths,
							collectScripts: this.executeScripts,
							collectRequires: this.parseContent,
							bodyExtract: this.extractContent };
						data = _loader.splitAndFixPaths.call(this, args);
					}else if(data.url!="./"){
						 this.url = data.url;// backbutton thing
					}
					this.onSetContent(data.xml);

					// insert styles from content (in same order they came in)
					for(var i = 0, styles = data.styles; i < styles.length; i++){
						if(styles[i].path){
							this.loader.styleNodes.push(dojo.html.insertCssFile(styles[i].path));
						}else{
							this.loader.styleNodes.push(dojo.html.insertCssText(styles[i]));
						}
					}

					if(this.parseContent){
						for(var i = 0, requires = data.requires; i < requires.length; i++){
							try{
								eval(requires[i]);
							} catch(e){
								e._text = "dojo.widget.html.loader.hookUp: error in package loading calls, "+(e.description||e);
								handleDefaults.call(this, e, "onContentError", true);
							}
						}
					}
					// need to allow async load, Xdomain uses it
					// NOTE: on Xdomain loads this can break the sync thread of setContent
					// 		if you you do any dojo. require(...) etc
					if(dojo.hostenv.isXDomain && data.requires.length){
						dojo.addOnLoad(function(){
							asyncParse.call(this, data);
							if(!dontLog){
								_loader._log(this, data);
							}
						});// this opens a thread need abort undo
						dontLog = true;
					}else{
						asyncParse.call(this, data);
					}
				}if(!dontLog){
// 					_loader._log(this, data);
				}
			};
		}

		if(!widgetProto.onContentParse){
			widgetProto.onContentParse = function(){
				var node = this.containerNode || this.domNode;
				var parser = new dojo.xml.Parse();
				var frag = parser.parseElement(node, null, true);
				dojo.widget.getParser().createSubComponents(frag, this);
			};
		}

		// previously called _executeScripts
		if(!widgetProto.onExecScript){
			widgetProto.onExecScript = function(scripts){
				// loop through the scripts in the order they came in
				var self = this, tmp = "", code = "";
				for(var i = 0; i < scripts.length; i++){ // remotescript
					if(scripts[i].path){
						var url = scripts[i].path;
						downloader.call(this,{
							'url': 		url,
							'load': function(type, scriptStr){
								(function(){tmp = scriptStr; scripts[i] = scriptStr;}).call(self);
							},
							'error': function(type, error){
								error._text = type + " downloading remote script";
								handleDefaults.call(self, error, "onExecError", true);
							},
							'mimetype': "text/plain",
							'sync':     true
						});
						code += tmp;
					}else{
						code += scripts[i];
					}
				}

				try{
					// initialize a new anonymous container for our script, don't make it part of this widget's scope chain
					// instead send in a variable that points to this widget, useful to connect events to onLoad, onUnLoad etc..
					delete this.scriptScope;
					this.scriptScope = new (new Function('_container_', code+'; return this;'))(self);
				}catch(e){
					e._text = "Error running scripts from content:\n"+(e.description||e.toString());
					handleDefaults.call(this, e, "onExecError", true);
				}
			};
		}

		// Generate content from given java function
		if(!widgetProto.setHandler){
			widgetProto.setHandler = function(handler) {
				var fcn = dojo.lang.isFunction(handler) ? handler : window[handler];
				if(!isFunc(fcn)) {
					// FIXME: needs testing! somebody with java knowledge needs to try this
					handleDefaults.call(this, "Unable to set handler, '" + handler + "' not a function.", "onExecError", true);
					return;
				}
				this.handler = function() {
					return fcn.apply(this, arguments);
				};
			};
		}

		// make sure we extend this widget only once
		widgetProto._loader_defined = true;
	};


})();
