You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by he...@apache.org on 2006/11/13 23:55:14 UTC
svn commit: r474551 [40/49] - in
/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo:
./ src/ src/alg/ src/animation/ src/cal/ src/charting/ src/charting/svg/
src/charting/vml/ src/collections/ src/crypto/ src/data/ src/data/cs...
Added: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SortableTable.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SortableTable.js?view=auto&rev=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SortableTable.js (added)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SortableTable.js Mon Nov 13 14:54:45 2006
@@ -0,0 +1,615 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.SortableTable");
+
+dojo.deprecated("SortableTable will be removed in favor of FilteringTable.", "0.5");
+
+dojo.require("dojo.lang.common");
+dojo.require("dojo.date.format");
+dojo.require("dojo.html.*");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.html.util");
+dojo.require("dojo.html.style");
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+
+dojo.widget.defineWidget(
+ "dojo.widget.SortableTable",
+ dojo.widget.HtmlWidget,
+ function(){
+ this.data=[];
+ this.selected=[]; // always an array to handle multiple selections.
+ this.columns=[];
+ },
+ {
+ // custom properties
+ enableMultipleSelect: false,
+ maximumNumberOfSelections: 0, // 0 for unlimited, is the default.
+ enableAlternateRows: false,
+ minRows: 0, // 0 means ignore.
+ defaultDateFormat: "%D",
+ sortIndex: 0, // index of the column sorted on, first is the default.
+ sortDirection: 0, // 0==asc, 1==desc
+ valueField: "Id", // if a JSON structure is parsed and there is a field of this name,
+ // a value attribute will be added to the row (tr value="{Id}")
+
+ headClass: "",
+ tbodyClass: "",
+ headerClass: "",
+ headerSortUpClass: "selected",
+ headerSortDownClass: "selected",
+ rowClass: "",
+ rowAlternateClass: "alt",
+ rowSelectedClass: "selected",
+ columnSelected: "sorted-column",
+
+ isContainer: false,
+ templatePath:null,
+ templateCssPath:null,
+
+ getTypeFromString:function(/* string */ s){
+ // summary
+ // Find the constructor that matches param s by searching through the entire object tree.
+ var parts=s.split("."),i=0,obj=dj_global;
+ do{obj=obj[parts[i++]];}while(i<parts.length&&obj);
+ return(obj!=dj_global)?obj:null; // function
+ },
+ compare:function(/* object */ o1, /* object */ o2){
+ // summary
+ // Compare two objects using a shallow property compare
+ for(var p in o1){
+ if(!(p in o2)) return false; // boolean
+ if(o1[p].valueOf()!=o2[p].valueOf()) return false; // boolean
+ }
+ return true; // boolean
+ },
+ isSelected:function(/* object */ o){
+ // summary
+ // checked to see if the passed object is in the current selection.
+ for(var i=0;i<this.selected.length;i++){
+ if(this.compare(this.selected[i],o)){
+ return true; // boolean
+ }
+ }
+ return false; // boolean
+ },
+ removeFromSelected:function(/* object */ o){
+ // summary
+ // remove the passed object from the current selection.
+ var idx=-1;
+ for(var i=0;i<this.selected.length;i++){
+ if(this.compare(this.selected[i],o)){
+ idx=i;
+ break;
+ }
+ }
+ if(idx>=0){
+ this.selected.splice(idx,1);
+ }
+ },
+ getSelection:function(){
+ // summary
+ // return the array of currently selected objects (JSON format)
+ return this.selected; // array
+ },
+ getValue:function(){
+ // summary
+ // return a comma-delimited list of selected valueFields.
+ var a=[];
+ for(var i=0;i<this.selected.length;i++){
+ if (this.selected[i][this.valueField]){
+ a.push(this.selected[i][this.valueField]);
+ }
+ }
+ return a.join(); // string
+ },
+ reset:function(){
+ // summary
+ // completely resets the internal representations.
+ this.columns=[];
+ this.data=[];
+ this.resetSelections(this.domNode.getElementsByTagName("tbody")[0]);
+ },
+ resetSelections:function(/* HTMLTableBodyElement */ body){
+ this.selected=[];
+ var idx=0;
+ var rows=body.getElementsByTagName("tr");
+ for(var i=0; i<rows.length; i++){
+ if(rows[i].parentNode==body){
+ rows[i].removeAttribute("selected");
+ if(this.enableAlternateRows&&idx%2==1){
+ rows[i].className=this.rowAlternateClass;
+ }else{
+ rows[i].className="";
+ }
+ idx++;
+ }
+ }
+ },
+
+ getObjectFromRow:function(/* HTMLTableRowElement */ row){
+ // summary
+ // creates a JSON object based on the passed row
+ var cells=row.getElementsByTagName("td");
+ var o={};
+ for(var i=0; i<this.columns.length;i++){
+ if(this.columns[i].sortType=="__markup__"){
+ // FIXME: should we parse this instead? Because if the user may not get back the markup they put in...
+ o[this.columns[i].getField()]=cells[i].innerHTML;
+ }else{
+ var text=dojo.html.renderedTextContent(cells[i]);
+ var val=text;
+ if (this.columns[i].getType() != String){
+ var val=new (this.columns[i].getType())(text);
+ }
+ o[this.columns[i].getField()]=val;
+ }
+ }
+ if(dojo.html.hasAttribute(row,"value")){
+ o[this.valueField]=dojo.html.getAttribute(row,"value");
+ }
+ return o; // object
+ },
+ setSelectionByRow:function(/* HTMLTableElementRow */ row){
+ // summary
+ // create the selection object based on the passed row, makes sure it's unique.
+ // note that you need to call render manually (because of multi-select operations)
+ var o=this.getObjectFromRow(row);
+ var b=false;
+ for(var i=0;i<this.selected.length;i++){
+ if(this.compare(this.selected[i], o)){
+ b=true;
+ break;
+ }
+ }
+ if(!b){
+ this.selected.push(o);
+ }
+ },
+
+ parseColumns:function(/* HTMLTableHeadElement */ node){
+ // summary
+ // parses the passed element to create column objects
+ this.reset();
+ var row=node.getElementsByTagName("tr")[0];
+ var cells=row.getElementsByTagName("td");
+ if (cells.length==0) cells=row.getElementsByTagName("th");
+ for(var i=0; i<cells.length; i++){
+ var o={
+ field:null,
+ format:null,
+ noSort:false,
+ sortType:"String",
+ dataType:String,
+ sortFunction:null,
+ label:null,
+ align:"left",
+ valign:"middle",
+ getField:function(){ return this.field||this.label; },
+ getType:function(){ return this.dataType; }
+ };
+ // presentation attributes
+ if(dojo.html.hasAttribute(cells[i], "align")){
+ o.align=dojo.html.getAttribute(cells[i],"align");
+ }
+ if(dojo.html.hasAttribute(cells[i], "valign")){
+ o.valign=dojo.html.getAttribute(cells[i],"valign");
+ }
+
+ // sorting features.
+ if(dojo.html.hasAttribute(cells[i], "nosort")){
+ o.noSort=dojo.html.getAttribute(cells[i],"nosort")=="true";
+ }
+ if(dojo.html.hasAttribute(cells[i], "sortusing")){
+ var trans=dojo.html.getAttribute(cells[i],"sortusing");
+ var f=this.getTypeFromString(trans);
+ if (f!=null && f!=window && typeof(f)=="function")
+ o.sortFunction=f;
+ }
+
+ if(dojo.html.hasAttribute(cells[i], "field")){
+ o.field=dojo.html.getAttribute(cells[i],"field");
+ }
+ if(dojo.html.hasAttribute(cells[i], "format")){
+ o.format=dojo.html.getAttribute(cells[i],"format");
+ }
+ if(dojo.html.hasAttribute(cells[i], "dataType")){
+ var sortType=dojo.html.getAttribute(cells[i],"dataType");
+ if(sortType.toLowerCase()=="html"||sortType.toLowerCase()=="markup"){
+ o.sortType="__markup__"; // always convert to "__markup__"
+ o.noSort=true;
+ }else{
+ var type=this.getTypeFromString(sortType);
+ if(type){
+ o.sortType=sortType;
+ o.dataType=type;
+ }
+ }
+ }
+ o.label=dojo.html.renderedTextContent(cells[i]);
+ this.columns.push(o);
+
+ // check to see if there's a default sort, and set the properties necessary
+ if(dojo.html.hasAttribute(cells[i], "sort")){
+ this.sortIndex=i;
+ var dir=dojo.html.getAttribute(cells[i], "sort");
+ if(!isNaN(parseInt(dir))){
+ dir=parseInt(dir);
+ this.sortDirection=(dir!=0)?1:0;
+ }else{
+ this.sortDirection=(dir.toLowerCase()=="desc")?1:0;
+ }
+ }
+ }
+ },
+
+ parseData:function(/* array */ data){
+ // summary
+ // Parse the passed JSON data structure, and cast based on columns.
+ this.data=[];
+ this.selected=[];
+ for(var i=0; i<data.length; i++){
+ var o={}; // new data object.
+ for(var j=0; j<this.columns.length; j++){
+ var field=this.columns[j].getField();
+ if(this.columns[j].sortType=="__markup__"){
+ o[field]=String(data[i][field]);
+ }else{
+ var type=this.columns[j].getType();
+ var val=data[i][field];
+ var t=this.columns[j].sortType.toLowerCase();
+ if(type == String) {
+ o[field]=val;
+ } else {
+ if(val!=null){
+ o[field]=new type(val);
+ }else{
+ o[field]=new type(); // let it use the default.
+ }
+ }
+ }
+ }
+ // check for the valueField if not already parsed.
+ if(data[i][this.valueField]&&!o[this.valueField]){
+ o[this.valueField]=data[i][this.valueField];
+ }
+ this.data.push(o);
+ }
+ },
+
+ parseDataFromTable:function(/* HTMLTableBodyElement */ tbody){
+ // summary
+ // parses the data in the tbody of a table to create a set of objects.
+ // Will add objects to this.selected if an attribute 'selected="true"' is present on the row.
+ this.data=[];
+ this.selected=[];
+ var rows=tbody.getElementsByTagName("tr");
+ for(var i=0; i<rows.length; i++){
+ if(dojo.html.getAttribute(rows[i],"ignoreIfParsed")=="true"){
+ continue;
+ }
+ var o={}; // new data object.
+ var cells=rows[i].getElementsByTagName("td");
+ for(var j=0; j<this.columns.length; j++){
+ var field=this.columns[j].getField();
+ if(this.columns[j].sortType=="__markup__"){
+ // FIXME: parse this?
+ o[field]=cells[j].innerHTML;
+ }else{
+ var type=this.columns[j].getType();
+ var val=dojo.html.renderedTextContent(cells[j]); // should be the same index as the column.
+ if(type == String){
+ o[field]=val;
+ } else {
+ if (val!=null){
+ o[field]=new type(val);
+ } else {
+ o[field]=new type(); // let it use the default.
+ }
+ }
+ }
+ }
+ if(dojo.html.hasAttribute(rows[i],"value")&&!o[this.valueField]){
+ o[this.valueField]=dojo.html.getAttribute(rows[i],"value");
+ }
+ // FIXME: add code to preserve row attributes in __metadata__ field?
+ this.data.push(o);
+
+ // add it to the selections if selected="true" is present.
+ if(dojo.html.getAttribute(rows[i],"selected")=="true"){
+ this.selected.push(o);
+ }
+ }
+ },
+
+ showSelections:function(){
+ var body=this.domNode.getElementsByTagName("tbody")[0];
+ var rows=body.getElementsByTagName("tr");
+ var idx=0;
+ for(var i=0; i<rows.length; i++){
+ if(rows[i].parentNode==body){
+ if(dojo.html.getAttribute(rows[i],"selected")=="true"){
+ rows[i].className=this.rowSelectedClass;
+ } else {
+ if(this.enableAlternateRows&&idx%2==1){
+ rows[i].className=this.rowAlternateClass;
+ }else{
+ rows[i].className="";
+ }
+ }
+ idx++;
+ }
+ }
+ },
+ render:function(bDontPreserve){
+ // summary
+ // renders the table to the browser
+ var data=[];
+ var body=this.domNode.getElementsByTagName("tbody")[0];
+
+ if(!bDontPreserve){
+ // rebuild data and selection
+ this.parseDataFromTable(body);
+ }
+
+ // clone this.data for sorting purposes.
+ for(var i=0; i<this.data.length; i++){
+ data.push(this.data[i]);
+ }
+
+ var col=this.columns[this.sortIndex];
+ if(!col.noSort){
+ var field=col.getField();
+ if(col.sortFunction){
+ var sort=col.sortFunction;
+ }else{
+ var sort=function(a,b){
+ if (a[field]>b[field]) return 1;
+ if (a[field]<b[field]) return -1;
+ return 0;
+ }
+ }
+ data.sort(sort);
+ if(this.sortDirection!=0) data.reverse();
+ }
+
+ // build the table and pop it in.
+ while(body.childNodes.length>0) body.removeChild(body.childNodes[0]);
+ for(var i=0; i<data.length;i++){
+ var row=document.createElement("tr");
+ dojo.html.disableSelection(row);
+ if (data[i][this.valueField]){
+ row.setAttribute("value",data[i][this.valueField]);
+ }
+ if(this.isSelected(data[i])){
+ row.className=this.rowSelectedClass;
+ row.setAttribute("selected","true");
+ } else {
+ if(this.enableAlternateRows&&i%2==1){
+ row.className=this.rowAlternateClass;
+ }
+ }
+ for(var j=0;j<this.columns.length;j++){
+ var cell=document.createElement("td");
+ cell.setAttribute("align", this.columns[j].align);
+ cell.setAttribute("valign", this.columns[j].valign);
+ dojo.html.disableSelection(cell);
+ if(this.sortIndex==j){
+ cell.className=this.columnSelected;
+ }
+ if(this.columns[j].sortType=="__markup__"){
+ cell.innerHTML=data[i][this.columns[j].getField()];
+ for(var k=0; k<cell.childNodes.length; k++){
+ var node=cell.childNodes[k];
+ if(node&&node.nodeType==dojo.html.ELEMENT_NODE){
+ dojo.html.disableSelection(node);
+ }
+ }
+ }else{
+ if(this.columns[j].getType()==Date){
+ var format=this.defaultDateFormat;
+ if(this.columns[j].format) format=this.columns[j].format;
+ cell.appendChild(document.createTextNode(dojo.date.strftime(data[i][this.columns[j].getField()], format)));
+ }else{
+ cell.appendChild(document.createTextNode(data[i][this.columns[j].getField()]));
+ }
+ }
+ row.appendChild(cell);
+ }
+ body.appendChild(row);
+ dojo.event.connect(row, "onclick", this, "onUISelect");
+ }
+
+ // if minRows exist.
+ var minRows=parseInt(this.minRows);
+ if (!isNaN(minRows) && minRows>0 && data.length<minRows){
+ var mod=0;
+ if(data.length%2==0) mod=1;
+ var nRows=minRows-data.length;
+ for(var i=0; i<nRows; i++){
+ var row=document.createElement("tr");
+ row.setAttribute("ignoreIfParsed","true");
+ if(this.enableAlternateRows&&i%2==mod){
+ row.className=this.rowAlternateClass;
+ }
+ for(var j=0;j<this.columns.length;j++){
+ var cell=document.createElement("td");
+ cell.appendChild(document.createTextNode("\u00A0"));
+ row.appendChild(cell);
+ }
+ body.appendChild(row);
+ }
+ }
+ },
+
+ // the following the user can override.
+ onSelect:function(/* DomEvent */ e){
+ // summary
+ // empty function for the user to attach code to, fired by onUISelect
+ },
+ onUISelect:function(/* DomEvent */ e){
+ // summary
+ // fired when a user selects a row
+ var row=dojo.html.getParentByType(e.target,"tr");
+ var body=dojo.html.getParentByType(row,"tbody");
+ if(this.enableMultipleSelect){
+ if(e.metaKey||e.ctrlKey){
+ if(this.isSelected(this.getObjectFromRow(row))){
+ this.removeFromSelected(this.getObjectFromRow(row));
+ row.removeAttribute("selected");
+ }else{
+ // push onto the selection stack.
+ this.setSelectionByRow(row);
+ row.setAttribute("selected","true");
+ }
+ }else if(e.shiftKey){
+ // the tricky one. We need to figure out the *last* selected row above,
+ // and select all the rows in between.
+ var startRow;
+ var rows=body.getElementsByTagName("tr");
+ // if there's a selection above, we go with that first.
+ for(var i=0;i<rows.length;i++){
+ if(rows[i].parentNode==body){
+ if(rows[i]==row) break;
+ if(dojo.html.getAttribute(rows[i],"selected")=="true"){
+ startRow=rows[i];
+ }
+ }
+ }
+ // if there isn't a selection above, we continue with a selection below.
+ if(!startRow){
+ startRow=row;
+ for(;i<rows.length;i++){
+ if(dojo.html.getAttribute(rows[i],"selected")=="true"){
+ row=rows[i];
+ break;
+ }
+ }
+ }
+ this.resetSelections(body);
+ if(startRow==row){
+ // this is the only selection
+ row.setAttribute("selected","true");
+ this.setSelectionByRow(row);
+ }else{
+ var doSelect=false;
+ for(var i=0; i<rows.length; i++){
+ if(rows[i].parentNode==body){
+ rows[i].removeAttribute("selected");
+ if(rows[i]==startRow){
+ doSelect=true;
+ }
+ if(doSelect){
+ this.setSelectionByRow(rows[i]);
+ rows[i].setAttribute("selected","true");
+ }
+ if(rows[i]==row){
+ doSelect=false;
+ }
+ }
+ }
+ }
+ }else{
+ // reset the selection
+ this.resetSelections(body);
+ row.setAttribute("selected","true");
+ this.setSelectionByRow(row);
+ }
+ }else{
+ // reset the data selection and go.
+ this.resetSelections(body);
+ row.setAttribute("selected","true");
+ this.setSelectionByRow(row);
+ }
+ this.showSelections();
+ this.onSelect(e);
+ e.stopPropagation();
+ e.preventDefault();
+ },
+ onHeaderClick:function(/* DomEvent */ e){
+ // summary
+ // Main handler function for each header column click.
+ var oldIndex=this.sortIndex;
+ var oldDirection=this.sortDirection;
+ var source=e.target;
+ var row=dojo.html.getParentByType(source,"tr");
+ var cellTag="td";
+ if(row.getElementsByTagName(cellTag).length==0) cellTag="th";
+
+ var headers=row.getElementsByTagName(cellTag);
+ var header=dojo.html.getParentByType(source,cellTag);
+
+ for(var i=0; i<headers.length; i++){
+ if(headers[i]==header){
+ if(i!=oldIndex){
+ // new col.
+ this.sortIndex=i;
+ this.sortDirection=0;
+ headers[i].className=this.headerSortDownClass
+ }else{
+ this.sortDirection=(oldDirection==0)?1:0;
+ if(this.sortDirection==0){
+ headers[i].className=this.headerSortDownClass;
+ }else{
+ headers[i].className=this.headerSortUpClass;
+ }
+ }
+ }else{
+ // reset the header class.
+ headers[i].className=this.headerClass;
+ }
+ }
+ this.render();
+ },
+
+ postCreate:function(){
+ // summary
+ // overridden from HtmlWidget, initializes and renders the widget.
+ var thead=this.domNode.getElementsByTagName("thead")[0];
+ if(this.headClass.length>0){
+ thead.className=this.headClass;
+ }
+
+ // disable selections
+ dojo.html.disableSelection(this.domNode);
+
+ // parse the columns.
+ this.parseColumns(thead);
+
+ // attach header handlers.
+ var header="td";
+ if(thead.getElementsByTagName(header).length==0) header="th";
+ var headers=thead.getElementsByTagName(header);
+ for(var i=0; i<headers.length; i++){
+ if(!this.columns[i].noSort){
+ dojo.event.connect(headers[i], "onclick", this, "onHeaderClick");
+ }
+ if(this.sortIndex==i){
+ if(this.sortDirection==0){
+ headers[i].className=this.headerSortDownClass;
+ }else{
+ headers[i].className=this.headerSortUpClass;
+ }
+ }
+ }
+
+ // parse the tbody element and re-render it.
+ var tbody=this.domNode.getElementsByTagName("tbody")[0];
+ if (this.tbodyClass.length>0) {
+ tbody.className=this.tbodyClass;
+ }
+
+ this.parseDataFromTable(tbody);
+ this.render(true);
+ }
+ }
+);
Propchange: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SortableTable.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Spinner.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Spinner.js?view=auto&rev=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Spinner.js (added)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Spinner.js Mon Nov 13 14:54:45 2006
@@ -0,0 +1,622 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Spinner");
+
+dojo.require("dojo.io.*");
+dojo.require("dojo.lfx.*");
+dojo.require("dojo.html.*");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.string");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.IntegerTextbox");
+dojo.require("dojo.widget.RealNumberTextbox");
+dojo.require("dojo.widget.DateTextbox");
+
+dojo.require("dojo.experimental");
+
+// summary: Mixin for validation widgets with a spinner
+// description: This class basically (conceptually) extends dojo.widget.ValidationTextbox.
+// It modifies the template to have up/down arrows, and provides related handling code.
+dojo.declare(
+ "dojo.widget.Spinner",
+ null,
+ {
+ _typamaticTimer: null,
+ _typamaticFunction: null,
+ _currentTimeout: this.defaultTimeout,
+ _eventCount: 0,
+ // Number
+ // number of milliseconds before a held key or button becomes typematic
+ defaultTimeout: 500,
+ // Number
+ // fraction of time used to change the typematic timer between events
+ // 1.0 means that each typematic event fires at defaultTimeout intervals
+ // < 1.0 means that each typematic event fires at an increasing faster rate
+ timeoutChangeRate: 0.90,
+
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Spinner.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/Spinner.css"),
+ // String
+ // up arrow graphic URL
+ incrementSrc: dojo.uri.dojoUri("src/widget/templates/images/spinnerIncrement.gif"),
+ // String
+ // down arrow graphic URL
+ decrementSrc: dojo.uri.dojoUri("src/widget/templates/images/spinnerDecrement.gif"),
+
+ // does the keyboard related stuff
+ _handleKeyEvents: function(/*Event*/ evt){
+ if(!evt.key){ return; }
+
+ if(!evt.ctrlKey && !evt.altKey){
+ switch(evt.key){
+ case evt.KEY_DOWN_ARROW:
+ dojo.event.browser.stopEvent(evt);
+ this._downArrowPressed(evt);
+ return;
+ case evt.KEY_UP_ARROW:
+ dojo.event.browser.stopEvent(evt);
+ this._upArrowPressed(evt);
+ return;
+ }
+ }
+ this._eventCount++;
+ },
+
+ _onSpinnerKeyUp: function(/*Event*/ evt){
+ this._arrowReleased(evt);
+ this.onkeyup(evt);
+ },
+
+ // reset button size; this function is called when the input area has changed size
+ _resize: function(){
+ var inputSize = dojo.html.getBorderBox(this.textbox);
+ this.buttonSize = { width: inputSize.height / 2, height: inputSize.height / 2 };
+ if(this.upArrowNode){
+ dojo.html.setMarginBox(this.upArrowNode, this.buttonSize);
+ dojo.html.setMarginBox(this.downArrowNode, this.buttonSize);
+ }
+ },
+
+ _pressButton: function(/*DomNode*/ node){
+ node.style.borderWidth = "1px 0px 0px 1px";
+ node.style.borderStyle = "inset";
+ },
+
+ _releaseButton: function(/*DomNode*/ node){
+ node.style.borderWidth = "0px 1px 1px 0px";
+ node.style.borderStyle = "outset";
+ },
+
+ _arrowPressed: function(/*Event*/ evt, /*Number*/ direction){
+ var nodePressed = (direction == -1) ? this.downArrowNode : this.upArrowNode;
+ var nodeReleased = (direction == +1) ? this.downArrowNode : this.upArrowNode;
+ if(typeof evt != "number"){
+ if(this._typamaticTimer != null){
+ if(this._typamaticNode == nodePressed){
+ return;
+ }
+ dojo.lang.clearTimeout(this._typamaticTimer);
+ }
+ this._releaseButton(nodeReleased);
+ this._eventCount++;
+ this._typamaticTimer = null;
+ this._currentTimeout = this.defaultTimeout;
+
+ }else if (evt != this._eventCount){
+ this._releaseButton(nodePressed);
+ return;
+ }
+ this._pressButton(nodePressed);
+ this._setCursorX(this.adjustValue(direction,this._getCursorX()));
+ this._typamaticNode = nodePressed;
+ this._typamaticTimer = dojo.lang.setTimeout(this, "_arrowPressed", this._currentTimeout, this._eventCount, direction);
+ this._currentTimeout = Math.round(this._currentTimeout * this.timeoutChangeRate);
+ },
+
+ _downArrowPressed: function(/*Event*/ evt){
+ return this._arrowPressed(evt,-1);
+ },
+
+ // IE sends these events when rapid clicking, mimic an extra single click
+ _downArrowDoubleClicked: function(/*Event*/ evt){
+ var rc = this._downArrowPressed(evt);
+ dojo.lang.setTimeout(this, "_arrowReleased", 50, null);
+ return rc;
+ },
+
+ _upArrowPressed: function(/*Event*/ evt){
+ return this._arrowPressed(evt,+1);
+ },
+
+ // IE sends these events when rapid clicking, mimic an extra single click
+ _upArrowDoubleClicked: function(/*Event*/ evt){
+ var rc = this._upArrowPressed(evt);
+ dojo.lang.setTimeout(this, "_arrowReleased", 50, null);
+ return rc;
+ },
+
+ _arrowReleased: function(/*Event*/ evt){
+ this.textbox.focus();
+ if(evt != null && typeof evt == "object" && evt.keyCode && evt.keyCode != null){
+ var keyCode = evt.keyCode;
+ var k = dojo.event.browser.keys;
+
+ switch(keyCode){
+ case k.KEY_DOWN_ARROW:
+ case k.KEY_UP_ARROW:
+ dojo.event.browser.stopEvent(evt);
+ break;
+ }
+ }
+ this._releaseButton(this.upArrowNode);
+ this._releaseButton(this.downArrowNode);
+ this._eventCount++;
+ if(this._typamaticTimer != null){
+ dojo.lang.clearTimeout(this._typamaticTimer);
+ }
+ this._typamaticTimer = null;
+ this._currentTimeout = this.defaultTimeout;
+ },
+
+ _mouseWheeled: function(/*Event*/ evt){
+ var scrollAmount = 0;
+ if(typeof evt.wheelDelta == 'number'){ // IE
+ scrollAmount = evt.wheelDelta;
+ }else if (typeof evt.detail == 'number'){ // Mozilla+Firefox
+ scrollAmount = -evt.detail;
+ }
+ if(scrollAmount > 0){
+ this._upArrowPressed(evt);
+ this._arrowReleased(evt);
+ }else if (scrollAmount < 0){
+ this._downArrowPressed(evt);
+ this._arrowReleased(evt);
+ }
+ },
+
+ _discardEvent: function(/*Event*/ evt){
+ dojo.event.browser.stopEvent(evt);
+ },
+
+ _getCursorX: function(){
+ var x = -1;
+ try{
+ this.textbox.focus();
+ if (typeof this.textbox.selectionEnd == "number"){
+ x = this.textbox.selectionEnd;
+ }else if (document.selection && document.selection.createRange){
+ var range = document.selection.createRange().duplicate();
+ if(range.parentElement() == this.textbox){
+ range.moveStart('textedit', -1);
+ x = range.text.length;
+ }
+ }
+ }catch(e){ /* squelch! */ }
+ return x;
+ },
+
+ _setCursorX: function(/*Number*/ x){
+ try{
+ this.textbox.focus();
+ if(!x){ x = 0; }
+ if(typeof this.textbox.selectionEnd == "number"){
+ this.textbox.selectionEnd = x;
+ }else if(this.textbox.createTextRange){
+ var range = this.textbox.createTextRange();
+ range.collapse(true);
+ range.moveEnd('character', x);
+ range.moveStart('character', x);
+ range.select();
+ }
+ }catch(e){ /* squelch! */ }
+ },
+
+ _spinnerPostMixInProperties: function(/*Object*/ args, /*Object*/ frag){
+ // summary: the widget's postMixInProperties() method should call this method
+
+ // set image size before instantiating template;
+ // changing it aftwards doesn't work on FF
+ var inputNode = this.getFragNodeRef(frag);
+ var inputSize = dojo.html.getBorderBox(inputNode);
+ this.buttonSize = { width: inputSize.height / 2 - 1, height: inputSize.height / 2 - 1};
+ },
+
+ _spinnerPostCreate: function(/*Object*/ args, /*Object*/ frag){
+ // summary: the widget's postCreate() method should call this method
+
+ // extra listeners
+ if(this.textbox.addEventListener){
+ // dojo.event.connect() doesn't seem to work with DOMMouseScroll
+ this.textbox.addEventListener('DOMMouseScroll', dojo.lang.hitch(this, "_mouseWheeled"), false); // Mozilla + Firefox + Netscape
+ }else{
+ dojo.event.connect(this.textbox, "onmousewheel", this, "_mouseWheeled"); // IE + Safari
+ }
+ //dojo.event.connect(window, "onchange", this, "_resize");
+ }
+ }
+);
+
+// summary
+// create spinable, single integer, input field
+dojo.widget.defineWidget(
+ "dojo.widget.IntegerSpinner",
+ [dojo.widget.IntegerTextbox, dojo.widget.Spinner],
+{
+ // summary: an IntegerSpinner with +/- buttons
+
+ // Number
+ // increment amount
+ delta: "1",
+
+ postMixInProperties: function(/*Object*/ args, /*Object*/ frag){
+ dojo.widget.IntegerSpinner.superclass.postMixInProperties.apply(this, arguments);
+ this._spinnerPostMixInProperties(args, frag);
+ },
+
+ postCreate: function(/*Object*/ args, /*Object*/ frag){
+ dojo.widget.IntegerSpinner.superclass.postCreate.apply(this, arguments);
+ this._spinnerPostCreate(args, frag);
+ },
+
+ // sumary
+ // spin the input field
+ // direction < 0: spin down
+ // direction > 0: spin up
+ // direction = 0: revalidate existing value
+ adjustValue: function(/*Number*/ direction, /*Number*/ x){
+ var val = this.getValue().replace(/[^\-+\d]/g, "");
+ if(val.length == 0){ return; }
+
+ var num = Math.min(Math.max((parseInt(val)+(parseInt(this.delta) * direction)), (this.flags.min?this.flags.min:-Infinity)), (this.flags.max?this.flags.max:+Infinity));
+ val = num.toString();
+
+ if(num >= 0){
+ val = ((this.flags.signed == true)?'+':' ')+val; // make sure first char is a nondigit
+ }
+
+ if(this.flags.separator.length > 0){
+ for (var i=val.length-3; i > 1; i-=3){
+ val = val.substr(0,i)+this.flags.separator+val.substr(i);
+ }
+ }
+
+ if(val.substr(0,1) == ' '){ val = val.substr(1); } // remove space
+
+ this.setValue(val);
+
+ return val.length;
+ }
+});
+
+/*
+ ****** RealNumberSpinner ******
+
+ A subclass of RealNumberTextbox.
+ @attr places The exact number of decimal places. If omitted, it's unlimited and optional.
+ @attr exponent Can be true or false. If omitted the exponential part is optional.
+ @attr eSigned Is the exponent signed? Can be true or false, if omitted the sign is optional.
+*/
+dojo.widget.defineWidget(
+ "dojo.widget.RealNumberSpinner",
+ [dojo.widget.RealNumberTextbox, dojo.widget.Spinner],
+ function(){ dojo.experimental("dojo.widget.RealNumberSpinner"); },
+{
+ // new subclass properties
+ delta: "1e1",
+
+ postMixInProperties: function(/*Object*/ args, /*Object*/ frag){
+ dojo.widget.RealNumberSpinner.superclass.postMixInProperties.apply(this, arguments);
+ this._spinnerPostMixInProperties(args, frag);
+ },
+
+ postCreate: function(/*Object*/ args, /*Object*/ frag){
+ dojo.widget.RealNumberSpinner.superclass.postCreate.apply(this, arguments);
+ this._spinnerPostCreate(args, frag);
+ },
+
+ adjustValue: function(/*Number*/ direction, /*Number*/ x){
+ var val = this.getValue().replace(/[^\-+\.eE\d]/g, "");
+ if(!val.length){ return; }
+
+ var num = parseFloat(val);
+ if(isNaN(num)){ return; }
+ var delta = this.delta.split(/[eE]/);
+ if(!delta.length){
+ delta = [1, 1];
+ }else{
+ delta[0] = parseFloat(delta[0].replace(/[^\-+\.\d]/g, ""));
+ if(isNaN(delta[0])){ delta[0] = 1; }
+ if(delta.length > 1){
+ delta[1] = parseInt(delta[1]);
+ }
+ if(isNaN(delta[1])){ delta[1] = 1; }
+ }
+ val = this.getValue().split(/[eE]/);
+ if(!val.length){ return; }
+ var numBase = parseFloat(val[0].replace(/[^\-+\.\d]/g, ""));
+ if(val.length == 1){
+ var numExp = 0;
+ }else{
+ var numExp = parseInt(val[1].replace(/[^\-+\d]/g, ""));
+ }
+ if(x <= val[0].length){
+ x = 0;
+ numBase += delta[0] * direction;
+ }else{
+ x = Number.MAX_VALUE;
+ numExp += delta[1] * direction;
+ if(this.flags.eSigned == false && numExp < 0){
+ numExp = 0;
+ }
+ }
+ num = Math.min(Math.max((numBase * Math.pow(10,numExp)), (this.flags.min?this.flags.min:-Infinity)), (this.flags.max?this.flags.max:+Infinity));
+ if((this.flags.exponent == true || (this.flags.exponent != false && x != 0)) && num.toExponential){
+ if (isNaN(this.flags.places) || this.flags.places == Infinity){
+ val = num.toExponential();
+ }else{
+ val = num.toExponential(this.flags.places);
+ }
+ }else if(num.toFixed && num.toPrecision){
+ if(isNaN(this.flags.places) || this.flags.places == Infinity){
+ val = num.toPrecision((1/3).toString().length-1);
+ }else{
+ val = num.toFixed(this.flags.places);
+ }
+ }else{
+ val = num.toString();
+ }
+
+ if(num >= 0){
+ if(this.flags.signed == true){
+ val = '+' + val;
+ }
+ }
+ val = val.split(/[eE]/);
+ if(this.flags.separator.length > 0){
+ if(num >= 0 && val[0].substr(0,1) != '+'){
+ val[0] = ' ' + val[0]; // make sure first char is nondigit for easy algorithm
+ }
+ var i = val[0].lastIndexOf('.');
+ if(i >= 0){
+ i -= 3;
+ }else{
+ i = val[0].length-3;
+ }
+ for (; i > 1; i-=3){
+ val[0] = val[0].substr(0,i)+this.flags.separator+val[0].substr(i);
+ }
+ if(val[0].substr(0,1) == ' '){ val[0] = val[0].substr(1); } // remove space
+ }
+ if(val.length > 1){
+ if((this.flags.eSigned == true)&&(val[1].substr(0,1) != '+')){
+ val[1] = '+' + val[1];
+ }else if((!this.flags.eSigned)&&(val[1].substr(0,1) == '+')){
+ val[1] = val[1].substr(1);
+ }else if((!this.flags.eSigned)&&(val[1].substr(0,1) == '-')&&(num.toFixed && num.toPrecision)){
+ if(isNaN(this.flags.places)){
+ val[0] = num.toPrecision((1/3).toString().length-1);
+ }else{
+ val[0] = num.toFixed(this.flags.places).toString();
+ }
+ val[1] = "0";
+ }
+ val[0] += 'e' + val[1];
+ }
+ this.setValue(val[0]);
+ if(x > val[0].length){ x = val[0].length; }
+ return x;
+ }
+});
+
+dojo.widget.defineWidget(
+ "dojo.widget.TimeSpinner",
+ [dojo.widget.TimeTextbox, dojo.widget.Spinner],
+ function(){ dojo.experimental("dojo.widget.TimeSpinner"); },
+{
+ postMixInProperties: function(/*Object*/ args, /*Object*/ frag){
+ dojo.widget.TimeSpinner.superclass.postMixInProperties.apply(this, arguments);
+ this._spinnerPostMixInProperties(args, frag);
+ },
+
+ postCreate: function(/*Object*/ args, /*Object*/ frag){
+ dojo.widget.TimeSpinner.superclass.postCreate.apply(this, arguments);
+ this._spinnerPostCreate(args, frag);
+ },
+
+ adjustValue: function(/*Number*/ direction, /*Number*/ x){
+ //FIXME: formatting should make use of dojo.date.format?
+ var val = this.getValue();
+ var format = (this.flags.format && this.flags.format.search(/[Hhmst]/) >= 0) ? this.flags.format : "hh:mm:ss t";
+ if(direction == 0 || !val.length || !this.isValid()){ return; }
+ if (!this.flags.amSymbol){
+ this.flags.amSymbol = "AM";
+ }
+ if (!this.flags.pmSymbol){
+ this.flags.pmSymbol = "PM";
+ }
+ var re = dojo.regexp.time(this.flags);
+ var qualifiers = format.replace(/H/g,"h").replace(/[^hmst]/g,"").replace(/([hmst])\1/g,"$1");
+ var hourPos = qualifiers.indexOf('h') + 1;
+ var minPos = qualifiers.indexOf('m') + 1;
+ var secPos = qualifiers.indexOf('s') + 1;
+ var ampmPos = qualifiers.indexOf('t') + 1;
+ // tweak format to match the incoming data exactly to help find where the cursor is
+ var cursorFormat = format;
+ var ampm = "";
+ if (ampmPos > 0){
+ ampm = val.replace(new RegExp(re),"$"+ampmPos);
+ cursorFormat = cursorFormat.replace(/t+/, ampm.replace(/./g,"t"));
+ }
+ var hour = 0;
+ var deltaHour = 1;
+ if (hourPos > 0){
+ hour = val.replace(new RegExp(re),"$"+hourPos);
+ if (dojo.lang.isString(this.delta)){
+ deltaHour = this.delta.replace(new RegExp(re),"$"+hourPos);
+ }
+ if (isNaN(deltaHour)){
+ deltaHour = 1;
+ } else {
+ deltaHour = parseInt(deltaHour);
+ }
+ if (hour.length == 2){
+ cursorFormat = cursorFormat.replace(/([Hh])+/, "$1$1");
+ } else {
+ cursorFormat = cursorFormat.replace(/([Hh])+/, "$1");
+ }
+ if (isNaN(hour)){
+ hour = 0;
+ } else {
+ hour = parseInt(hour.replace(/^0(\d)/,"$1"));
+ }
+ }
+ var min = 0;
+ var deltaMin = 1;
+ if (minPos > 0){
+ min = val.replace(new RegExp(re),"$"+minPos);
+ if (dojo.lang.isString(this.delta)){
+ deltaMin = this.delta.replace(new RegExp(re),"$"+minPos);
+ }
+ if (isNaN(deltaMin)){
+ deltaMin = 1;
+ } else {
+ deltaMin = parseInt(deltaMin);
+ }
+ cursorFormat = cursorFormat.replace(/m+/, min.replace(/./g,"m"));
+ if (isNaN(min)){
+ min = 0;
+ } else {
+ min = parseInt(min.replace(/^0(\d)/,"$1"));
+ }
+ }
+ var sec = 0;
+ var deltaSec = 1;
+ if (secPos > 0){
+ sec = val.replace(new RegExp(re),"$"+secPos);
+ if (dojo.lang.isString(this.delta)){
+ deltaSec = this.delta.replace(new RegExp(re),"$"+secPos);
+ }
+ if (isNaN(deltaSec)){
+ deltaSec = 1;
+ } else {
+ deltaSec = parseInt(deltaSec);
+ }
+ cursorFormat = cursorFormat.replace(/s+/, sec.replace(/./g,"s"));
+ if (isNaN(sec)){
+ sec = 0;
+ } else {
+ sec = parseInt(sec.replace(/^0(\d)/,"$1"));
+ }
+ }
+ if (isNaN(x) || x >= cursorFormat.length){
+ x = cursorFormat.length-1;
+ }
+ var cursorToken = cursorFormat.charAt(x);
+
+ switch(cursorToken){
+ case 't':
+ if (ampm == this.flags.amSymbol){
+ ampm = this.flags.pmSymbol;
+ }
+ else if (ampm == this.flags.pmSymbol){
+ ampm = this.flags.amSymbol;
+ }
+ break;
+ default:
+ if (hour >= 1 && hour < 12 && ampm == this.flags.pmSymbol){
+ hour += 12;
+ }
+ if (hour == 12 && ampm == this.flags.amSymbol){
+ hour = 0;
+ }
+ switch(cursorToken){
+ case 's':
+ sec += deltaSec * direction;
+ while (sec < 0){
+ min--;
+ sec += 60;
+ }
+ while (sec >= 60){
+ min++;
+ sec -= 60;
+ }
+ case 'm':
+ if (cursorToken == 'm'){
+ min += deltaMin * direction;
+ }
+ while (min < 0){
+ hour--;
+ min += 60;
+ }
+ while (min >= 60){
+ hour++;
+ min -= 60;
+ }
+ case 'h':
+ case 'H':
+ if (cursorToken == 'h' || cursorToken == 'H'){
+ hour += deltaHour * direction;
+ }
+ while (hour < 0){
+ hour += 24;
+ }
+ while (hour >= 24){
+ hour -= 24;
+ }
+ break;
+ default: // should never get here
+ return;
+ }
+ if (hour >= 12){
+ ampm = this.flags.pmSymbol;
+ if (format.indexOf('h') >= 0 && hour >= 13){
+ hour -= 12;
+ }
+ } else {
+ ampm = this.flags.amSymbol;
+ if (format.indexOf('h') >= 0 && hour == 0){
+ hour = 12;
+ }
+ }
+ }
+
+ cursorFormat = format;
+ if (hour >= 0 && hour < 10 && format.search(/[hH]{2}/) >= 0){
+ hour = "0" + hour.toString();
+ }
+ if (hour >= 10 && cursorFormat.search(/[hH]{2}/) < 0 ){
+ cursorFormat = cursorFormat.replace(/(h|H)/, "$1$1");
+ }
+ if (min >= 0 && min < 10 && cursorFormat.search(/mm/) >= 0){
+ min = "0" + min.toString();
+ }
+ if (min >= 10 && cursorFormat.search(/mm/) < 0 ){
+ cursorFormat = cursorFormat.replace(/m/, "$1$1");
+ }
+ if (sec >= 0 && sec < 10 && cursorFormat.search(/ss/) >= 0){
+ sec = "0" + sec.toString();
+ }
+ if (sec >= 10 && cursorFormat.search(/ss/) < 0 ){
+ cursorFormat = cursorFormat.replace(/s/, "$1$1");
+ }
+ x = cursorFormat.indexOf(cursorToken);
+ if (x == -1){
+ x = format.length;
+ }
+ format = format.replace(/[hH]+/, hour);
+ format = format.replace(/m+/, min);
+ format = format.replace(/s+/, sec);
+ format = format.replace(/t/, ampm);
+ this.setValue(format);
+ if(x > format.length){ x = format.length; }
+ return x;
+ }
+});
Propchange: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Spinner.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SplitContainer.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SplitContainer.js?view=auto&rev=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SplitContainer.js (added)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SplitContainer.js Mon Nov 13 14:54:45 2006
@@ -0,0 +1,527 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.SplitContainer");
+
+//
+// TODO
+// make it prettier
+// active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
+//
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.ContentPane");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.html.style");
+dojo.require("dojo.html.layout");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.io.cookie");
+
+dojo.widget.defineWidget(
+ "dojo.widget.SplitContainer",
+ dojo.widget.HtmlWidget,
+ function(){
+ this.sizers = [];
+ },
+{
+ isContainer: true,
+
+ // variables
+ virtualSizer: null,
+ isHorizontal: null,
+ paneBefore: null,
+ paneAfter: null,
+ isSizing: false,
+ dragOffset: 0,
+ startPoint: 0,
+ lastPoint: 0,
+ sizingSplitter: null,
+ screenToClientOffset: 0,
+ isDraggingLeft: 0,
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/SplitContainer.css"),
+ originPos: 0,
+
+ // parameters (user settable)
+ activeSizing: false,
+ sizerWidth: 15,
+ orientation: 'horizontal',
+ persist: true, // save splitter positions in a cookie
+
+ debugName: '',
+
+ fillInTemplate: function(){
+
+ dojo.html.insertCssFile(this.templateCssPath, null, true);
+ dojo.html.addClass(this.domNode, "dojoSplitContainer");
+ // overflow has to be explicitly hidden for splitContainers using gekko (trac #1435)
+ // to keep other combined css classes from inadvertantly making the overflow visible
+ if (dojo.render.html.moz) {
+ this.domNode.style.overflow = '-moz-scrollbars-none'; // hidden doesn't work
+ }
+
+ var content = dojo.html.getContentBox(this.domNode);
+ this.paneWidth = content.width;
+ this.paneHeight = content.height;
+
+ this.isHorizontal = (this.orientation == 'horizontal');
+
+ //dojo.debug("fillInTemplate for "+this.debugName);
+ },
+
+ onResized: function(e){
+ var content = dojo.html.getContentBox(this.domNode);
+ this.paneWidth = content.width;
+ this.paneHeight = content.height;
+ this.layoutPanels();
+ },
+
+ postCreate: function(args, fragment, parentComp){
+
+ // dojo.debug("post create for "+this.debugName);
+
+ // attach the children and create the draggers
+ for(var i=0; i<this.children.length; i++){
+ with(this.children[i].domNode.style){
+ position = "absolute";
+ }
+ dojo.html.addClass(this.children[i].domNode,
+ "dojoSplitPane");
+
+ if(i == this.children.length-1){
+ break;
+ }
+
+ this._addSizer();
+ }
+
+ // create the fake dragger
+ if (typeof this.sizerWidth == "object") {
+ try {
+ this.sizerWidth = parseInt(this.sizerWidth.toString());
+ } catch(e) { this.sizerWidth = 15; }
+ }
+ this.virtualSizer = document.createElement('div');
+ this.virtualSizer.style.position = 'absolute';
+ this.virtualSizer.style.display = 'none';
+ //this.virtualSizer.style.backgroundColor = 'lime';
+ this.virtualSizer.style.zIndex = 10;
+ this.virtualSizer.className = this.isHorizontal ? 'dojoSplitContainerVirtualSizerH' : 'dojoSplitContainerVirtualSizerV';
+ this.domNode.appendChild(this.virtualSizer);
+
+ dojo.html.disableSelection(this.virtualSizer);
+
+ if(this.persist){
+ this.restoreState();
+ }
+
+ // size the panels once the browser has caught up
+ this.resizeSoon();
+ },
+
+ _injectChild: function(child) {
+ with(child.domNode.style){
+ position = "absolute";
+ }
+ dojo.html.addClass(child.domNode,
+ "dojoSplitPane");
+ },
+
+ _addSizer: function() {
+ var i = this.sizers.length;
+
+ this.sizers[i] = document.createElement('div');
+ this.sizers[i].style.position = 'absolute';
+ this.sizers[i].className = this.isHorizontal ? 'dojoSplitContainerSizerH' : 'dojoSplitContainerSizerV';
+
+ var self = this;
+ var handler = (function(){ var sizer_i = i; return function(e){ self.beginSizing(e, sizer_i); } })();
+ dojo.event.connect(this.sizers[i], "onmousedown", handler);
+
+ this.domNode.appendChild(this.sizers[i]);
+ dojo.html.disableSelection(this.sizers[i]);
+ },
+
+ removeChild: function(widget){
+ // Remove sizer, but only if widget is really our child and
+ // we have at least one sizer to throw away
+ if (this.sizers.length > 0) {
+ for(var x=0; x<this.children.length; x++){
+ if(this.children[x] === widget){
+ var i = this.sizers.length - 1;
+ this.domNode.removeChild(this.sizers[i]);
+ this.sizers.length = i;
+ break;
+ }
+ }
+ }
+
+ // Remove widget and repaint
+ dojo.widget.SplitContainer.superclass.removeChild.call(this, widget, arguments);
+ this.onResized();
+ },
+
+ addChild: function(widget, overrideContainerNode, pos, ref, insertIndex){
+ dojo.widget.SplitContainer.superclass.addChild.call(this, widget, overrideContainerNode, pos, ref, insertIndex);
+ this._injectChild(widget);
+
+ if (this.children.length > 1) {
+ this._addSizer();
+ }
+
+ this.layoutPanels();
+ },
+
+ layoutPanels: function(){
+ if (this.children.length == 0){ return; }
+
+ //
+ // calculate space
+ //
+
+ var space = this.isHorizontal ? this.paneWidth : this.paneHeight;
+
+ if (this.children.length > 1){
+
+ space -= this.sizerWidth * (this.children.length - 1);
+ }
+
+
+ //
+ // calculate total of SizeShare values
+ //
+
+ var out_of = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ out_of += this.children[i].sizeShare;
+ }
+
+
+ //
+ // work out actual pixels per sizeshare unit
+ //
+
+ var pix_per_unit = space / out_of;
+
+
+ //
+ // set the SizeActual member of each pane
+ //
+
+ var total_size = 0;
+
+ for(var i=0; i<this.children.length-1; i++){
+
+ var size = Math.round(pix_per_unit * this.children[i].sizeShare);
+ this.children[i].sizeActual = size;
+ total_size += size;
+ }
+ this.children[this.children.length-1].sizeActual = space - total_size;
+
+ //
+ // make sure the sizes are ok
+ //
+
+ this.checkSizes();
+
+
+ //
+ // now loop, positioning each pane and letting children resize themselves
+ //
+
+ var pos = 0;
+ var size = this.children[0].sizeActual;
+ this.movePanel(this.children[0].domNode, pos, size);
+ this.children[0].position = pos;
+ this.children[0].checkSize();
+ pos += size;
+
+ for(var i=1; i<this.children.length; i++){
+
+ // first we position the sizing handle before this pane
+ this.movePanel(this.sizers[i-1], pos, this.sizerWidth);
+ this.sizers[i-1].position = pos;
+ pos += this.sizerWidth;
+
+ size = this.children[i].sizeActual;
+ this.movePanel(this.children[i].domNode, pos, size);
+ this.children[i].position = pos;
+ this.children[i].checkSize();
+ pos += size;
+ }
+ },
+
+ movePanel: function(panel, pos, size){
+ if (this.isHorizontal){
+ panel.style.left = pos + 'px';
+ panel.style.top = 0;
+
+ dojo.html.setMarginBox(panel, { width: size, height: this.paneHeight });
+ }else{
+ panel.style.left = 0;
+ panel.style.top = pos + 'px';
+
+ dojo.html.setMarginBox(panel, { width: this.paneWidth, height: size });
+ }
+ },
+
+ growPane: function(growth, pane){
+
+ if (growth > 0){
+ if (pane.sizeActual > pane.sizeMin){
+ if ((pane.sizeActual - pane.sizeMin) > growth){
+
+ // stick all the growth in this pane
+ pane.sizeActual = pane.sizeActual - growth;
+ growth = 0;
+ }else{
+ // put as much growth in here as we can
+ growth -= pane.sizeActual - pane.sizeMin;
+ pane.sizeActual = pane.sizeMin;
+ }
+ }
+ }
+ return growth;
+ },
+
+ checkSizes: function(){
+
+ var total_min_size = 0;
+ var total_size = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ total_size += this.children[i].sizeActual;
+ total_min_size += this.children[i].sizeMin;
+ }
+
+ // only make adjustments if we have enough space for all the minimums
+
+ if (total_min_size <= total_size){
+
+ var growth = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ if (this.children[i].sizeActual < this.children[i].sizeMin){
+
+ growth += this.children[i].sizeMin - this.children[i].sizeActual;
+ this.children[i].sizeActual = this.children[i].sizeMin;
+ }
+ }
+
+ if (growth > 0){
+ if (this.isDraggingLeft){
+ for(var i=this.children.length-1; i>=0; i--){
+ growth = this.growPane(growth, this.children[i]);
+ }
+ }else{
+ for(var i=0; i<this.children.length; i++){
+ growth = this.growPane(growth, this.children[i]);
+ }
+ }
+ }
+ }else{
+
+ for(var i=0; i<this.children.length; i++){
+ this.children[i].sizeActual = Math.round(total_size * (this.children[i].sizeMin / total_min_size));
+ }
+ }
+ },
+
+ beginSizing: function(e, i){
+ this.paneBefore = this.children[i];
+ this.paneAfter = this.children[i+1];
+
+ this.isSizing = true;
+ this.sizingSplitter = this.sizers[i];
+ this.originPos = dojo.html.getAbsolutePosition(this.children[0].domNode, true, dojo.html.boxSizing.MARGIN_BOX);
+ if (this.isHorizontal){
+ var client = (e.layerX ? e.layerX : e.offsetX);
+ var screen = e.pageX;
+ this.originPos = this.originPos.x;
+ }else{
+ var client = (e.layerY ? e.layerY : e.offsetY);
+ var screen = e.pageY;
+ this.originPos = this.originPos.y;
+ }
+ this.startPoint = this.lastPoint = screen;
+ this.screenToClientOffset = screen - client;
+ this.dragOffset = this.lastPoint - this.paneBefore.sizeActual - this.originPos - this.paneBefore.position;
+
+ if (!this.activeSizing){
+ this.showSizingLine();
+ }
+
+ //
+ // attach mouse events
+ //
+
+ dojo.event.connect(document.documentElement, "onmousemove", this, "changeSizing");
+ dojo.event.connect(document.documentElement, "onmouseup", this, "endSizing");
+ dojo.event.browser.stopEvent(e);
+ },
+
+ changeSizing: function(e){
+ this.lastPoint = this.isHorizontal ? e.pageX : e.pageY;
+ if (this.activeSizing){
+ this.movePoint();
+ this.updateSize();
+ }else{
+ this.movePoint();
+ this.moveSizingLine();
+ }
+ dojo.event.browser.stopEvent(e);
+ },
+
+ endSizing: function(e){
+
+ if (!this.activeSizing){
+ this.hideSizingLine();
+ }
+
+ this.updateSize();
+
+ this.isSizing = false;
+
+ dojo.event.disconnect(document.documentElement, "onmousemove", this, "changeSizing");
+ dojo.event.disconnect(document.documentElement, "onmouseup", this, "endSizing");
+
+ if(this.persist){
+ this.saveState(this);
+ }
+ },
+
+ movePoint: function(){
+
+ // make sure lastPoint is a legal point to drag to
+ var p = this.lastPoint - this.screenToClientOffset;
+
+ var a = p - this.dragOffset;
+ a = this.legaliseSplitPoint(a);
+ p = a + this.dragOffset;
+
+ this.lastPoint = p + this.screenToClientOffset;
+ },
+
+ legaliseSplitPoint: function(a){
+
+ a += this.sizingSplitter.position;
+
+ this.isDraggingLeft = (a > 0) ? 1 : 0;
+
+ if (!this.activeSizing){
+
+ if (a < this.paneBefore.position + this.paneBefore.sizeMin){
+
+ a = this.paneBefore.position + this.paneBefore.sizeMin;
+ }
+
+ if (a > this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin))){
+
+ a = this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin));
+ }
+ }
+
+ a -= this.sizingSplitter.position;
+
+ this.checkSizes();
+
+ return a;
+ },
+
+ updateSize: function(){
+ var pos = this.lastPoint - this.dragOffset - this.originPos;
+
+ var start_region = this.paneBefore.position;
+ var end_region = this.paneAfter.position + this.paneAfter.sizeActual;
+
+ this.paneBefore.sizeActual = pos - start_region;
+ this.paneAfter.position = pos + this.sizerWidth;
+ this.paneAfter.sizeActual = end_region - this.paneAfter.position;
+
+ for(var i=0; i<this.children.length; i++){
+
+ this.children[i].sizeShare = this.children[i].sizeActual;
+ }
+
+ this.layoutPanels();
+ },
+
+ showSizingLine: function(){
+
+ this.moveSizingLine();
+
+ if (this.isHorizontal){
+ dojo.html.setMarginBox(this.virtualSizer, { width: this.sizerWidth, height: this.paneHeight });
+ }else{
+ dojo.html.setMarginBox(this.virtualSizer, { width: this.paneWidth, height: this.sizerWidth });
+ }
+
+ this.virtualSizer.style.display = 'block';
+ },
+
+ hideSizingLine: function(){
+ this.virtualSizer.style.display = 'none';
+ },
+
+ moveSizingLine: function(){
+ var pos = this.lastPoint - this.startPoint + this.sizingSplitter.position;
+ if (this.isHorizontal){
+ this.virtualSizer.style.left = pos + 'px';
+ }else{
+ var pos = (this.lastPoint - this.startPoint) + this.sizingSplitter.position;
+ this.virtualSizer.style.top = pos + 'px';
+ }
+
+ },
+
+ _getCookieName: function(i) {
+ return this.widgetId + "_" + i;
+ },
+
+ restoreState: function () {
+ for(var i=0; i<this.children.length; i++) {
+ var cookieName = this._getCookieName(i);
+ var cookieValue = dojo.io.cookie.getCookie(cookieName);
+ if (cookieValue != null) {
+ var pos = parseInt(cookieValue);
+ if (typeof pos == "number") {
+ this.children[i].sizeShare=pos;
+ }
+ }
+ }
+ },
+
+ saveState: function (){
+ for(var i=0; i<this.children.length; i++) {
+ var cookieName = this._getCookieName(i);
+ dojo.io.cookie.setCookie(cookieName, this.children[i].sizeShare, null, null, null, null);
+ }
+ }
+});
+
+// These arguments can be specified for the children of a SplitContainer.
+// Since any widget can be specified as a SplitContainer child, mix them
+// into the base widget class. (This is a hack, but it's effective.)
+dojo.lang.extend(dojo.widget.Widget, {
+ sizeMin: 10,
+ sizeShare: 10
+});
+
+// Deprecated class for split pane children.
+// Actually any widget can be the child of a split pane
+dojo.widget.defineWidget(
+ "dojo.widget.SplitContainerPanel",
+ dojo.widget.ContentPane,
+ {}
+);
+
Propchange: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SplitContainer.js
------------------------------------------------------------------------------
svn:eol-style = native
Modified: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgButton.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgButton.js?view=diff&rev=474551&r1=474550&r2=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgButton.js (original)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgButton.js Mon Nov 13 14:54:45 2006
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004-2005, The Dojo Foundation
+ Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
@@ -54,7 +54,7 @@
//textNode.appendChild(labelNode);
//this.domNode.appendChild(textNode);
return textString;
- alert(textNode.getComputedTextLength());
+ //alert(textNode.getComputedTextLength());
}
this.fillInTemplate = function(x, y, textSize, label, shape){
@@ -136,8 +136,6 @@
return textString;
}
-//dojo.widget.SVGButton.prototype.templateString = "<g class='dojoButton' dojoAttachEvent='onClick; onMouseMove: onFoo;' dojoAttachPoint='labelNode'>"+ dojo.webui.widgets.SVGButton.prototype.shapeString("ellipse") + "</g>";
-
dojo.widget.SvgButton.prototype.templateString = function(x, y, textSize, label, shape) {
- return "<g class='dojoButton' dojoAttachEvent='onClick; onMouseMove: onFoo;' dojoAttachPoint='labelNode'>"+ dojo.webui.widgets.SVGButton.prototype.shapeString(x, y, textSize, label, shape) + dojo.widget.SVGButton.prototype.labelString(x, y, textSize, label, shape) + "</g>";
+ return "<g class='dojoButton' dojoAttachEvent='onClick; onMouseMove: onFoo;' dojoAttachPoint='labelNode'>"+ dojo.widgets.SVGButton.prototype.shapeString(x, y, textSize, label, shape) + dojo.widget.SVGButton.prototype.labelString(x, y, textSize, label, shape) + "</g>";
}
Modified: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgWidget.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgWidget.js?view=diff&rev=474551&r1=474550&r2=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgWidget.js (original)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgWidget.js Mon Nov 13 14:54:45 2006
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004-2005, The Dojo Foundation
+ Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
@@ -15,26 +15,23 @@
dojo.require("dojo.dom");
// SVGWidget is a mixin ONLY
-dojo.widget.SvgWidget = function(args){
- // mix in the parent type
- // dojo.widget.DomWidget.call(this);
-}
-dojo.inherits(dojo.widget.SvgWidget, dojo.widget.DomWidget);
-
-dojo.lang.extend(dojo.widget.SvgWidget, {
+dojo.widget.declare(
+ "dojo.widget.SvgWidget",
+ dojo.widget.DomWidget,
+{
getContainerHeight: function(){
// NOTE: container height must be returned as the INNER height
- dj_unimplemented("dojo.widget.SvgWidget.getContainerHeight");
+ dojo.unimplemented("dojo.widget.SvgWidget.getContainerHeight");
},
getContainerWidth: function(){
// return this.parent.domNode.offsetWidth;
- dj_unimplemented("dojo.widget.SvgWidget.getContainerWidth");
+ dojo.unimplemented("dojo.widget.SvgWidget.getContainerWidth");
},
setNativeHeight: function(height){
// var ch = this.getContainerHeight();
- dj_unimplemented("dojo.widget.SVGWidget.setNativeHeight");
+ dojo.unimplemented("dojo.widget.SVGWidget.setNativeHeight");
},
createNodesFromText: function(txt, wrap){
Added: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SwtWidget.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SwtWidget.js?view=auto&rev=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SwtWidget.js (added)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SwtWidget.js Mon Nov 13 14:54:45 2006
@@ -0,0 +1,64 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.SwtWidget");
+
+dojo.require("dojo.event.*");
+dojo.require("dojo.widget.Widget");
+dojo.require("dojo.uri.*");
+dojo.require("dojo.lang.func");
+dojo.require("dojo.lang.extras");
+
+try{
+ importPackage(Packages.org.eclipse.swt.widgets);
+
+ dojo.declare("dojo.widget.SwtWidget", dojo.widget.Widget,
+ function() {
+ if((arguments.length>0)&&(typeof arguments[0] == "object")){
+ this.create(arguments[0]);
+ }
+ },
+ {
+ display: null,
+ shell: null,
+
+ show: function(){ },
+ hide: function(){ },
+
+ addChild: function(){ },
+ registerChild: function(){ },
+ addWidgetAsDirectChild: function(){ },
+ removeChild: function(){ },
+ cleanUp: function(){ },
+ destroyRendering: function(){ },
+ postInitialize: function(){ },
+ });
+
+ // initialize SWT runtime
+
+ dojo.widget.SwtWidget.prototype.display = new Display();
+ dojo.widget.SwtWidget.prototype.shell = new Shell(dojo.widget.SwtWidget.prototype.display);
+
+ dojo.widget.manager.startShell = function(){
+ var sh = dojo.widget.SwtWidget.prototype.shell;
+ var d = dojo.widget.SwtWidget.prototype.display;
+ sh.open();
+ while(!sh.isDisposed()){
+ dojo.widget.manager.doNext();
+ if(!d.readAndDispatch()){
+ d.sleep();
+ }
+ }
+ d.dispose();
+ };
+}catch(e){
+ // seems we didn't have the SWT classes in the environment. Log it.
+ dojo.debug("dojo.widget.SwtWidget not loaded. SWT classes not available");
+}
Propchange: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SwtWidget.js
------------------------------------------------------------------------------
svn:eol-style = native
Added: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TabContainer.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TabContainer.js?view=auto&rev=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TabContainer.js (added)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TabContainer.js Mon Nov 13 14:54:45 2006
@@ -0,0 +1,215 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.TabContainer");
+
+dojo.require("dojo.lang.func");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.PageContainer");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.selection");
+dojo.require("dojo.widget.html.layout");
+
+// 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.
+dojo.widget.defineWidget("dojo.widget.TabContainer", dojo.widget.PageContainer, {
+
+ // String
+ // Defines where tab labels go relative to tab content.
+ // "top", "bottom", "left-h", "right-h"
+ labelPosition: "top",
+
+ // 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.dojoUri("src/widget/templates/TabContainer.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/TabContainer.css"),
+
+ // 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);
+ }
+});
+
+// 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.
+dojo.widget.defineWidget(
+ "dojo.widget.TabController",
+ dojo.widget.PageController,
+ {
+ templateString: "<div wairole='tablist' dojoAttachEvent='onKey'></div>",
+
+ // String
+ // Defines where tab labels go relative to tab content.
+ // "top", "bottom", "left-h", "right-h"
+ labelPosition: "top",
+
+ doLayout: true,
+
+ // String
+ // Class name to apply to the top dom node
+ "class": "",
+
+ // 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);
+ }
+ }
+);
+
+// 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.
+dojo.widget.defineWidget("dojo.widget.TabButton", dojo.widget.PageButton,
+{
+ 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);
+ }
+});
+
+
+// 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.
+dojo.widget.defineWidget(
+ "dojo.widget.a11y.TabButton",
+ dojo.widget.TabButton,
+ {
+ imgPath: dojo.uri.dojoUri("src/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>"
+ }
+);
+
+
Propchange: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TabContainer.js
------------------------------------------------------------------------------
svn:eol-style = native
Modified: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TaskBar.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TaskBar.js?view=diff&rev=474551&r1=474550&r2=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TaskBar.js (original)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TaskBar.js Mon Nov 13 14:54:45 2006
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004-2005, The Dojo Foundation
+ Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
@@ -8,25 +8,86 @@
http://dojotoolkit.org/community/licensing.shtml
*/
-dojo.provide("dojo.widget.TaskBar");
-dojo.provide("dojo.widget.TaskBarItem");
-dojo.require("dojo.widget.Widget");
-
-dojo.widget.TaskBar = function(){
- dojo.widget.Widget.call(this);
-
- this.widgetType = "TaskBar";
- this.isContainer = true;
-}
-dojo.inherits(dojo.widget.TaskBar, dojo.widget.Widget);
-dojo.widget.tags.addParseTreeHandler("dojo:taskbar");
-
-dojo.widget.TaskBarItem = function(){
- dojo.widget.Widget.call(this);
-
- this.widgetType = "TaskBarItem";
-}
-dojo.inherits(dojo.widget.TaskBarItem, dojo.widget.Widget);
-dojo.widget.tags.addParseTreeHandler("dojo:taskbaritem");
-
-dojo.requireAfterIf("html", "dojo.widget.html.TaskBar");
+dojo.provide("dojo.widget.TaskBar");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.FloatingPane");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.event.*");
+dojo.require("dojo.html.selection");
+
+// summary
+// Widget used internally by the TaskBar;
+// shows an icon associated w/a floating pane
+dojo.widget.defineWidget(
+ "dojo.widget.TaskBarItem",
+ dojo.widget.HtmlWidget,
+{
+ // String
+ // path of icon for associated floating pane
+ iconSrc: '',
+
+ // String
+ // name of associated floating pane
+ caption: 'Untitled',
+
+ // String
+ // widget id of associated floating pane
+ widgetId: "",
+
+ templatePath: dojo.uri.dojoUri("src/widget/templates/TaskBarItemTemplate.html"),
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/TaskBar.css"),
+
+ fillInTemplate: function() {
+ if (this.iconSrc) {
+ var img = document.createElement("img");
+ img.src = this.iconSrc;
+ this.domNode.appendChild(img);
+ }
+ this.domNode.appendChild(document.createTextNode(this.caption));
+ dojo.html.disableSelection(this.domNode);
+ },
+
+ postCreate: function() {
+ this.window=dojo.widget.getWidgetById(this.windowId);
+ this.window.explodeSrc = this.domNode;
+ dojo.event.connect(this.window, "destroy", this, "destroy")
+ },
+
+ onClick: function() {
+ this.window.toggleDisplay();
+ }
+});
+
+// summary:
+// Displays an icon for each associated floating pane, like Windows task bar
+dojo.widget.defineWidget(
+ "dojo.widget.TaskBar",
+ dojo.widget.FloatingPane,
+ function(){
+ this._addChildStack = [];
+ },
+{
+ // TODO: this class extends floating pane merely to get the shadow;
+ // it should extend HtmlWidget and then just call the shadow code directly
+ resizable: false,
+ titleBarDisplay: "none",
+
+ addChild: function(/*Widget*/ child) {
+ // summary: add taskbar item for specified FloatingPane
+ // TODO: this should not be called addChild(), as that has another meaning.
+ if(!this.containerNode){
+ this._addChildStack.push(child);
+ }else if(this._addChildStack.length > 0){
+ var oarr = this._addChildStack;
+ this._addChildStack = [];
+ dojo.lang.forEach(oarr, this.addChild, this);
+ }
+ var tbi = dojo.widget.createWidget("TaskBarItem",
+ { windowId: child.widgetId,
+ caption: child.title,
+ iconSrc: child.iconSrc
+ });
+ dojo.widget.TaskBar.superclass.addChild.call(this,tbi);
+ }
+});
Added: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Textbox.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Textbox.js?view=auto&rev=474551
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Textbox.js (added)
+++ struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Textbox.js Mon Nov 13 14:54:45 2006
@@ -0,0 +1,94 @@
+/*
+ Copyright (c) 2004-2006, The Dojo Foundation
+ All Rights Reserved.
+
+ Licensed under the Academic Free License version 2.1 or above OR the
+ modified BSD license. For more information on Dojo licensing, see:
+
+ http://dojotoolkit.org/community/licensing.shtml
+*/
+
+dojo.provide("dojo.widget.Textbox");
+
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.HtmlWidget");
+dojo.require("dojo.widget.Manager");
+dojo.require("dojo.widget.Parse");
+dojo.require("dojo.xml.Parse");
+dojo.require("dojo.lang.array");
+dojo.require("dojo.lang.common");
+
+dojo.require("dojo.i18n.common");
+dojo.requireLocalization("dojo.widget", "validate");
+
+/*
+ ****** Textbox ******
+
+ This widget is a generic textbox field.
+ Serves as a base class to derive more specialized functionality in subclasses.
+ Has the following properties that can be specified as attributes in the markup.
+
+ @attr id The textbox id attribute.
+ @attr className The textbox class attribute.
+ @attr name The textbox name attribute.
+ @attr value The textbox value attribute.
+ @attr trim Removes leading and trailing whitespace if true. Default is false.
+ @attr uppercase Converts all characters to uppercase if true. Default is false.
+ @attr lowercase Converts all characters to lowercase if true. Default is false.
+ @attr ucFirst Converts the first character of each word to uppercase if true.
+ @attr lowercase Removes all characters that are not digits if true. Default is false.
+*/
+dojo.widget.defineWidget(
+ "dojo.widget.Textbox",
+ dojo.widget.HtmlWidget,
+ {
+ // default values for new subclass properties
+ className: "",
+ name: "",
+ value: "",
+ type: "",
+ trim: false,
+ uppercase: false,
+ lowercase: false,
+ ucFirst: false,
+ digit: false,
+ htmlfloat: "none",
+
+ templatePath: dojo.uri.dojoUri("src/widget/templates/Textbox.html"),
+
+ // our DOM nodes
+ textbox: null,
+
+ // Apply various filters to textbox value
+ filter: function() {
+ if (this.trim) {
+ this.textbox.value = this.textbox.value.replace(/(^\s*|\s*$)/g, "");
+ }
+ if (this.uppercase) {
+ this.textbox.value = this.textbox.value.toUpperCase();
+ }
+ if (this.lowercase) {
+ this.textbox.value = this.textbox.value.toLowerCase();
+ }
+ if (this.ucFirst) {
+ this.textbox.value = this.textbox.value.replace(/\b\w+\b/g,
+ function(word) { return word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase(); });
+ }
+ if (this.digit) {
+ this.textbox.value = this.textbox.value.replace(/\D/g, "");
+ }
+ },
+
+ // event handlers, you can over-ride these in your own subclasses
+ onfocus: function() {},
+ onblur: function() { this.filter(); },
+
+ // All functions below are called by create from dojo.widget.Widget
+ mixInProperties: function(localProperties, frag) {
+ dojo.widget.Textbox.superclass.mixInProperties.apply(this, arguments);
+ if ( localProperties["class"] ) {
+ this.className = localProperties["class"];
+ }
+ }
+ }
+);
Propchange: struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Textbox.js
------------------------------------------------------------------------------
svn:eol-style = native