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/StackContainer.js | 460 ++++++++++++++++++++++++++----------- 1 file changed, 324 insertions(+), 136 deletions(-) (limited to 'lib/dijit/layout/StackContainer.js') diff --git a/lib/dijit/layout/StackContainer.js b/lib/dijit/layout/StackContainer.js index 78a49021d..98af4c942 100644 --- a/lib/dijit/layout/StackContainer.js +++ b/lib/dijit/layout/StackContainer.js @@ -1,148 +1,336 @@ /* - 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.StackContainer"]){ -dojo._hasResource["dijit.layout.StackContainer"]=true; +if(!dojo._hasResource["dijit.layout.StackContainer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.layout.StackContainer"] = true; dojo.provide("dijit.layout.StackContainer"); dojo.require("dijit._Templated"); dojo.require("dijit.layout._LayoutWidget"); -dojo.requireLocalization("dijit","common",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.requireLocalization("dijit", "common", 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.require("dojo.cookie"); -dojo.declare("dijit.layout.StackContainer",dijit.layout._LayoutWidget,{doLayout:true,persist:false,baseClass:"dijitStackContainer",postCreate:function(){ -this.inherited(arguments); -dojo.addClass(this.domNode,"dijitLayoutContainer"); -dijit.setWaiRole(this.containerNode,"tabpanel"); -this.connect(this.domNode,"onkeypress",this._onKeyPress); -},startup:function(){ -if(this._started){ -return; -} -var _1=this.getChildren(); -dojo.forEach(_1,this._setupChild,this); -if(this.persist){ -this.selectedChildWidget=dijit.byId(dojo.cookie(this.id+"_selectedChild")); -}else{ -dojo.some(_1,function(_2){ -if(_2.selected){ -this.selectedChildWidget=_2; -} -return _2.selected; -},this); -} -var _3=this.selectedChildWidget; -if(!_3&&_1[0]){ -_3=this.selectedChildWidget=_1[0]; -_3.selected=true; -} -dojo.publish(this.id+"-startup",[{children:_1,selected:_3}]); -this.inherited(arguments); -},resize:function(){ -var _4=this.selectedChildWidget; -if(_4&&!this._hasBeenShown){ -this._hasBeenShown=true; -this._showChild(_4); -} -this.inherited(arguments); -},_setupChild:function(_5){ -this.inherited(arguments); -dojo.removeClass(_5.domNode,"dijitVisible"); -dojo.addClass(_5.domNode,"dijitHidden"); -_5.domNode.title=""; -},addChild:function(_6,_7){ -this.inherited(arguments); -if(this._started){ -dojo.publish(this.id+"-addChild",[_6,_7]); -this.layout(); -if(!this.selectedChildWidget){ -this.selectChild(_6); -} -} -},removeChild:function(_8){ -this.inherited(arguments); -if(this._started){ -dojo.publish(this.id+"-removeChild",[_8]); -} -if(this._beingDestroyed){ -return; -} -if(this.selectedChildWidget===_8){ -this.selectedChildWidget=undefined; -if(this._started){ -var _9=this.getChildren(); -if(_9.length){ -this.selectChild(_9[0]); -} -} -} -if(this._started){ -this.layout(); -} -},selectChild:function(_a,_b){ -_a=dijit.byId(_a); -if(this.selectedChildWidget!=_a){ -this._transition(_a,this.selectedChildWidget,_b); -this.selectedChildWidget=_a; -dojo.publish(this.id+"-selectChild",[_a]); -if(this.persist){ -dojo.cookie(this.id+"_selectedChild",this.selectedChildWidget.id); -} -} -},_transition:function(_c,_d){ -if(_d){ -this._hideChild(_d); -} -this._showChild(_c); -if(_c.resize){ -if(this.doLayout){ -_c.resize(this._containerContentBox||this._contentBox); -}else{ -_c.resize(); -} -} -},_adjacent:function(_e){ -var _f=this.getChildren(); -var _10=dojo.indexOf(_f,this.selectedChildWidget); -_10+=_e?1:_f.length-1; -return _f[_10%_f.length]; -},forward:function(){ -this.selectChild(this._adjacent(true),true); -},back:function(){ -this.selectChild(this._adjacent(false),true); -},_onKeyPress:function(e){ -dojo.publish(this.id+"-containerKeyPress",[{e:e,page:this}]); -},layout:function(){ -if(this.doLayout&&this.selectedChildWidget&&this.selectedChildWidget.resize){ -this.selectedChildWidget.resize(this._containerContentBox||this._contentBox); -} -},_showChild:function(_11){ -var _12=this.getChildren(); -_11.isFirstChild=(_11==_12[0]); -_11.isLastChild=(_11==_12[_12.length-1]); -_11.selected=true; -dojo.removeClass(_11.domNode,"dijitHidden"); -dojo.addClass(_11.domNode,"dijitVisible"); -_11._onShow(); -},_hideChild:function(_13){ -_13.selected=false; -dojo.removeClass(_13.domNode,"dijitVisible"); -dojo.addClass(_13.domNode,"dijitHidden"); -_13.onHide(); -},closeChild:function(_14){ -var _15=_14.onClose(this,_14); -if(_15){ -this.removeChild(_14); -_14.destroyRecursive(); -} -},destroyDescendants:function(_16){ -dojo.forEach(this.getChildren(),function(_17){ -this.removeChild(_17); -_17.destroyRecursive(_16); -},this); -}}); dojo.require("dijit.layout.StackController"); -dojo.extend(dijit._Widget,{selected:false,closable:false,iconClass:"",showTitle:true}); + + +dojo.declare( + "dijit.layout.StackContainer", + dijit.layout._LayoutWidget, + { + // summary: + // A container that has multiple children, but shows only + // one child at a time + // + // description: + // A container for widgets (ContentPanes, for example) That displays + // only one Widget at a time. + // + // Publishes topics [widgetId]-addChild, [widgetId]-removeChild, and [widgetId]-selectChild + // + // Can be base class for container, Wizard, Show, etc. + + // doLayout: Boolean + // If true, change the size of my currently displayed child to match my size + doLayout: true, + + // persist: Boolean + // Remembers the selected child across sessions + persist: false, + + baseClass: "dijitStackContainer", + +/*===== + // selectedChildWidget: [readonly] dijit._Widget + // References the currently selected child widget, if any. + // Adjust selected child with selectChild() method. + selectedChildWidget: null, +=====*/ + + buildRendering: function(){ + this.inherited(arguments); + dojo.addClass(this.domNode, "dijitLayoutContainer"); + dijit.setWaiRole(this.containerNode, "tabpanel"); + }, + + postCreate: function(){ + this.inherited(arguments); + this.connect(this.domNode, "onkeypress", this._onKeyPress); + }, + + startup: function(){ + if(this._started){ return; } + + var children = this.getChildren(); + + // Setup each page panel to be initially hidden + dojo.forEach(children, this._setupChild, this); + + // Figure out which child to initially display, defaulting to first one + if(this.persist){ + this.selectedChildWidget = dijit.byId(dojo.cookie(this.id + "_selectedChild")); + }else{ + dojo.some(children, function(child){ + if(child.selected){ + this.selectedChildWidget = child; + } + return child.selected; + }, this); + } + var selected = this.selectedChildWidget; + if(!selected && children[0]){ + selected = this.selectedChildWidget = children[0]; + selected.selected = true; + } + + // Publish information about myself so any StackControllers can initialize. + // This needs to happen before this.inherited(arguments) so that for + // TabContainer, this._contentBox doesn't include the space for the tab labels. + dojo.publish(this.id+"-startup", [{children: children, selected: selected}]); + + // Startup each child widget, and do initial layout like setting this._contentBox, + // then calls this.resize() which does the initial sizing on the selected child. + this.inherited(arguments); + }, + + resize: function(){ + // Resize is called when we are first made visible (it's called from startup() + // if we are initially visible). If this is the first time we've been made + // visible then show our first child. + var selected = this.selectedChildWidget; + if(selected && !this._hasBeenShown){ + this._hasBeenShown = true; + this._showChild(selected); + } + this.inherited(arguments); + }, + + _setupChild: function(/*dijit._Widget*/ child){ + // Overrides _LayoutWidget._setupChild() + + this.inherited(arguments); + + dojo.replaceClass(child.domNode, "dijitHidden", "dijitVisible"); + + // remove the title attribute so it doesn't show up when i hover + // over a node + child.domNode.title = ""; + }, + + addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){ + // Overrides _Container.addChild() to do layout and publish events + + this.inherited(arguments); + + if(this._started){ + dojo.publish(this.id+"-addChild", [child, insertIndex]); + + // in case the tab titles have overflowed from one line to two lines + // (or, if this if first child, from zero lines to one line) + // TODO: w/ScrollingTabController this is no longer necessary, although + // ScrollTabController.resize() does need to get called to show/hide + // the navigation buttons as appropriate, but that's handled in ScrollingTabController.onAddChild() + this.layout(); + + // if this is the first child, then select it + if(!this.selectedChildWidget){ + this.selectChild(child); + } + } + }, + + removeChild: function(/*dijit._Widget*/ page){ + // Overrides _Container.removeChild() to do layout and publish events + + this.inherited(arguments); + + if(this._started){ + // this will notify any tablists to remove a button; do this first because it may affect sizing + dojo.publish(this.id + "-removeChild", [page]); + } + + // If we are being destroyed than don't run the code below (to select another page), because we are deleting + // every page one by one + if(this._beingDestroyed){ return; } + + // Select new page to display, also updating TabController to show the respective tab. + // Do this before layout call because it can affect the height of the TabController. + if(this.selectedChildWidget === page){ + this.selectedChildWidget = undefined; + if(this._started){ + var children = this.getChildren(); + if(children.length){ + this.selectChild(children[0]); + } + } + } + + if(this._started){ + // In case the tab titles now take up one line instead of two lines + // (note though that ScrollingTabController never overflows to multiple lines), + // or the height has changed slightly because of addition/removal of tab which close icon + this.layout(); + } + }, + + selectChild: function(/*dijit._Widget|String*/ page, /*Boolean*/ animate){ + // summary: + // Show the given widget (which must be one of my children) + // page: + // Reference to child widget or id of child widget + + page = dijit.byId(page); + + if(this.selectedChildWidget != page){ + // Deselect old page and select new one + var d = this._transition(page, this.selectedChildWidget, animate); + this._set("selectedChildWidget", page); + dojo.publish(this.id+"-selectChild", [page]); + + if(this.persist){ + dojo.cookie(this.id + "_selectedChild", this.selectedChildWidget.id); + } + } + + return d; // If child has an href, promise that fires when the child's href finishes loading + }, + + _transition: function(/*dijit._Widget*/ newWidget, /*dijit._Widget*/ oldWidget, /*Boolean*/ animate){ + // summary: + // Hide the old widget and display the new widget. + // Subclasses should override this. + // tags: + // protected extension + if(oldWidget){ + this._hideChild(oldWidget); + } + var d = this._showChild(newWidget); + + // Size the new widget, in case this is the first time it's being shown, + // or I have been resized since the last time it was shown. + // Note that page must be visible for resizing to work. + if(newWidget.resize){ + if(this.doLayout){ + newWidget.resize(this._containerContentBox || this._contentBox); + }else{ + // the child should pick it's own size but we still need to call resize() + // (with no arguments) to let the widget lay itself out + newWidget.resize(); + } + } + + return d; // If child has an href, promise that fires when the child's href finishes loading + }, + + _adjacent: function(/*Boolean*/ forward){ + // summary: + // Gets the next/previous child widget in this container from the current selection. + var children = this.getChildren(); + var index = dojo.indexOf(children, this.selectedChildWidget); + index += forward ? 1 : children.length - 1; + return children[ index % children.length ]; // dijit._Widget + }, + + forward: function(){ + // summary: + // Advance to next page. + return this.selectChild(this._adjacent(true), true); + }, + + back: function(){ + // summary: + // Go back to previous page. + return this.selectChild(this._adjacent(false), true); + }, + + _onKeyPress: function(e){ + dojo.publish(this.id+"-containerKeyPress", [{ e: e, page: this}]); + }, + + layout: function(){ + // Implement _LayoutWidget.layout() virtual method. + if(this.doLayout && this.selectedChildWidget && this.selectedChildWidget.resize){ + this.selectedChildWidget.resize(this._containerContentBox || this._contentBox); + } + }, + + _showChild: function(/*dijit._Widget*/ page){ + // summary: + // Show the specified child by changing it's CSS, and call _onShow()/onShow() so + // it can do any updates it needs regarding loading href's etc. + // returns: + // Promise that fires when page has finished showing, or true if there's no href + var children = this.getChildren(); + page.isFirstChild = (page == children[0]); + page.isLastChild = (page == children[children.length-1]); + page._set("selected", true); + + dojo.replaceClass(page.domNode, "dijitVisible", "dijitHidden"); + + return page._onShow() || true; + }, + + _hideChild: function(/*dijit._Widget*/ page){ + // summary: + // Hide the specified child by changing it's CSS, and call _onHide() so + // it's notified. + page._set("selected", false); + dojo.replaceClass(page.domNode, "dijitHidden", "dijitVisible"); + + page.onHide(); + }, + + closeChild: function(/*dijit._Widget*/ page){ + // summary: + // Callback when user clicks the [X] to remove a page. + // If onClose() returns true then remove and destroy the child. + // tags: + // private + var remove = page.onClose(this, page); + if(remove){ + this.removeChild(page); + // makes sure we can clean up executeScripts in ContentPane onUnLoad + page.destroyRecursive(); + } + }, + + destroyDescendants: function(/*Boolean*/ preserveDom){ + dojo.forEach(this.getChildren(), function(child){ + this.removeChild(child); + child.destroyRecursive(preserveDom); + }, this); + } +}); + +// For back-compat, remove for 2.0 + + +// These arguments can be specified for the children of a StackContainer. +// Since any widget can be specified as a StackContainer child, mix them +// into the base widget class. (This is a hack, but it's effective.) +dojo.extend(dijit._Widget, { + // selected: Boolean + // Parameter for children of `dijit.layout.StackContainer` or subclasses. + // Specifies that this widget should be the initially displayed pane. + // Note: to change the selected child use `dijit.layout.StackContainer.selectChild` + selected: false, + + // closable: Boolean + // Parameter for children of `dijit.layout.StackContainer` or subclasses. + // True if user can close (destroy) this child, such as (for example) clicking the X on the tab. + closable: false, + + // iconClass: String + // Parameter for children of `dijit.layout.StackContainer` or subclasses. + // CSS Class specifying icon to use in label associated with this pane. + iconClass: "", + + // showTitle: Boolean + // Parameter for children of `dijit.layout.StackContainer` or subclasses. + // When true, display title of this widget as tab label etc., rather than just using + // icon specified in iconClass + showTitle: true +}); + } -- cgit v1.2.3