Modified: 
struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js?view=diff&rev=535556&r1=535555&r2=535556
==============================================================================
--- 
struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js
 (original)
+++ 
struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts_dojo.js.uncompressed.js
 Sat May  5 11:45:02 2007
@@ -22263,7 +22263,7 @@
     if(this.notifyTopicsArray) {
       dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
         try {
-          dojo.event.topic.publish(topic, data, type, e);
+          dojo.event.topic.publish(topic, data, type, e, self);
         } catch(ex){
                  self.log(ex);
         }
@@ -22274,25 +22274,27 @@
     var topicsArray = null;
     switch(type) {
       case "before":
-        topicsArray = this.beforeNotifyTopicsArray;
+        this.notifyTo(this.beforeNotifyTopicsArray, null, e);
         break;
       case "load":
-        topicsArray = this.afterNotifyTopicsArray;
+        this.notifyTo(this.afterNotifyTopicsArray, data, e);
         break;
       case "error":
-        topicsArray = this.errorNotifyTopicsArray;
+        this.notifyTo(this.errorNotifyTopicsArray, data, e);
         break;
     }
-    
-    this.notifyTo(topicsArray, data, type, e);
   },
   
-  notifyTo : function(topicsArray, data, type, e) {
+  notifyTo : function(topicsArray, data, e) {
     var self = this;
     if(topicsArray) {
       dojo.lang.forEach(topicsArray, function(topic) {
       try {
-        dojo.event.topic.publish(topic, data, type, e);
+        if(data) {
+          dojo.event.topic.publish(topic, data, e, self);
+        } else {
+          dojo.event.topic.publish(topic, e, self);
+        }
       } catch(ex){
         self.log(ex);
       }
@@ -22537,6 +22539,9 @@
     highlightColor : "",
     highlightDuration : 2000,
     
+    //only used when inside a tabbedpanel
+    disabled : false,
+    
     onDownloadStart : function(event) {
       if(!this.showLoading) {
         event.returnValue = false;
@@ -22581,7 +22586,7 @@
         var self = this;
         dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
           try {
-            dojo.event.topic.publish(topic, data, type, e);
+            dojo.event.topic.publish(topic, data, type, e, self);
           } catch(ex) {
             self.log(ex);
           }
@@ -22592,28 +22597,30 @@
       var topicsArray = null;
       switch(type) {
         case "before":
-          topicsArray = this.beforeNotifyTopicsArray;
+          this.notifyTo(this.beforeNotifyTopicsArray, null, e);
           break;
         case "load":
-          topicsArray = this.afterNotifyTopicsArray;
+          this.notifyTo(this.afterNotifyTopicsArray, data, e);
           break;
         case "error":
-          topicsArray = this.errorNotifyTopicsArray;
+          this.notifyTo(this.errorNotifyTopicsArray, data, e);
           break;
       }
-    
-      this.notifyTo(topicsArray, data, type, e);
     },
     
-    notifyTo : function(topicsArray, data, type, e) {
+    notifyTo : function(topicsArray, data, e) {
       var self = this;
       if(topicsArray) {
         dojo.lang.forEach(topicsArray, function(topic) {
-          try {
-            dojo.event.topic.publish(topic, data, type, e);
-          } catch(ex){
-            self.log(ex);
+        try {
+          if(data) {
+            dojo.event.topic.publish(topic, data, e, self);
+          } else {
+            dojo.event.topic.publish(topic, e, self);
           }
+        } catch(ex){
+          self.log(ex);
+        }
         });
       }
     },
@@ -28107,6 +28114,723 @@
   
 });
 
+dojo.provide("dojo.widget.PageContainer");
+
+
+
+
+
+
+dojo.widget.defineWidget("dojo.widget.PageContainer", dojo.widget.HtmlWidget, {
+       // summary
+       //      A container that has multiple children, but shows only
+       //      one child at a time (like looking at the pages in a book one by 
one).
+       //
+       //      Publishes topics <widgetId>-addChild, <widgetId>-removeChild, 
and <widgetId>-selectChild
+       //
+       //      Can be base class for container, Wizard, Show, etc.
+
+       isContainer: true,
+
+       // doLayout: Boolean
+       //  if true, change the size of my currently displayed child to match 
my size
+       doLayout: true,
+
+       templateString: "<div dojoAttachPoint='containerNode'></div>",
+
+       // selectedChild: String
+       //   id of the currently shown page
+       selectedChild: "",
+
+       fillInTemplate: function(args, frag) {
+               // Copy style info from input node to output node
+               var source = this.getFragNodeRef(frag);
+               dojo.html.copyStyle(this.domNode, source);
+               dojo.widget.PageContainer.superclass.fillInTemplate.apply(this, 
arguments);
+       },
+
+       postCreate: function(args, frag) {
+               if(this.children.length){
+                       // Setup each page panel
+                       dojo.lang.forEach(this.children, this._setupChild, 
this);
+
+                       // Figure out which child to initially display
+                       var initialChild;
+                       if(this.selectedChild){
+                               this.selectChild(this.selectedChild);
+                       }else{
+                               for(var i=0; i<this.children.length; i++){
+                                       if(this.children[i].selected){
+                                               
this.selectChild(this.children[i]);
+                                               break;
+                                       }
+                               }
+                               if(!this.selectedChildWidget){
+                                       this.selectChild(this.children[0]);
+                               }
+                       }
+               }
+       },
+
+       addChild: function(child){
+               dojo.widget.PageContainer.superclass.addChild.apply(this, 
arguments);
+               this._setupChild(child);
+
+               // in case the tab labels have overflowed from one line to two 
lines
+               this.onResized();
+
+               // if this is the first child, then select it
+               if(!this.selectedChildWidget){
+                       this.selectChild(child);
+               }
+       },
+
+       _setupChild: function(/*Widget*/ page){
+               // Summary: Add the given child to this page container
+
+               page.hide();
+               
+               // since we are setting the width/height of the child elements, 
they need
+               // to be position:relative, or IE has problems (See bug #2033)
+               page.domNode.style.position="relative";
+
+               // publish the addChild event for panes added via addChild(), 
and the original panes too
+               dojo.event.topic.publish(this.widgetId+"-addChild", page);
+       },
+
+       removeChild: function(/*Widget*/ page){
+               dojo.widget.PageContainer.superclass.removeChild.apply(this, 
arguments);
+
+               // 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; }
+
+               // this will notify any tablists to remove a button; do this 
first because it may affect sizing
+               dojo.event.topic.publish(this.widgetId+"-removeChild", page);
+
+               // in case the tab labels now take up one line instead of two 
lines
+               this.onResized();
+
+               if (this.selectedChildWidget === page) {
+                       this.selectedChildWidget = undefined;
+                       if (this.children.length > 0) {
+                               this.selectChild(this.children[0], true);
+                       }
+               }
+       },
+
+       selectChild: function(/*Widget*/ page, /*Widget*/ callingWidget){
+               // summary
+               //      Show the given widget (which must be one of my children)
+               page = dojo.widget.byId(page);
+               this.correspondingPageButton = callingWidget;
+
+               // Deselect old page and select new one
+               if(this.selectedChildWidget){
+                       this._hideChild(this.selectedChildWidget);
+               }
+               this.selectedChildWidget = page;
+               this.selectedChild = page.widgetId;
+               this._showChild(page);
+               page.isFirstChild = (page == this.children[0]);
+               page.isLastChild = (page == 
this.children[this.children.length-1]);
+               dojo.event.topic.publish(this.widgetId+"-selectChild", page);
+       },
+
+       forward: function(){
+               // Summary: advance to next page
+               var index = dojo.lang.find(this.children, 
this.selectedChildWidget);
+               this.selectChild(this.children[index+1]);
+       },
+
+       back: function(){
+               // Summary: go back to previous page
+               var index = dojo.lang.find(this.children, 
this.selectedChildWidget);
+               this.selectChild(this.children[index-1]);
+       },
+
+       onResized: function(){
+               // Summary: called when any page is shown, to make it fit the 
container correctly
+               if(this.doLayout && this.selectedChildWidget){
+                       with(this.selectedChildWidget.domNode.style){
+                               top = 
dojo.html.getPixelValue(this.containerNode, "padding-top", true);
+                               left = 
dojo.html.getPixelValue(this.containerNode, "padding-left", true);
+                       }
+                       var content = 
dojo.html.getContentBox(this.containerNode);
+                       this.selectedChildWidget.resizeTo(content.width, 
content.height);
+               }
+       },
+
+       _showChild: function(/*Widget*/ page) {
+               // size the current page (in case this is the first time it's 
being shown, or I have been resized)
+               if(this.doLayout){
+                       var content = 
dojo.html.getContentBox(this.containerNode);
+                       page.resizeTo(content.width, content.height);
+               }
+
+               page.selected=true;
+               page.show();
+       },
+
+       _hideChild: function(/*Widget*/ page) {
+               page.selected=false;
+               page.hide();
+       },
+
+       closeChild: function(/*Widget*/ page) {
+               // summary
+               //      callback when user clicks the [X] to remove a page
+               //      if onClose() returns true then remove and destroy the 
childd
+               var remove = page.onClose(this, page);
+               if(remove) {
+                       this.removeChild(page);
+                       // makes sure we can clean up executeScripts in 
ContentPane onUnLoad
+                       page.destroy();
+               }
+       },
+
+       destroy: function(){
+               this._beingDestroyed = true;
+               dojo.event.topic.destroy(this.widgetId+"-addChild");
+               dojo.event.topic.destroy(this.widgetId+"-removeChild");
+               dojo.event.topic.destroy(this.widgetId+"-selectChild");
+               dojo.widget.PageContainer.superclass.destroy.apply(this, 
arguments);
+       }
+});
+
+
+dojo.widget.defineWidget(
+    "dojo.widget.PageController",
+    dojo.widget.HtmlWidget,
+       {
+               // summary
+               //      Set of buttons to select a page in a page list.
+               //      Monitors the specified PageContaine, and whenever a 
page is
+               //      added, deleted, or selected, updates itself accordingly.
+
+               templateString: "<span wairole='tablist' 
dojoAttachEvent='onKey'></span>",
+               isContainer: true,
+
+               // containerId: String
+               //      the id of the page container that I point to
+               containerId: "",
+
+               // buttonWidget: String
+               //      the name of the button widget to create to correspond 
to each page
+               buttonWidget: "PageButton",
+
+               // class: String
+               //      Class name to apply to the top dom node
+               "class": "dojoPageController",
+
+               fillInTemplate: function() {
+                       dojo.html.addClass(this.domNode, this["class"]);  // 
"class" is a reserved word in JS
+                       dojo.widget.wai.setAttr(this.domNode, "waiRole", 
"role", "tablist");
+               },
+
+               postCreate: function(){
+                       this.pane2button = {};          // mapping from panes 
to buttons
+
+                       // If children have already been added to the page 
container then create buttons for them
+                       var container = dojo.widget.byId(this.containerId);
+                       if(container){
+                               dojo.lang.forEach(container.children, 
this.onAddChild, this);
+                       }
+
+                       
dojo.event.topic.subscribe(this.containerId+"-addChild", this, "onAddChild");
+                       
dojo.event.topic.subscribe(this.containerId+"-removeChild", this, 
"onRemoveChild");
+                       
dojo.event.topic.subscribe(this.containerId+"-selectChild", this, 
"onSelectChild");
+               },
+
+               destroy: function(){
+                       
dojo.event.topic.unsubscribe(this.containerId+"-addChild", this, "onAddChild");
+                       
dojo.event.topic.unsubscribe(this.containerId+"-removeChild", this, 
"onRemoveChild");
+                       
dojo.event.topic.unsubscribe(this.containerId+"-selectChild", this, 
"onSelectChild");
+                       
dojo.widget.PageController.superclass.destroy.apply(this, arguments);
+               },
+
+               onAddChild: function(/*Widget*/ page){
+                       // summary
+                       //   Called whenever a page is added to the container.
+                       //   Create button corresponding to the page.
+                       var button = dojo.widget.createWidget(this.buttonWidget,
+                               {
+                                       label: page.label,
+                                       closeButton: page.closable
+                               });
+                       this.addChild(button);
+                       this.domNode.appendChild(button.domNode);
+                       this.pane2button[page]=button;
+                       page.controlButton = button;    // this value might be 
overwritten if two tabs point to same container
+
+                       var _this = this;
+                       dojo.event.connect(button, "onClick", function(){ 
_this.onButtonClick(page); });
+                       dojo.event.connect(button, "onCloseButtonClick", 
function(){ _this.onCloseButtonClick(page); });
+               },
+
+               onRemoveChild: function(/*Widget*/ page){
+                       // summary
+                       //   Called whenever a page is removed from the 
container.
+                       //   Remove the button corresponding to the page.
+                       if(this._currentChild == page){ this._currentChild = 
null; }
+                       var button = this.pane2button[page];
+                       if(button){
+                               button.destroy();
+                       }
+                       this.pane2button[page] = null;
+               },
+
+               onSelectChild: function(/*Widget*/ page){
+                       // Summary
+                       //      Called when a page has been selected in the 
PageContainer, either by me or by another PageController
+                       if(this._currentChild){
+                               var 
oldButton=this.pane2button[this._currentChild];
+                               oldButton.clearSelected();
+                       }
+                       var newButton=this.pane2button[page];
+                       newButton.setSelected();
+                       this._currentChild=page;
+               },
+
+               onButtonClick: function(/*Widget*/ page){
+                       // summary
+                       //   Called whenever one of my child buttons is pressed 
in an attempt to select a page
+                       var container = dojo.widget.byId(this.containerId);     
// TODO: do this via topics?
+                       container.selectChild(page, false, this);
+               },
+
+               onCloseButtonClick: function(/*Widget*/ page){
+                       // summary
+                       //   Called whenever one of my child buttons [X] is 
pressed in an attempt to close a page
+                       var container = dojo.widget.byId(this.containerId);
+                       container.closeChild(page);
+               },
+
+               onKey: function(/*Event*/ evt){
+                       // summary:
+                       //   Handle keystrokes on the page list, for advancing 
to next/previous button
+
+                       if( (evt.keyCode == evt.KEY_RIGHT_ARROW)||
+                               (evt.keyCode == evt.KEY_LEFT_ARROW) ){
+                               var current = 0;
+                               var next = null;        // the next button to 
focus on
+                               
+                               // find currently focused button in children 
array
+                               var current = dojo.lang.find(this.children, 
this.pane2button[this._currentChild]);
+                               
+                               // pick next button to focus on
+                               if(evt.keyCode == evt.KEY_RIGHT_ARROW){
+                                       next = this.children[ (current+1) % 
this.children.length ]; 
+                               }else{ // is LEFT_ARROW
+                                       next = this.children[ (current+ 
(this.children.length-1)) % this.children.length ];
+                               }
+                               
+                               dojo.event.browser.stopEvent(evt);
+                               next.onClick();
+                       }
+               }
+       }
+);
+
+dojo.widget.defineWidget("dojo.widget.PageButton", dojo.widget.HtmlWidget,
+{
+       // summary
+       //      Internal widget used by PageList.
+       //      The button-like or tab-like object you click to select or 
delete a page
+
+       templateString: "<span class='item'>" +
+                                               "<span 
dojoAttachEvent='onClick' dojoAttachPoint='titleNode' 
class='selectButton'>${this.label}</span>" +
+                                               "<span 
dojoAttachEvent='onClick:onCloseButtonClick' class='closeButton'>[X]</span>" +
+                                       "</span>",
+
+       // label: String
+       //  Name to print on the button
+       label: "foo",
+       
+       // closeButton: Boolean
+       //      true iff we should also print a close icon to destroy 
corresponding page
+       closeButton: false,
+
+       onClick: function(){
+               // summary
+               //  Basically this is the attach point PageController listens 
to, to select the page
+               this.focus();
+       },
+
+       onCloseButtonMouseOver: function(){
+               // summary
+               //      The close button changes color a bit when you mouse 
over        
+               dojo.html.addClass(this.closeButtonNode, "closeHover");
+       },
+
+       onCloseButtonMouseOut: function(){
+               // summary
+               //      Revert close button to normal color on mouse out
+               dojo.html.removeClass(this.closeButtonNode, "closeHover");
+       },
+
+       onCloseButtonClick: function(/*Event*/ evt){
+               // summary
+               //      Handle clicking the close button for this tab
+       },
+       
+       setSelected: function(){
+               // summary
+               //      This is run whenever the page corresponding to this 
button has been selected
+               dojo.html.addClass(this.domNode, "current");
+               this.titleNode.setAttribute("tabIndex","0");
+       },
+       
+       clearSelected: function(){
+               // summary
+               //      This function is run whenever the page corresponding to 
this button has been deselected (and another page has been shown)
+               dojo.html.removeClass(this.domNode, "current");
+               this.titleNode.setAttribute("tabIndex","-1");
+       },
+
+       focus: function(){
+               // summary
+               //      This will focus on the this button (for accessibility 
you need to do this when the button is selected)
+               if(this.titleNode.focus){       // mozilla 1.7 doesn't have 
focus() func
+                       this.titleNode.focus();
+               }
+       }
+});
+
+// These arguments can be specified for the children of a PageContainer.
+// Since any widget can be specified as a PageContainer child, mix them
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.lang.extend(dojo.widget.Widget, {
+       // label: String
+       //              Label or title of this widget.  Used by TabContainer to 
the name the tab, etc.
+       label: "",
+       
+       // selected: Boolean
+       //              Is this child currently selected?
+       selected: false,
+       
+       // closable: Boolean
+       //              True if user can close (destroy) this child, such as 
(for example) clicking the X on the tab.
+       closable: false,        // true if user can close this tab pane
+       
+       onClose: function(){
+               // summary: Callback if someone tries to close the child, child 
will be closed if func returns true
+               return true;
+       }
+});
+
+dojo.provide("dojo.widget.TabContainer");
+
+
+
+
+
+
+
+
+dojo.widget.defineWidget("dojo.widget.TabContainer", 
dojo.widget.PageContainer, {
+
+       // summary
+       //      A TabContainer is a container that has multiple panes, but 
shows only
+       //      one pane at a time.  There are a set of tabs corresponding to 
each pane,
+       //      where each tab has the title (aka label) of the pane, and 
optionally a close button.
+       //
+       //      Publishes topics <widgetId>-addChild, <widgetId>-removeChild, 
and <widgetId>-selectChild
+       //      (where <widgetId> is the id of the TabContainer itself.
+
+       // labelPosition: String
+       //   Defines where tab labels go relative to tab content.
+       //   "top", "bottom", "left-h", "right-h"
+       labelPosition: "top",
+       
+       // closeButton: String
+       //   If closebutton=="tab", then every tab gets a close button.
+       //   DEPRECATED:  Should just say closable=true on each
+       //   pane you want to be closable.
+       closeButton: "none",
+
+       templateString: null,   // override setting in PageContainer
+       templatePath: dojo.uri.moduleUri("dojo.widget", 
"templates/TabContainer.html"),
+       templateCssPath: dojo.uri.moduleUri("dojo.widget", 
"templates/TabContainer.css"),
+
+       // selectedTab: String
+       //      initially selected tab (widgetId)
+       //      DEPRECATED: use selectedChild instead.
+       selectedTab: "",
+
+       postMixInProperties: function() {
+               if(this.selectedTab){
+                       dojo.deprecated("selectedTab deprecated, use 
selectedChild instead, will be removed in", "0.5");
+                       this.selectedChild=this.selectedTab;
+               }
+               if(this.closeButton!="none"){
+                       dojo.deprecated("closeButton deprecated, use 
closable='true' on each child instead, will be removed in", "0.5");
+               }
+               
dojo.widget.TabContainer.superclass.postMixInProperties.apply(this, arguments);
+       },
+
+       fillInTemplate: function() {
+               // create the tab list that will have a tab (a.k.a. tab button) 
for each tab panel
+               this.tablist = dojo.widget.createWidget("TabController",
+                       {
+                               id: this.widgetId + "_tablist",
+                               labelPosition: this.labelPosition,
+                               doLayout: this.doLayout,
+                               containerId: this.widgetId
+                       }, this.tablistNode);
+               dojo.widget.TabContainer.superclass.fillInTemplate.apply(this, 
arguments);
+       },
+
+       postCreate: function(args, frag) {      
+               dojo.widget.TabContainer.superclass.postCreate.apply(this, 
arguments);
+
+               // size the container pane to take up the space not used by the 
tabs themselves
+               this.onResized();
+       },
+
+       _setupChild: function(tab){
+               if(this.closeButton=="tab" || this.closeButton=="pane"){
+                       // TODO: remove in 0.5
+                       tab.closable=true;
+               }
+               dojo.html.addClass(tab.domNode, "dojoTabPane");
+               dojo.widget.TabContainer.superclass._setupChild.apply(this, 
arguments);
+       },
+
+       onResized: function(){
+               // Summary: Configure the content pane to take up all the space 
except for where the tabs are
+               if(!this.doLayout){ return; }
+
+               // position the labels and the container node
+               var labelAlign=this.labelPosition.replace(/-h/,"");
+               var children = [
+                       {domNode: this.tablist.domNode, layoutAlign: 
labelAlign},
+                       {domNode: this.containerNode, layoutAlign: "client"}
+               ];
+               dojo.widget.html.layout(this.domNode, children);
+
+               if(this.selectedChildWidget){
+                       var containerSize = 
dojo.html.getContentBox(this.containerNode);
+                       this.selectedChildWidget.resizeTo(containerSize.width, 
containerSize.height);
+               }
+       },
+
+       selectTab: function(tab, callingWidget){
+               dojo.deprecated("use selectChild() rather than selectTab(), 
selectTab() will be removed in", "0.5");
+               this.selectChild(tab, callingWidget);
+       },
+
+       onKey: function(e){
+               // summary
+               //      Keystroke handling for keystrokes on the tab panel 
itself (that were bubbled up to me)
+               //      Ctrl-up: focus is returned from the pane to the tab 
button
+               //      Alt-del: close tab
+               if(e.keyCode == e.KEY_UP_ARROW && e.ctrlKey){
+                       // set focus to current tab
+                       var button = this.correspondingTabButton || 
this.selectedTabWidget.tabButton;
+                       button.focus();
+                       dojo.event.browser.stopEvent(e);
+               }else if(e.keyCode == e.KEY_DELETE && e.altKey){
+                       if (this.selectedChildWidget.closable){
+                               this.closeChild(this.selectedChildWidget);
+                               dojo.event.browser.stopEvent(e);
+                       }
+               }
+       },
+
+       destroy: function(){
+               this.tablist.destroy();
+               dojo.widget.TabContainer.superclass.destroy.apply(this, 
arguments);
+       }
+});
+
+dojo.widget.defineWidget(
+    "dojo.widget.TabController",
+    dojo.widget.PageController,
+       {
+               // summary
+               //      Set of tabs (the things with labels and a close button, 
that you click to show a tab panel).
+               //      Lets the user select the currently shown pane in a 
TabContainer or PageContainer.
+               //      TabController also monitors the TabContainer, and 
whenever a pane is
+               //      added or deleted updates itself accordingly.
+
+               templateString: "<div wairole='tablist' 
dojoAttachEvent='onKey'></div>",
+
+               // labelPosition: String
+               //   Defines where tab labels go relative to tab content.
+               //   "top", "bottom", "left-h", "right-h"
+               labelPosition: "top",
+
+               doLayout: true,
+
+               // class: String
+               //      Class name to apply to the top dom node
+               "class": "",
+
+               // buttonWidget: String
+               //      the name of the tab widget to create to correspond to 
each page
+               buttonWidget: "TabButton",
+
+               postMixInProperties: function() {
+                       if(!this["class"]){
+                               this["class"] = "dojoTabLabels-" + 
this.labelPosition + (this.doLayout ? "" : " dojoTabNoLayout");
+                       }
+                       
dojo.widget.TabController.superclass.postMixInProperties.apply(this, arguments);
+               }
+       }
+);
+
+dojo.widget.defineWidget("dojo.widget.TabButton", dojo.widget.PageButton,
+{
+       // summary
+       //      A tab (the thing you click to select a pane).
+       //      Contains the title (aka label) of the pane, and optionally a 
close-button to destroy the pane.
+       //      This is an internal widget and should not be instantiated 
directly.
+
+       templateString: "<div class='dojoTab' dojoAttachEvent='onClick'>"
+                                               +"<div 
dojoAttachPoint='innerDiv'>"
+                                                       +"<span 
dojoAttachPoint='titleNode' tabIndex='-1' waiRole='tab'>${this.label}</span>"
+                                                       +"<span 
dojoAttachPoint='closeButtonNode' class='close closeImage' 
style='${this.closeButtonStyle}'"
+                                                       +"    
dojoAttachEvent='onMouseOver:onCloseButtonMouseOver; 
onMouseOut:onCloseButtonMouseOut; onClick:onCloseButtonClick'></span>"
+                                               +"</div>"
+                                       +"</div>",
+
+       postMixInProperties: function(){
+               this.closeButtonStyle = this.closeButton ? "" : "display: none";
+               
dojo.widget.TabButton.superclass.postMixInProperties.apply(this, arguments);
+       },
+
+       fillInTemplate: function(){
+               dojo.html.disableSelection(this.titleNode);
+               dojo.widget.TabButton.superclass.fillInTemplate.apply(this, 
arguments);
+       },
+       
+       onCloseButtonClick: function(/*Event*/ evt){
+               // since the close button is located inside the select button, 
make sure that the select
+               // button doesn't inadvertently get an onClick event
+               evt.stopPropagation();
+               dojo.widget.TabButton.superclass.onCloseButtonClick.apply(this, 
arguments);
+       }
+});
+
+
+dojo.widget.defineWidget(
+       "dojo.widget.a11y.TabButton",
+       dojo.widget.TabButton,
+       {
+               // summary
+               //      Tab for display in high-contrast mode (where background 
images don't show up).
+               //      This is an internal widget and shouldn't be 
instantiated directly.
+
+               imgPath: dojo.uri.moduleUri("dojo.widget", 
"templates/images/tab_close.gif"),
+               
+               templateString: "<div class='dojoTab' 
dojoAttachEvent='onClick;onKey'>"
+                                                       +"<div 
dojoAttachPoint='innerDiv'>"
+                                                               +"<span 
dojoAttachPoint='titleNode' tabIndex='-1' waiRole='tab'>${this.label}</span>"
+                                                               +"<img 
class='close' src='${this.imgPath}' alt='[x]' style='${this.closeButtonStyle}'"
+                                                               +"    
dojoAttachEvent='onClick:onCloseButtonClick'>"
+                                                       +"</div>"
+                                               +"</div>"
+       }
+);
+
+dojo.provide("struts.widget.StrutsTabContainer");
+
+
+
+dojo.widget.defineWidget(
+  "struts.widget.StrutsTabContainer",
+  dojo.widget.TabContainer, {
+  widgetType : "StrutsTabContainer",
+
+  afterSelectTabNotifyTopics : "",
+  afterSelectTabNotifyTopicsArray : null,
+  beforeSelectTabNotifyTopics : "",
+  beforeSelectTabNotifyTopicsArray : null,
+
+  disabledTabCssClass : "strutsDisabledTab",
+  
+  postCreate : function() {
+    struts.widget.StrutsTabContainer.superclass.postCreate.apply(this);
+    
+    //before topics
+    if(!dojo.string.isBlank(this.beforeSelectTabNotifyTopics)) {
+      this.beforeSelectTabNotifyTopicsArray = 
this.beforeSelectTabNotifyTopics.split(",");
+    }
+    
+    //after topics
+    if(!dojo.string.isBlank(this.afterSelectTabNotifyTopics)) {
+      this.afterSelectTabNotifyTopicsArray = 
this.afterSelectTabNotifyTopics.split(",");
+    }
+    
+    // add disabled class to disabled tabs
+    if(this.disabledTabCssClass) {
+      dojo.lang.forEach(this.children, function(div){
+        if(div.disabled) {
+          this.disableTab(div);
+        }
+      });
+    }
+  },
+   
+  selectChild: function (tab, callingWidget)  {
+    if(!tab.disabled) {
+      var cancel = {"cancel" : false};
+      
+      if(this.beforeSelectTabNotifyTopicsArray) {
+        var self = this;
+        dojo.lang.forEach(this.beforeSelectTabNotifyTopicsArray, 
function(topic) {
+          try {
+            dojo.event.topic.publish(topic, self, tab, cancel);
+          } catch(ex){
+            dojo.debug(ex);
+          }
+        });   
+      }
+      
+      if(!cancel.cancel) {
+        struts.widget.StrutsTabContainer.superclass.selectChild.apply(this, 
[tab, callingWidget]);
+        
+        if(this.afterSelectTabNotifyTopicsArray) {
+          var self = this;
+          dojo.lang.forEach(this.afterSelectTabNotifyTopicsArray, 
function(topic) {
+            try {
+              dojo.event.topic.publish(topic, self, tab, cancel);
+            } catch(ex){
+              dojo.debug(ex);
+            }
+          });   
+        }
+      } 
+    } 
+  },
+  
+  disableTab : function(t) {
+    var tabWidget = this.getTabWidget(t);
+    tabWidget.disabled = true;
+    dojo.html.addClass(tabWidget.controlButton.domNode, 
this.disabledTabCssClass);
+  },
+  
+  enableTab : function(t) {
+    var tabWidget = this.getTabWidget(t);
+    tabWidget.disabled = false;
+    dojo.html.removeClass(tabWidget.controlButton.domNode, 
this.disabledTabCssClass);
+  },
+  
+  getTabWidget : function(t) {
+    if(dojo.lang.isNumber(t)) {
+      //tab index
+      return this.children[t];
+    } else if(dojo.lang.isString(t)) {
+      //tab id
+      return dojo.widget.byId(t);
+    } else {
+      //tab widget?
+      return t;
+    }
+  }
+});
+
 dojo.kwCompoundRequire({
        common: ["struts.widget.Bind",
                 "struts.widget.BindDiv",
@@ -28115,7 +28839,8 @@
              "struts.widget.StrutsTimePicker",
              "struts.widget.StrutsDatePicker",
              "struts.widget.BindEvent",
-             "struts.widget.StrutsTreeSelector"]
+             "struts.widget.StrutsTreeSelector",
+             "struts.widget.StrutsTabContainer"]
 });
 dojo.provide("struts.widget.*");
 

Modified: 
struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/div.ftl
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/div.ftl?view=diff&rev=535556&r1=535555&r2=535556
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/div.ftl 
(original)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/div.ftl 
Sat May  5 11:45:02 2007
@@ -26,6 +26,9 @@
   <#if parameters.preload?exists>
     preload="${parameters.preload?string?html}"<#rt/>
   </#if>
+  <#if parameters.disabled?exists>
+    disabled="${parameters.disabled?string?html}"<#rt/>
+  </#if>
   <#include "/${parameters.templateDir}/ajax/ajax-common.ftl" />
   <#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
   <#include "/${parameters.templateDir}/simple/common-attributes.ftl" />

Modified: 
struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/tabbedpanel.ftl
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/tabbedpanel.ftl?view=diff&rev=535556&r1=535555&r2=535556
==============================================================================
--- 
struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/tabbedpanel.ftl
 (original)
+++ 
struts/struts2/trunk/plugins/dojo/src/main/resources/template/ajax/tabbedpanel.ftl
 Sat May  5 11:45:02 2007
@@ -1,3 +1,4 @@
+<link rel="stylesheet" href="${base}/struts/TabbedPanel.css" type="text/css"/>
 <div dojoType="struts:StrutsTabContainer"
   <#if parameters.cssStyle?if_exists != "">
     style="${parameters.cssStyle?html}"<#rt/>
@@ -31,6 +32,9 @@
   </#if>
   <#if parameters.afterSelectTabNotifyTopics?if_exists != "">
     
afterSelectTabNotifyTopics="${parameters.afterSelectTabNotifyTopics?html}"<#rt/>
+  </#if>
+  <#if parameters.disabledTabCssClass?if_exists != "">
+    disabledTabCssClass="${parameters.disabledTabCssClass?html}"<#rt/>
   </#if>
   <#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
   <#include "/${parameters.templateDir}/simple/common-attributes.ftl" />


Reply via email to