Blame | Last modification | View Log | RSS feed
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.layout._LayoutWidget");dojo.require("dojo.parser");dojo.require("dojo.string");dojo.requireLocalization("dijit", "loading", null, "ko,zh,ja,zh-tw,ru,it,ROOT,hu,fr,pt,pl,es,de,cs");dojo.declare("dijit.layout.ContentPane",dijit._Widget,{// summary:// A widget that acts as a Container for other widgets, and includes a ajax interface// description:// A widget that can be used as a standalone widget// or as a baseclass for other widgets// Handles replacement of document fragment using either external uri or javascript// generated markup or DOM content, instantiating widgets within that content.// Don't confuse it with an iframe, it only needs/wants document fragments.// It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.// But note that those classes can contain any widget as a child.// example:// Some quick samples:// To change the innerHTML use .setContent('<b>new content</b>')//// Or you can send it a NodeList, .setContent(dojo.query('div [class=selected]', userSelection))// please note that the nodes in NodeList will copied, not moved//// To do a ajax update use .setHref('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; see setHref();href: "",// extractContent: Boolean// Extract visible content from inside of <body> .... </body>extractContent: false,// parseOnLoad: Boolean// parse content and create the widgets, if anyparseOnLoad: true,// preventCache: Boolean// Cache content retreived externallypreventCache: false,// preload: Boolean// Force load of data even if pane is hidden.preload: false,// refreshOnShow: Boolean// Refresh (re-download) content when pane goes from hidden to shownrefreshOnShow: false,// loadingMessage: String// Message that shows while downloadingloadingMessage: "<span class='dijitContentPaneLoading'>${loadingState}</span>",// errorMessage: String// Message that shows if an error occurserrorMessage: "<span class='dijitContentPaneError'>${errorState}</span>",// isLoaded: Boolean// Tells loading status see onLoad|onUnload for event hooksisLoaded: false,// class: String// Class name to apply to ContentPane dom nodes"class": "dijitContentPane",postCreate: function(){// remove the title attribute so it doesn't show up when i hover// over a nodethis.domNode.title = "";if(this.preload){this._loadCheck();}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);// for programatically created ContentPane (with <span> tag), need to muck w/CSS// or it's as though overflow:visible is setdojo.addClass(this.domNode, this["class"]);},startup: function(){if(this._started){ return; }this._checkIfSingleChild();if(this._singleChild){this._singleChild.startup();}this._loadCheck();this._started = true;},_checkIfSingleChild: function(){// summary:// Test if we have exactly one widget as a child, and if so assume that we are a container for that widget,// and should propogate startup() and resize() calls to it.var childNodes = dojo.query(">", this.containerNode || this.domNode),childWidgets = childNodes.filter("[widgetId]");if(childNodes.length == 1 && childWidgets.length == 1){this.isContainer = true;this._singleChild = dijit.byNode(childWidgets[0]);}else{delete this.isContainer;delete this._singleChild;}},refresh: function(){// summary:// Force a refresh (re-download) of content, be sure to turn off cache// we return result of _prepareLoad here to avoid code dup. in dojox.layout.ContentPanereturn this._prepareLoad(true);},setHref: function(/*String|Uri*/ href){// summary:// 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 mainpagethis.href = href;// we return result of _prepareLoad here to avoid code dup. in dojox.layout.ContentPanereturn this._prepareLoad();},setContent: function(/*String|DomNode|Nodelist*/data){// summary:// 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 cant run refresh and clear content// refresh should only work if we downloaded the contentif(!this._isDownloaded){this.href = "";this._onUnloadHandler();}this._setContent(data || "");this._isDownloaded = false; // must be set after _setContent(..), pathadjust in dojox.layout.ContentPaneif(this.parseOnLoad){this._createSubWidgets();}this._checkIfSingleChild();if(this._singleChild && this._singleChild.resize){this._singleChild.resize(this._contentBox);}this._onLoadHandler();},cancel: function(){// summary:// Cancels a inflight download of contentif(this._xhrDfd && (this._xhrDfd.fired == -1)){this._xhrDfd.cancel();}delete this._xhrDfd; // garbage collect},destroy: function(){// if we have multiple controllers destroying us, bail after the firstif(this._beingDestroyed){return;}// make sure we call onUnloadthis._onUnloadHandler();this._beingDestroyed = true;this.inherited("destroy",arguments);},resize: function(size){dojo.marginBox(this.domNode, size);// Compute content box size in case we [later] need to size child// If either height or width wasn't specified by the user, then query node for it.// But note that setting the margin box and then immediately querying dimensions may return// inaccurate results, so try not to depend on it.var node = this.containerNode || this.domNode,mb = dojo.mixin(dojo.marginBox(node), size||{});this._contentBox = dijit.layout.marginBox2contentBox(node, mb);// If we have a single widget child then size it to fit snugly within my bordersif(this._singleChild && this._singleChild.resize){this._singleChild.resize(this._contentBox);}},_prepareLoad: function(forceLoad){// sets up for a xhrLoad, load is deferred until widget onShow// cancels a inflight downloadthis.cancel();this.isLoaded = false;this._loadCheck(forceLoad);},_loadCheck: function(forceLoad){// call this when you change onShow (onSelected) status when selected in parent container// it's used as a trigger for href download when this.domNode.display != 'none'// sequence:// if no href -> bail// forceLoad -> always load// this.preload -> load when download not in progress, domNode display doesn't matter// this.refreshOnShow -> load when download in progress bails, domNode display !='none' AND// this.open !== false (undefined is ok), isLoaded doesn't matter// else -> load when download not in progress, if this.open !== false (undefined is ok) AND// domNode display != 'none', isLoaded must be falsevar displayState = ((this.open !== false) && (this.domNode.style.display != 'none'));if(this.href &&(forceLoad ||(this.preload && !this._xhrDfd) ||(this.refreshOnShow && displayState && !this._xhrDfd) ||(!this.isLoaded && displayState && !this._xhrDfd))){this._downloadExternalContent();}},_downloadExternalContent: function(){this._onUnloadHandler();// display loading messagethis._setContent(this.onDownloadStart.call(this));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.onDownloadEnd.call(self);self._isDownloaded = true;self.setContent.call(self, html); // onload event is called from here}catch(err){self._onError.call(self, 'Content', err); // onContentError}delete self._xhrDfd;return html;});hand.addErrback(function(err){if(!hand.cancelled){// show error message in the paneself._onError.call(self, 'Download', err); // onDownloadError}delete self._xhrDfd;return err;});},_onLoadHandler: function(){this.isLoaded = true;try{this.onLoad.call(this);}catch(e){console.error('Error '+this.widgetId+' running custom onLoad code');}},_onUnloadHandler: function(){this.isLoaded = false;this.cancel();try{this.onUnload.call(this);}catch(e){console.error('Error '+this.widgetId+' running custom onUnload code');}},_setContent: function(cont){this.destroyDescendants();try{var node = this.containerNode || this.domNode;while(node.firstChild){dojo._destroyElement(node.firstChild);}if(typeof cont == "string"){// dijit.ContentPane does only minimal fixes,// No pathAdjustments, script retrieval, style clean etc// some of these should be available in the dojox.layout.ContentPaneif(this.extractContent){match = cont.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(match){ cont = match[1]; }}node.innerHTML = cont;}else{// domNode or NodeListif(cont.nodeType){ // domNode (htmlNode 1 or textNode 3)node.appendChild(cont);}else{// nodelist or array such as dojo.Nodelistdojo.forEach(cont, function(n){node.appendChild(n.cloneNode(true));});}}}catch(e){// check if a domfault occurs when we are appending this.errorMessage// like for instance if domNode is a UL and we try append a DIVvar errMess = this.onContentError(e);try{node.innerHTML = errMess;}catch(e){console.error('Fatal '+this.id+' could not change content due to '+e.message, e);}}},_onError: function(type, err, consoleText){// shows user the string that is returned by on[type]Error// overide on[type]Error and return your own string to customizevar errText = this['on' + type + 'Error'].call(this, err);if(consoleText){console.error(consoleText, err);}else if(errText){// a empty string won't change current contentthis._setContent.call(this, errText);}},_createSubWidgets: function(){// summary: scan my contents and create subwidgetsvar rootNode = this.containerNode || this.domNode;try{dojo.parser.parse(rootNode, true);}catch(e){this._onError('Content', e, "Couldn't create widgets in "+this.id+(this.href ? " from "+this.href : ""));}},// EVENT's, should be overide-ableonLoad: function(e){// summary:// Event hook, is called after everything is loaded and widgetified},onUnload: function(e){// summary:// Event hook, is called before old content is cleared},onDownloadStart: function(){// summary:// called before download starts// 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 textreturn this.loadingMessage;},onContentError: function(/*Error*/ error){// summary:// called on DOM faults, require fault etc in content// default is to display errormessage inside pane},onDownloadError: function(/*Error*/ error){// summary:// Called when download error occurs, default is to display// errormessage inside pane. Overide function to change that.// The string returned by this function will be the html// that tells the user a error happendreturn this.errorMessage;},onDownloadEnd: function(){// summary:// called when download is finished}});}