📄 loader.js
字号:
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, don'tLog){ 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(!don'tLog){ _loader._log(this, data); } });// this opens a thread need abort undo don'tLog = true; }else{ asyncParse.call(this, data); } }if(!don'tLog){// _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; };})();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -