From 81bea17aefb26859f825b9293c7c99192874806e Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Tue, 8 Nov 2011 20:40:44 +0400 Subject: upgrade Dojo to 1.6.1 --- lib/dijit/layout/ContentPane.js | 860 +++++++++++++++++++++++++++------------- 1 file changed, 581 insertions(+), 279 deletions(-) (limited to 'lib/dijit/layout/ContentPane.js') diff --git a/lib/dijit/layout/ContentPane.js b/lib/dijit/layout/ContentPane.js index 56952800a..399ec1bc9 100644 --- a/lib/dijit/layout/ContentPane.js +++ b/lib/dijit/layout/ContentPane.js @@ -1,291 +1,593 @@ /* - Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + 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 */ -if(!dojo._hasResource["dijit.layout.ContentPane"]){ -dojo._hasResource["dijit.layout.ContentPane"]=true; +if(!dojo._hasResource["dijit.layout.ContentPane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.layout.ContentPane"] = true; dojo.provide("dijit.layout.ContentPane"); dojo.require("dijit._Widget"); -dojo.require("dijit._Contained"); -dojo.require("dijit.layout._LayoutWidget"); -dojo.require("dojo.parser"); +dojo.require("dijit.layout._ContentPaneResizeMixin"); dojo.require("dojo.string"); dojo.require("dojo.html"); -dojo.requireLocalization("dijit","loading",null,"ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw"); -dojo.declare("dijit.layout.ContentPane",dijit._Widget,{href:"",extractContent:false,parseOnLoad:true,preventCache:false,preload:false,refreshOnShow:false,loadingMessage:"${loadingState}",errorMessage:"${errorState}",isLoaded:false,baseClass:"dijitContentPane",doLayout:true,ioArgs:{},isContainer:true,isLayoutContainer:true,onLoadDeferred:null,attributeMap:dojo.delegate(dijit._Widget.prototype.attributeMap,{title:[]}),postMixInProperties:function(){ -this.inherited(arguments); -var _1=dojo.i18n.getLocalization("dijit","loading",this.lang); -this.loadingMessage=dojo.string.substitute(this.loadingMessage,_1); -this.errorMessage=dojo.string.substitute(this.errorMessage,_1); -if(!this.href&&this.srcNodeRef&&this.srcNodeRef.innerHTML){ -this.isLoaded=true; -} -},buildRendering:function(){ -this.inherited(arguments); -if(!this.containerNode){ -this.containerNode=this.domNode; -} -},postCreate:function(){ -this.domNode.title=""; -if(!dojo.attr(this.domNode,"role")){ -dijit.setWaiRole(this.domNode,"group"); -} -dojo.addClass(this.domNode,this.baseClass); -},startup:function(){ -if(this._started){ -return; -} -var _2=dijit._Contained.prototype.getParent.call(this); -this._childOfLayoutWidget=_2&&_2.isLayoutContainer; -this._needLayout=!this._childOfLayoutWidget; -if(this.isLoaded){ -dojo.forEach(this.getChildren(),function(_3){ -_3.startup(); -}); -} -if(this._isShown()||this.preload){ -this._onShow(); -} -this.inherited(arguments); -},_checkIfSingleChild:function(){ -var _4=dojo.query("> *",this.containerNode).filter(function(_5){ -return _5.tagName!=="SCRIPT"; -}),_6=_4.filter(function(_7){ -return dojo.hasAttr(_7,"dojoType")||dojo.hasAttr(_7,"widgetId"); -}),_8=dojo.filter(_6.map(dijit.byNode),function(_9){ -return _9&&_9.domNode&&_9.resize; -}); -if(_4.length==_6.length&&_8.length==1){ -this._singleChild=_8[0]; -}else{ -delete this._singleChild; -} -dojo.toggleClass(this.containerNode,this.baseClass+"SingleChild",!!this._singleChild); -},setHref:function(_a){ -dojo.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use set('href', ...) instead.","","2.0"); -return this.set("href",_a); -},_setHrefAttr:function(_b){ -this.cancel(); -this.onLoadDeferred=new dojo.Deferred(dojo.hitch(this,"cancel")); -this.href=_b; -if(this._created&&(this.preload||this._isShown())){ -this._load(); -}else{ -this._hrefChanged=true; -} -return this.onLoadDeferred; -},setContent:function(_c){ -dojo.deprecated("dijit.layout.ContentPane.setContent() is deprecated. Use set('content', ...) instead.","","2.0"); -this.set("content",_c); -},_setContentAttr:function(_d){ -this.href=""; -this.cancel(); -this.onLoadDeferred=new dojo.Deferred(dojo.hitch(this,"cancel")); -this._setContent(_d||""); -this._isDownloaded=false; -return this.onLoadDeferred; -},_getContentAttr:function(){ -return this.containerNode.innerHTML; -},cancel:function(){ -if(this._xhrDfd&&(this._xhrDfd.fired==-1)){ -this._xhrDfd.cancel(); -} -delete this._xhrDfd; -this.onLoadDeferred=null; -},uninitialize:function(){ -if(this._beingDestroyed){ -this.cancel(); -} -this.inherited(arguments); -},destroyRecursive:function(_e){ -if(this._beingDestroyed){ -return; -} -this.inherited(arguments); -},resize:function(_f,_10){ -if(!this._wasShown){ -this._onShow(); -} -this._resizeCalled=true; -if(_f){ -dojo.marginBox(this.domNode,_f); -} -var cn=this.containerNode; -if(cn===this.domNode){ -var mb=_10||{}; -dojo.mixin(mb,_f||{}); -if(!("h" in mb)||!("w" in mb)){ -mb=dojo.mixin(dojo.marginBox(cn),mb); -} -this._contentBox=dijit.layout.marginBox2contentBox(cn,mb); -}else{ -this._contentBox=dojo.contentBox(cn); -} -this._layoutChildren(); -},_isShown:function(){ -if(this._childOfLayoutWidget){ -if(this._resizeCalled&&"open" in this){ -return this.open; -} -return this._resizeCalled; -}else{ -if("open" in this){ -return this.open; -}else{ -var _11=this.domNode; -return (_11.style.display!="none")&&(_11.style.visibility!="hidden")&&!dojo.hasClass(_11,"dijitHidden"); -} -} -},_onShow:function(){ -if(this.href){ -if(!this._xhrDfd&&(!this.isLoaded||this._hrefChanged||this.refreshOnShow)){ -this.refresh(); -} -}else{ -if(!this._childOfLayoutWidget&&this._needLayout){ -this._layoutChildren(); -} -} -this.inherited(arguments); -this._wasShown=true; -},refresh:function(){ -this.cancel(); -this.onLoadDeferred=new dojo.Deferred(dojo.hitch(this,"cancel")); -this._load(); -return this.onLoadDeferred; -},_load:function(){ -this._setContent(this.onDownloadStart(),true); -var _12=this; -var _13={preventCache:(this.preventCache||this.refreshOnShow),url:this.href,handleAs:"text"}; -if(dojo.isObject(this.ioArgs)){ -dojo.mixin(_13,this.ioArgs); -} -var _14=(this._xhrDfd=(this.ioMethod||dojo.xhrGet)(_13)); -_14.addCallback(function(_15){ -try{ -_12._isDownloaded=true; -_12._setContent(_15,false); -_12.onDownloadEnd(); -} -catch(err){ -_12._onError("Content",err); -} -delete _12._xhrDfd; -return _15; -}); -_14.addErrback(function(err){ -if(!_14.canceled){ -_12._onError("Download",err); -} -delete _12._xhrDfd; -return err; -}); -delete this._hrefChanged; -},_onLoadHandler:function(_16){ -this.isLoaded=true; -try{ -this.onLoadDeferred.callback(_16); -this.onLoad(_16); -} -catch(e){ -console.error("Error "+this.widgetId+" running custom onLoad code: "+e.message); -} -},_onUnloadHandler:function(){ -this.isLoaded=false; -try{ -this.onUnload(); -} -catch(e){ -console.error("Error "+this.widgetId+" running custom onUnload code: "+e.message); -} -},destroyDescendants:function(){ -if(this.isLoaded){ -this._onUnloadHandler(); -} -var _17=this._contentSetter; -dojo.forEach(this.getChildren(),function(_18){ -if(_18.destroyRecursive){ -_18.destroyRecursive(); -} -}); -if(_17){ -dojo.forEach(_17.parseResults,function(_19){ -if(_19.destroyRecursive&&_19.domNode&&_19.domNode.parentNode==dojo.body()){ -_19.destroyRecursive(); -} -}); -delete _17.parseResults; -} -dojo.html._emptyNode(this.containerNode); -delete this._singleChild; -},_setContent:function(_1a,_1b){ -this.destroyDescendants(); -var _1c=this._contentSetter; -if(!(_1c&&_1c instanceof dojo.html._ContentSetter)){ -_1c=this._contentSetter=new dojo.html._ContentSetter({node:this.containerNode,_onError:dojo.hitch(this,this._onError),onContentError:dojo.hitch(this,function(e){ -var _1d=this.onContentError(e); -try{ -this.containerNode.innerHTML=_1d; -} -catch(e){ -console.error("Fatal "+this.id+" could not change content due to "+e.message,e); -} -})}); -} -var _1e=dojo.mixin({cleanContent:this.cleanContent,extractContent:this.extractContent,parseContent:this.parseOnLoad,dir:this.dir,lang:this.lang},this._contentSetterParams||{}); -dojo.mixin(_1c,_1e); -_1c.set((dojo.isObject(_1a)&&_1a.domNode)?_1a.domNode:_1a); -delete this._contentSetterParams; -if(!_1b){ -dojo.forEach(this.getChildren(),function(_1f){ -if(!this.parseOnLoad||_1f.getParent){ -_1f.startup(); -} -},this); -this._scheduleLayout(); -this._onLoadHandler(_1a); -} -},_onError:function(_20,err,_21){ -this.onLoadDeferred.errback(err); -var _22=this["on"+_20+"Error"].call(this,err); -if(_21){ -console.error(_21,err); -}else{ -if(_22){ -this._setContent(_22,true); -} -} -},_scheduleLayout:function(){ -if(this._isShown()){ -this._layoutChildren(); -}else{ -this._needLayout=true; -} -},_layoutChildren:function(){ -if(this.doLayout){ -this._checkIfSingleChild(); -} -if(this._singleChild&&this._singleChild.resize){ -var cb=this._contentBox||dojo.contentBox(this.containerNode); -this._singleChild.resize({w:cb.w,h:cb.h}); -}else{ -dojo.forEach(this.getChildren(),function(_23){ -if(_23.resize){ -_23.resize(); -} +dojo.requireLocalization("dijit", "loading", null, "ROOT,ar,ca,cs,da,de,el,es,fi,fr,he,hu,it,ja,kk,ko,nb,nl,pl,pt,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-tw"); + + +dojo.declare( + "dijit.layout.ContentPane", [dijit._Widget, dijit.layout._ContentPaneResizeMixin], +{ + // summary: + // A widget containing an HTML fragment, specified inline + // or by uri. Fragment may include widgets. + // + // description: + // This widget embeds a document fragment in the page, specified + // either by uri, javascript generated markup or DOM reference. + // Any widgets within this content are instantiated and managed, + // but laid out according to the HTML structure. Unlike IFRAME, + // ContentPane embeds a document fragment as would be found + // inside the BODY tag of a full HTML document. It should not + // contain the HTML, HEAD, or BODY tags. + // For more advanced functionality with scripts and + // stylesheets, see dojox.layout.ContentPane. This widget may be + // used stand alone or as a base class for other widgets. + // ContentPane is useful as a child of other layout containers + // such as BorderContainer or TabContainer, but note that those + // widgets can contain any widget as a child. + // + // example: + // Some quick samples: + // To change the innerHTML: cp.set('content', 'new content') + // + // Or you can send it a NodeList: cp.set('content', dojo.query('div [class=selected]', userSelection)) + // + // To do an ajax update: cp.set('href', url) + + // href: String + // The href of the content that displays now. + // Set this at construction if you want to load data externally when the + // pane is shown. (Set preload=true to load it immediately.) + // Changing href after creation doesn't have any effect; Use set('href', ...); + href: "", + +/*===== + // content: String || DomNode || NodeList || dijit._Widget + // The innerHTML of the ContentPane. + // Note that the initialization parameter / argument to set("content", ...) + // can be a String, DomNode, Nodelist, or _Widget. + content: "", +=====*/ + + // extractContent: Boolean + // Extract visible content from inside of .... . + // I.e., strip and (and it's contents) from the href + extractContent: false, + + // parseOnLoad: Boolean + // Parse content and create the widgets, if any. + parseOnLoad: true, + + // parserScope: String + // Flag passed to parser. Root for attribute names to search for. If scopeName is dojo, + // will search for data-dojo-type (or dojoType). For backwards compatibility + // reasons defaults to dojo._scopeName (which is "dojo" except when + // multi-version support is used, when it will be something like dojo16, dojo20, etc.) + parserScope: dojo._scopeName, + + // preventCache: Boolean + // Prevent caching of data from href's by appending a timestamp to the href. + preventCache: false, + + // preload: Boolean + // Force load of data on initialization even if pane is hidden. + preload: false, + + // refreshOnShow: Boolean + // Refresh (re-download) content when pane goes from hidden to shown + refreshOnShow: false, + + // loadingMessage: String + // Message that shows while downloading + loadingMessage: "${loadingState}", + + // errorMessage: String + // Message that shows if an error occurs + errorMessage: "${errorState}", + + // isLoaded: [readonly] Boolean + // True if the ContentPane has data in it, either specified + // during initialization (via href or inline content), or set + // via set('content', ...) / set('href', ...) + // + // False if it doesn't have any content, or if ContentPane is + // still in the process of downloading href. + isLoaded: false, + + baseClass: "dijitContentPane", + + // ioArgs: Object + // Parameters to pass to xhrGet() request, for example: + // |
+ ioArgs: {}, + + // onLoadDeferred: [readonly] dojo.Deferred + // This is the `dojo.Deferred` returned by set('href', ...) and refresh(). + // Calling onLoadDeferred.addCallback() or addErrback() registers your + // callback to be called only once, when the prior set('href', ...) call or + // the initial href parameter to the constructor finishes loading. + // + // This is different than an onLoad() handler which gets called any time any href + // or content is loaded. + onLoadDeferred: null, + + // Override _Widget's attributeMap because we don't want the title attribute (used to specify + // tab labels) to be copied to ContentPane.domNode... otherwise a tooltip shows up over the + // entire pane. + attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, { + title: [] + }), + + // Flag to parser that I'll parse my contents, so it shouldn't. + stopParser: true, + + // template: [private] Boolean + // Flag from the parser that this ContentPane is inside a template + // so the contents are pre-parsed. + // (TODO: this declaration can be commented out in 2.0) + template: false, + + create: function(params, srcNodeRef){ + // Convert a srcNodeRef argument into a content parameter, so that the original contents are + // processed in the same way as contents set via set("content", ...), calling the parser etc. + // Avoid modifying original params object since that breaks NodeList instantiation, see #11906. + if((!params || !params.template) && srcNodeRef && !("href" in params) && !("content" in params)){ + var df = dojo.doc.createDocumentFragment(); + srcNodeRef = dojo.byId(srcNodeRef) + while(srcNodeRef.firstChild){ + df.appendChild(srcNodeRef.firstChild); + } + params = dojo.delegate(params, {content: df}); + } + this.inherited(arguments, [params, srcNodeRef]); + }, + + postMixInProperties: function(){ + this.inherited(arguments); + var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang); + this.loadingMessage = dojo.string.substitute(this.loadingMessage, messages); + this.errorMessage = dojo.string.substitute(this.errorMessage, messages); + }, + + buildRendering: function(){ + this.inherited(arguments); + + // Since we have no template we need to set this.containerNode ourselves, to make getChildren() work. + // For subclasses of ContentPane that do have a template, does nothing. + if(!this.containerNode){ + this.containerNode = this.domNode; + } + + // remove the title attribute so it doesn't show up when hovering + // over a node (TODO: remove in 2.0, no longer needed after #11490) + this.domNode.title = ""; + + if(!dojo.attr(this.domNode,"role")){ + dijit.setWaiRole(this.domNode, "group"); + } + }, + + _startChildren: function(){ + // summary: + // Call startup() on all children including non _Widget ones like dojo.dnd.Source objects + + // This starts all the widgets + this.inherited(arguments); + + // And this catches stuff like dojo.dnd.Source + if(this._contentSetter){ + dojo.forEach(this._contentSetter.parseResults, function(obj){ + if(!obj._started && !obj._destroyed && dojo.isFunction(obj.startup)){ + obj.startup(); + obj._started = true; + } + }, this); + } + }, + + setHref: function(/*String|Uri*/ href){ + // summary: + // Deprecated. Use set('href', ...) instead. + dojo.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use set('href', ...) instead.", "", "2.0"); + return this.set("href", href); + }, + _setHrefAttr: function(/*String|Uri*/ href){ + // summary: + // Hook so set("href", ...) works. + // description: + // Reset the (external defined) content of this pane and replace with new url + // Note: It delays the download until widget is shown if preload is false. + // href: + // url to the page you want to get, must be within the same domain as your mainpage + + // Cancel any in-flight requests (a set('href', ...) will cancel any in-flight set('href', ...)) + this.cancel(); + + this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel")); + this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad")); + + this._set("href", href); + + // _setHrefAttr() is called during creation and by the user, after creation. + // Assuming preload == false, only in the second case do we actually load the URL; + // otherwise it's done in startup(), and only if this widget is shown. + if(this.preload || (this._created && this._isShown())){ + this._load(); + }else{ + // Set flag to indicate that href needs to be loaded the next time the + // ContentPane is made visible + this._hrefChanged = true; + } + + return this.onLoadDeferred; // dojo.Deferred + }, + + setContent: function(/*String|DomNode|Nodelist*/data){ + // summary: + // Deprecated. Use set('content', ...) instead. + dojo.deprecated("dijit.layout.ContentPane.setContent() is deprecated. Use set('content', ...) instead.", "", "2.0"); + this.set("content", data); + }, + _setContentAttr: function(/*String|DomNode|Nodelist*/data){ + // summary: + // Hook to make set("content", ...) work. + // Replaces old content with data content, include style classes from old content + // data: + // the new Content may be String, DomNode or NodeList + // + // if data is a NodeList (or an array of nodes) nodes are copied + // so you can import nodes from another document implicitly + + // clear href so we can't run refresh and clear content + // refresh should only work if we downloaded the content + this._set("href", ""); + + // Cancel any in-flight requests (a set('content', ...) will cancel any in-flight set('href', ...)) + this.cancel(); + + // Even though user is just setting content directly, still need to define an onLoadDeferred + // because the _onLoadHandler() handler is still getting called from setContent() + this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel")); + if(this._created){ + // For back-compat reasons, call onLoad() for set('content', ...) + // calls but not for content specified in srcNodeRef (ie:
...
) + // or as initialization parameter (ie: new ContentPane({content: ...}) + this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad")); + } + + this._setContent(data || ""); + + this._isDownloaded = false; // mark that content is from a set('content') not a set('href') + + return this.onLoadDeferred; // dojo.Deferred + }, + _getContentAttr: function(){ + // summary: + // Hook to make get("content") work + return this.containerNode.innerHTML; + }, + + cancel: function(){ + // summary: + // Cancels an in-flight download of content + if(this._xhrDfd && (this._xhrDfd.fired == -1)){ + this._xhrDfd.cancel(); + } + delete this._xhrDfd; // garbage collect + + this.onLoadDeferred = null; + }, + + uninitialize: function(){ + if(this._beingDestroyed){ + this.cancel(); + } + this.inherited(arguments); + }, + + destroyRecursive: function(/*Boolean*/ preserveDom){ + // summary: + // Destroy the ContentPane and its contents + + // if we have multiple controllers destroying us, bail after the first + if(this._beingDestroyed){ + return; + } + this.inherited(arguments); + }, + + _onShow: function(){ + // summary: + // Called when the ContentPane is made visible + // description: + // For a plain ContentPane, this is called on initialization, from startup(). + // If the ContentPane is a hidden pane of a TabContainer etc., then it's + // called whenever the pane is made visible. + // + // Does necessary processing, including href download and layout/resize of + // child widget(s) + + this.inherited(arguments); + + if(this.href){ + if(!this._xhrDfd && // if there's an href that isn't already being loaded + (!this.isLoaded || this._hrefChanged || this.refreshOnShow) + ){ + return this.refresh(); // If child has an href, promise that fires when the load is complete + } + } + }, + + refresh: function(){ + // summary: + // [Re]download contents of href and display + // description: + // 1. cancels any currently in-flight requests + // 2. posts "loading..." message + // 3. sends XHR to download new data + + // Cancel possible prior in-flight request + this.cancel(); + + this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel")); + this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad")); + this._load(); + return this.onLoadDeferred; // If child has an href, promise that fires when refresh is complete + }, + + _load: function(){ + // summary: + // Load/reload the href specified in this.href + + // display loading message + this._setContent(this.onDownloadStart(), true); + + var self = this; + var getArgs = { + preventCache: (this.preventCache || this.refreshOnShow), + url: this.href, + handleAs: "text" + }; + if(dojo.isObject(this.ioArgs)){ + dojo.mixin(getArgs, this.ioArgs); + } + + var hand = (this._xhrDfd = (this.ioMethod || dojo.xhrGet)(getArgs)); + + hand.addCallback(function(html){ + try{ + self._isDownloaded = true; + self._setContent(html, false); + self.onDownloadEnd(); + }catch(err){ + self._onError('Content', err); // onContentError + } + delete self._xhrDfd; + return html; + }); + + hand.addErrback(function(err){ + if(!hand.canceled){ + // show error message in the pane + self._onError('Download', err); // onDownloadError + } + delete self._xhrDfd; + return err; + }); + + // Remove flag saying that a load is needed + delete this._hrefChanged; + }, + + _onLoadHandler: function(data){ + // summary: + // This is called whenever new content is being loaded + this._set("isLoaded", true); + try{ + this.onLoadDeferred.callback(data); + }catch(e){ + console.error('Error '+this.widgetId+' running custom onLoad code: ' + e.message); + } + }, + + _onUnloadHandler: function(){ + // summary: + // This is called whenever the content is being unloaded + this._set("isLoaded", false); + try{ + this.onUnload(); + }catch(e){ + console.error('Error '+this.widgetId+' running custom onUnload code: ' + e.message); + } + }, + + destroyDescendants: function(){ + // summary: + // Destroy all the widgets inside the ContentPane and empty containerNode + + // Make sure we call onUnload (but only when the ContentPane has real content) + if(this.isLoaded){ + this._onUnloadHandler(); + } + + // Even if this.isLoaded == false there might still be a "Loading..." message + // to erase, so continue... + + // For historical reasons we need to delete all widgets under this.containerNode, + // even ones that the user has created manually. + var setter = this._contentSetter; + dojo.forEach(this.getChildren(), function(widget){ + if(widget.destroyRecursive){ + widget.destroyRecursive(); + } + }); + if(setter){ + // Most of the widgets in setter.parseResults have already been destroyed, but + // things like Menu that have been moved to haven't yet + dojo.forEach(setter.parseResults, function(widget){ + if(widget.destroyRecursive && widget.domNode && widget.domNode.parentNode == dojo.body()){ + widget.destroyRecursive(); + } + }); + delete setter.parseResults; + } + + // And then clear away all the DOM nodes + dojo.html._emptyNode(this.containerNode); + + // Delete any state information we have about current contents + delete this._singleChild; + }, + + _setContent: function(/*String|DocumentFragment*/ cont, /*Boolean*/ isFakeContent){ + // summary: + // Insert the content into the container node + + // first get rid of child widgets + this.destroyDescendants(); + + // dojo.html.set will take care of the rest of the details + // we provide an override for the error handling to ensure the widget gets the errors + // configure the setter instance with only the relevant widget instance properties + // NOTE: unless we hook into attr, or provide property setters for each property, + // we need to re-configure the ContentSetter with each use + var setter = this._contentSetter; + if(! (setter && setter instanceof dojo.html._ContentSetter)){ + setter = this._contentSetter = new dojo.html._ContentSetter({ + node: this.containerNode, + _onError: dojo.hitch(this, this._onError), + onContentError: dojo.hitch(this, function(e){ + // fires if a domfault occurs when we are appending this.errorMessage + // like for instance if domNode is a UL and we try append a DIV + var errMess = this.onContentError(e); + try{ + this.containerNode.innerHTML = errMess; + }catch(e){ + console.error('Fatal '+this.id+' could not change content due to '+e.message, e); + } + })/*, + _onError */ + }); + }; + + var setterParams = dojo.mixin({ + cleanContent: this.cleanContent, + extractContent: this.extractContent, + parseContent: this.parseOnLoad, + parserScope: this.parserScope, + startup: false, + dir: this.dir, + lang: this.lang + }, this._contentSetterParams || {}); + + setter.set( (dojo.isObject(cont) && cont.domNode) ? cont.domNode : cont, setterParams ); + + // setter params must be pulled afresh from the ContentPane each time + delete this._contentSetterParams; + + if(this.doLayout){ + this._checkIfSingleChild(); + } + + if(!isFakeContent){ + if(this._started){ + // Startup each top level child widget (and they will start their children, recursively) + this._startChildren(); + + // Call resize() on each of my child layout widgets, + // or resize() on my single child layout widget... + // either now (if I'm currently visible) or when I become visible + this._scheduleLayout(); + } + + this._onLoadHandler(cont); + } + }, + + _onError: function(type, err, consoleText){ + this.onLoadDeferred.errback(err); + + // shows user the string that is returned by on[type]Error + // override on[type]Error and return your own string to customize + var errText = this['on' + type + 'Error'].call(this, err); + if(consoleText){ + console.error(consoleText, err); + }else if(errText){// a empty string won't change current content + this._setContent(errText, true); + } + }, + + // EVENT's, should be overide-able + onLoad: function(data){ + // summary: + // Event hook, is called after everything is loaded and widgetified + // tags: + // callback + }, + + onUnload: function(){ + // summary: + // Event hook, is called before old content is cleared + // tags: + // callback + }, + + onDownloadStart: function(){ + // summary: + // Called before download starts. + // description: + // The string returned by this function will be the html + // that tells the user we are loading something. + // Override with your own function if you want to change text. + // tags: + // extension + return this.loadingMessage; + }, + + onContentError: function(/*Error*/ error){ + // summary: + // Called on DOM faults, require faults etc. in content. + // + // In order to display an error message in the pane, return + // the error message from this method, as an HTML string. + // + // By default (if this method is not overriden), it returns + // nothing, so the error message is just printed to the console. + // tags: + // extension + }, + + onDownloadError: function(/*Error*/ error){ + // summary: + // Called when download error occurs. + // + // In order to display an error message in the pane, return + // the error message from this method, as an HTML string. + // + // Default behavior (if this method is not overriden) is to display + // the error message inside the pane. + // tags: + // extension + return this.errorMessage; + }, + + onDownloadEnd: function(){ + // summary: + // Called when download is finished. + // tags: + // callback + } }); -} -delete this._needLayout; -},onLoad:function(_24){ -},onUnload:function(){ -},onDownloadStart:function(){ -return this.loadingMessage; -},onContentError:function(_25){ -},onDownloadError:function(_26){ -return this.errorMessage; -},onDownloadEnd:function(){ -}}); + } -- cgit v1.2.3