diff options
Diffstat (limited to 'js/dojo-1.7.2/dojox/grid')
239 files changed, 45108 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/grid/DataGrid.js b/js/dojo-1.7.2/dojox/grid/DataGrid.js new file mode 100644 index 0000000..560e12a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/DataGrid.js @@ -0,0 +1,15 @@ +/* + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +/* + This is an optimized version of Dojo, built for deployment and not for + development. To get sources and documentation, please visit: + + http://dojotoolkit.org +*/ + +//>>built +require({cache:{"dojo/uacss":function(){define(["./dom-geometry","./_base/lang","./ready","./_base/sniff","./_base/window"],function(_1,_2,_3,_4,_5){var _6=_5.doc.documentElement,ie=_4("ie"),_7=_4("opera"),_8=Math.floor,ff=_4("ff"),_9=_1.boxModel.replace(/-/,""),_a={"dj_ie":ie,"dj_ie6":_8(ie)==6,"dj_ie7":_8(ie)==7,"dj_ie8":_8(ie)==8,"dj_ie9":_8(ie)==9,"dj_quirks":_4("quirks"),"dj_iequirks":ie&&_4("quirks"),"dj_opera":_7,"dj_khtml":_4("khtml"),"dj_webkit":_4("webkit"),"dj_safari":_4("safari"),"dj_chrome":_4("chrome"),"dj_gecko":_4("mozilla"),"dj_ff3":_8(ff)==3};_a["dj_"+_9]=true;var _b="";for(var _c in _a){if(_a[_c]){_b+=_c+" ";}}_6.className=_2.trim(_6.className+" "+_b);_3(90,function(){if(!_1.isBodyLtr()){var _d="dj_rtl dijitRtl "+_b.replace(/ /g,"-rtl ");_6.className=_2.trim(_6.className+" "+_d+"dj_rtl dijitRtl "+_b.replace(/ /g,"-rtl "));}});return _4;});},"dijit/hccss":function(){define("dijit/hccss",["require","dojo/_base/config","dojo/dom-class","dojo/dom-construct","dojo/dom-style","dojo/ready","dojo/_base/sniff","dojo/_base/window"],function(_e,_f,_10,_11,_12,_13,has,win){if(has("ie")||has("mozilla")){_13(90,function(){var div=_11.create("div",{id:"a11yTestNode",style:{cssText:"border: 1px solid;"+"border-color:red green;"+"position: absolute;"+"height: 5px;"+"top: -999px;"+"background-image: url(\""+(_f.blankGif||_e.toUrl("dojo/resources/blank.gif"))+"\");"}},win.body());var cs=_12.getComputedStyle(div);if(cs){var _14=cs.backgroundImage;var _15=(cs.borderTopColor==cs.borderRightColor)||(_14!=null&&(_14=="none"||_14=="url(invalid-url:)"));if(_15){_10.add(win.body(),"dijit_a11y");}if(has("ie")){div.outerHTML="";}else{win.body().removeChild(div);}}});}});},"dojox/grid/_View":function(){require({cache:{"url:dojox/grid/resources/View.html":"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n"}});define("dojox/grid/_View",["dojo","dijit/registry","../main","dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/_base/connect","dojo/_base/sniff","dojo/query","dojo/_base/window","dojo/text!./resources/View.html","dojo/dnd/Source","dijit/_Widget","dijit/_TemplatedMixin","dojox/html/metrics","./util","dojo/_base/html","./_Builder","dojo/dnd/Avatar","dojo/dnd/Manager"],function(_16,_17,_18,_19,_1a,_1b,_1c,has,_1d,win,_1e,_1f,_20,_21,_22,_23,_24,_25,_26){var _27=function(_28,_29){return _28.style.cssText==undefined?_28.getAttribute("style"):_28.style.cssText;};var _2a=_19("dojox.grid._View",[_20,_21],{defaultWidth:"18em",viewWidth:"",templateString:_1e,themeable:false,classTag:"dojoxGrid",marginBottom:0,rowPad:2,_togglingColumn:-1,_headerBuilderClass:_25._HeaderBuilder,_contentBuilderClass:_25._ContentBuilder,postMixInProperties:function(){this.rowNodes={};},postCreate:function(){this.connect(this.scrollboxNode,"onscroll","doscroll");_23.funnelEvents(this.contentNode,this,"doContentEvent",["mouseover","mouseout","click","dblclick","contextmenu","mousedown"]);_23.funnelEvents(this.headerNode,this,"doHeaderEvent",["dblclick","mouseover","mouseout","mousemove","mousedown","click","contextmenu"]);this.content=new this._contentBuilderClass(this);this.header=new this._headerBuilderClass(this);if(!this.grid.isLeftToRight()){this.headerNodeContainer.style.width="";}},destroy:function(){_24.destroy(this.headerNode);delete this.headerNode;for(var i in this.rowNodes){this._cleanupRowWidgets(this.rowNodes[i]);_24.destroy(this.rowNodes[i]);}this.rowNodes={};if(this.source){this.source.destroy();}this.inherited(arguments);},focus:function(){if(has("ie")||has("webkit")||has("opera")){this.hiddenFocusNode.focus();}else{this.scrollboxNode.focus();}},setStructure:function(_2b){var vs=(this.structure=_2b);if(vs.width&&!isNaN(vs.width)){this.viewWidth=vs.width+"em";}else{this.viewWidth=vs.width||(vs.noscroll?"auto":this.viewWidth);}this._onBeforeRow=vs.onBeforeRow||function(){};this._onAfterRow=vs.onAfterRow||function(){};this.noscroll=vs.noscroll;if(this.noscroll){this.scrollboxNode.style.overflow="hidden";}this.simpleStructure=Boolean(vs.cells.length==1);this.testFlexCells();this.updateStructure();},_cleanupRowWidgets:function(_2c){if(_2c){_1a.forEach(_1d("[widgetId]",_2c).map(_17.byNode),function(w){if(w._destroyOnRemove){w.destroy();delete w;}else{if(w.domNode&&w.domNode.parentNode){w.domNode.parentNode.removeChild(w.domNode);}}});}},onBeforeRow:function(_2d,_2e){this._onBeforeRow(_2d,_2e);if(_2d>=0){this._cleanupRowWidgets(this.getRowNode(_2d));}},onAfterRow:function(_2f,_30,_31){this._onAfterRow(_2f,_30,_31);var g=this.grid;_1a.forEach(_1d(".dojoxGridStubNode",_31),function(n){if(n&&n.parentNode){var lw=n.getAttribute("linkWidget");var _32=window.parseInt(_24.attr(n,"cellIdx"),10);var _33=g.getCell(_32);var w=_17.byId(lw);if(w){n.parentNode.replaceChild(w.domNode,n);if(!w._started){w.startup();}_16.destroy(n);}else{n.innerHTML="";}}},this);},testFlexCells:function(){this.flexCells=false;for(var j=0,row;(row=this.structure.cells[j]);j++){for(var i=0,_34;(_34=row[i]);i++){_34.view=this;this.flexCells=this.flexCells||_34.isFlex();}}return this.flexCells;},updateStructure:function(){this.header.update();this.content.update();},getScrollbarWidth:function(){var _35=this.hasVScrollbar();var _36=_24.style(this.scrollboxNode,"overflow");if(this.noscroll||!_36||_36=="hidden"){_35=false;}else{if(_36=="scroll"){_35=true;}}return (_35?_22.getScrollbar().w:0);},getColumnsWidth:function(){var h=this.headerContentNode;return h&&h.firstChild?h.firstChild.offsetWidth:0;},setColumnsWidth:function(_37){this.headerContentNode.firstChild.style.width=_37+"px";if(this.viewWidth){this.viewWidth=_37+"px";}},getWidth:function(){return this.viewWidth||(this.getColumnsWidth()+this.getScrollbarWidth())+"px";},getContentWidth:function(){return Math.max(0,_24._getContentBox(this.domNode).w-this.getScrollbarWidth())+"px";},render:function(){this.scrollboxNode.style.height="";this.renderHeader();if(this._togglingColumn>=0){this.setColumnsWidth(this.getColumnsWidth()-this._togglingColumn);this._togglingColumn=-1;}var _38=this.grid.layout.cells;var _39=_1b.hitch(this,function(_3a,_3b){!this.grid.isLeftToRight()&&(_3b=!_3b);var inc=_3b?-1:1;var idx=this.header.getCellNodeIndex(_3a)+inc;var _3c=_38[idx];while(_3c&&_3c.getHeaderNode()&&_3c.getHeaderNode().style.display=="none"){idx+=inc;_3c=_38[idx];}if(_3c){return _3c.getHeaderNode();}return null;});if(this.grid.columnReordering&&this.simpleStructure){if(this.source){this.source.destroy();}var _3d="dojoxGrid_bottomMarker";var _3e="dojoxGrid_topMarker";if(this.bottomMarker){_24.destroy(this.bottomMarker);}this.bottomMarker=_24.byId(_3d);if(this.topMarker){_24.destroy(this.topMarker);}this.topMarker=_24.byId(_3e);if(!this.bottomMarker){this.bottomMarker=_24.create("div",{"id":_3d,"class":"dojoxGridColPlaceBottom"},win.body());this._hide(this.bottomMarker);this.topMarker=_24.create("div",{"id":_3e,"class":"dojoxGridColPlaceTop"},win.body());this._hide(this.topMarker);}this.arrowDim=_24.contentBox(this.bottomMarker);var _3f=_24.contentBox(this.headerContentNode.firstChild.rows[0]).h;this.source=new _1f(this.headerContentNode.firstChild.rows[0],{horizontal:true,accept:["gridColumn_"+this.grid.id],viewIndex:this.index,generateText:false,onMouseDown:_1b.hitch(this,function(e){this.header.decorateEvent(e);if((this.header.overRightResizeArea(e)||this.header.overLeftResizeArea(e))&&this.header.canResize(e)&&!this.header.moveable){this.header.beginColumnResize(e);}else{if(this.grid.headerMenu){this.grid.headerMenu.onCancel(true);}if(e.button===(has("ie")<9?1:0)){_1f.prototype.onMouseDown.call(this.source,e);}}}),onMouseOver:_1b.hitch(this,function(e){var src=this.source;if(src._getChildByEvent(e)){_1f.prototype.onMouseOver.apply(src,arguments);}}),_markTargetAnchor:_1b.hitch(this,function(_40){var src=this.source;if(src.current==src.targetAnchor&&src.before==_40){return;}if(src.targetAnchor&&_39(src.targetAnchor,src.before)){src._removeItemClass(_39(src.targetAnchor,src.before),src.before?"After":"Before");}_1f.prototype._markTargetAnchor.call(src,_40);var _41=_40?src.targetAnchor:_39(src.targetAnchor,src.before);var _42=0;if(!_41){_41=src.targetAnchor;_42=_24.contentBox(_41).w+this.arrowDim.w/2+2;}var pos=_24.position(_41,true);var _43=Math.floor(pos.x-this.arrowDim.w/2+_42);_24.style(this.bottomMarker,"visibility","visible");_24.style(this.topMarker,"visibility","visible");_24.style(this.bottomMarker,{"left":_43+"px","top":(_3f+pos.y)+"px"});_24.style(this.topMarker,{"left":_43+"px","top":(pos.y-this.arrowDim.h)+"px"});if(src.targetAnchor&&_39(src.targetAnchor,src.before)){src._addItemClass(_39(src.targetAnchor,src.before),src.before?"After":"Before");}}),_unmarkTargetAnchor:_1b.hitch(this,function(){var src=this.source;if(!src.targetAnchor){return;}if(src.targetAnchor&&_39(src.targetAnchor,src.before)){src._removeItemClass(_39(src.targetAnchor,src.before),src.before?"After":"Before");}this._hide(this.bottomMarker);this._hide(this.topMarker);_1f.prototype._unmarkTargetAnchor.call(src);}),destroy:_1b.hitch(this,function(){_1c.disconnect(this._source_conn);_1c.unsubscribe(this._source_sub);_1f.prototype.destroy.call(this.source);if(this.bottomMarker){_24.destroy(this.bottomMarker);delete this.bottomMarker;}if(this.topMarker){_24.destroy(this.topMarker);delete this.topMarker;}}),onDndCancel:_1b.hitch(this,function(){_1f.prototype.onDndCancel.call(this.source);this._hide(this.bottomMarker);this._hide(this.topMarker);})});this._source_conn=_1c.connect(this.source,"onDndDrop",this,"_onDndDrop");this._source_sub=_1c.subscribe("/dnd/drop/before",this,"_onDndDropBefore");this.source.startup();}},_hide:function(_44){_24.style(_44,{top:"-10000px","visibility":"hidden"});},_onDndDropBefore:function(_45,_46,_47){if(_16.dnd.manager().target!==this.source){return;}this.source._targetNode=this.source.targetAnchor;this.source._beforeTarget=this.source.before;var _48=this.grid.views.views;var _49=_48[_45.viewIndex];var _4a=_48[this.index];if(_4a!=_49){_49.convertColPctToFixed();_4a.convertColPctToFixed();}},_onDndDrop:function(_4b,_4c,_4d){if(_16.dnd.manager().target!==this.source){if(_16.dnd.manager().source===this.source){this._removingColumn=true;}return;}this._hide(this.bottomMarker);this._hide(this.topMarker);var _4e=function(n){return n?_24.attr(n,"idx"):null;};var w=_24.marginBox(_4c[0]).w;if(_4b.viewIndex!==this.index){var _4f=this.grid.views.views;var _50=_4f[_4b.viewIndex];var _51=_4f[this.index];if(_50.viewWidth&&_50.viewWidth!="auto"){_50.setColumnsWidth(_50.getColumnsWidth()-w);}if(_51.viewWidth&&_51.viewWidth!="auto"){_51.setColumnsWidth(_51.getColumnsWidth());}}var stn=this.source._targetNode;var stb=this.source._beforeTarget;!this.grid.isLeftToRight()&&(stb=!stb);var _52=this.grid.layout;var idx=this.index;delete this.source._targetNode;delete this.source._beforeTarget;_52.moveColumn(_4b.viewIndex,idx,_4e(_4c[0]),_4e(stn),stb);},renderHeader:function(){this.headerContentNode.innerHTML=this.header.generateHtml(this._getHeaderContent);if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}_23.fire(this,"onAfterRow",[-1,this.structure.cells,this.headerContentNode]);},_getHeaderContent:function(_53){var n=_53.name||_53.grid.getCellName(_53);if(/^\s+$/.test(n)){n=" ";}var ret=["<div class=\"dojoxGridSortNode"];if(_53.index!=_53.grid.getSortIndex()){ret.push("\">");}else{ret=ret.concat([" ",_53.grid.sortInfo>0?"dojoxGridSortUp":"dojoxGridSortDown","\"><div class=\"dojoxGridArrowButtonChar\">",_53.grid.sortInfo>0?"▲":"▼","</div><div class=\"dojoxGridArrowButtonNode\" role=\"presentation\"></div>","<div class=\"dojoxGridColCaption\">"]);}ret=ret.concat([n,"</div></div>"]);return ret.join("");},resize:function(){this.adaptHeight();this.adaptWidth();},hasHScrollbar:function(_54){var _55=this._hasHScroll||false;if(this._hasHScroll==undefined||_54){if(this.noscroll){this._hasHScroll=false;}else{var _56=_24.style(this.scrollboxNode,"overflow");if(_56=="hidden"){this._hasHScroll=false;}else{if(_56=="scroll"){this._hasHScroll=true;}else{this._hasHScroll=(this.scrollboxNode.offsetWidth-this.getScrollbarWidth()<this.contentNode.offsetWidth);}}}}if(_55!==this._hasHScroll){this.grid.update();}return this._hasHScroll;},hasVScrollbar:function(_57){var _58=this._hasVScroll||false;if(this._hasVScroll==undefined||_57){if(this.noscroll){this._hasVScroll=false;}else{var _59=_24.style(this.scrollboxNode,"overflow");if(_59=="hidden"){this._hasVScroll=false;}else{if(_59=="scroll"){this._hasVScroll=true;}else{this._hasVScroll=(this.scrollboxNode.scrollHeight>this.scrollboxNode.clientHeight);}}}}if(_58!==this._hasVScroll){this.grid.update();}return this._hasVScroll;},convertColPctToFixed:function(){var _5a=false;this.grid.initialWidth="";var _5b=_1d("th",this.headerContentNode);var _5c=_1a.map(_5b,function(c,_5d){var w=c.style.width;_24.attr(c,"vIdx",_5d);if(w&&w.slice(-1)=="%"){_5a=true;}else{if(w&&w.slice(-2)=="px"){return window.parseInt(w,10);}}return _24.contentBox(c).w;});if(_5a){_1a.forEach(this.grid.layout.cells,function(_5e,idx){if(_5e.view==this){var _5f=_5e.view.getHeaderCellNode(_5e.index);if(_5f&&_24.hasAttr(_5f,"vIdx")){var _60=window.parseInt(_24.attr(_5f,"vIdx"));this.setColWidth(idx,_5c[_60]);_24.removeAttr(_5f,"vIdx");}}},this);return true;}return false;},adaptHeight:function(_61){if(!this.grid._autoHeight){var h=(this.domNode.style.height&&parseInt(this.domNode.style.height.replace(/px/,""),10))||this.domNode.clientHeight;var _62=this;var _63=function(){var v;for(var i in _62.grid.views.views){v=_62.grid.views.views[i];if(v!==_62&&v.hasHScrollbar()){return true;}}return false;};if(_61||(this.noscroll&&_63())){h-=_22.getScrollbar().h;}_23.setStyleHeightPx(this.scrollboxNode,h);}this.hasVScrollbar(true);},adaptWidth:function(){if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}var w=this.scrollboxNode.offsetWidth-this.getScrollbarWidth();if(!this._removingColumn){w=Math.max(w,this.getColumnsWidth())+"px";}else{w=Math.min(w,this.getColumnsWidth())+"px";this._removingColumn=false;}var cn=this.contentNode;cn.style.width=w;this.hasHScrollbar(true);},setSize:function(w,h){var ds=this.domNode.style;var hs=this.headerNode.style;if(w){ds.width=w;hs.width=w;}ds.height=(h>=0?h+"px":"");},renderRow:function(_64){var _65=this.createRowNode(_64);this.buildRow(_64,_65);return _65;},createRowNode:function(_66){var _67=document.createElement("div");_67.className=this.classTag+"Row";if(this instanceof _18.grid._RowSelector){_24.attr(_67,"role","presentation");}else{_24.attr(_67,"role","row");if(this.grid.selectionMode!="none"){_67.setAttribute("aria-selected","false");}}_67[_23.gridViewTag]=this.id;_67[_23.rowIndexTag]=_66;this.rowNodes[_66]=_67;return _67;},buildRow:function(_68,_69){this.buildRowContent(_68,_69);this.styleRow(_68,_69);},buildRowContent:function(_6a,_6b){_6b.innerHTML=this.content.generateHtml(_6a,_6a);if(this.flexCells&&this.contentWidth){_6b.firstChild.style.width=this.contentWidth;}_23.fire(this,"onAfterRow",[_6a,this.structure.cells,_6b]);},rowRemoved:function(_6c){if(_6c>=0){this._cleanupRowWidgets(this.getRowNode(_6c));}this.grid.edit.save(this,_6c);delete this.rowNodes[_6c];},getRowNode:function(_6d){return this.rowNodes[_6d];},getCellNode:function(_6e,_6f){var row=this.getRowNode(_6e);if(row){return this.content.getCellNode(row,_6f);}},getHeaderCellNode:function(_70){if(this.headerContentNode){return this.header.getCellNode(this.headerContentNode,_70);}},styleRow:function(_71,_72){_72._style=_27(_72);this.styleRowNode(_71,_72);},styleRowNode:function(_73,_74){if(_74){this.doStyleRowNode(_73,_74);}},doStyleRowNode:function(_75,_76){this.grid.styleRowNode(_75,_76);},updateRow:function(_77){var _78=this.getRowNode(_77);if(_78){_78.style.height="";this.buildRow(_77,_78);}return _78;},updateRowStyles:function(_79){this.styleRowNode(_79,this.getRowNode(_79));},lastTop:0,firstScroll:0,doscroll:function(_7a){var _7b=this.grid.isLeftToRight();if(this.firstScroll<2){if((!_7b&&this.firstScroll==1)||(_7b&&this.firstScroll===0)){var s=_24.marginBox(this.headerNodeContainer);if(has("ie")){this.headerNodeContainer.style.width=s.w+this.getScrollbarWidth()+"px";}else{if(has("mozilla")){this.headerNodeContainer.style.width=s.w-this.getScrollbarWidth()+"px";this.scrollboxNode.scrollLeft=_7b?this.scrollboxNode.clientWidth-this.scrollboxNode.scrollWidth:this.scrollboxNode.scrollWidth-this.scrollboxNode.clientWidth;}}}this.firstScroll++;}this.headerNode.scrollLeft=this.scrollboxNode.scrollLeft;var top=this.scrollboxNode.scrollTop;if(top!==this.lastTop){this.grid.scrollTo(top);}},setScrollTop:function(_7c){this.lastTop=_7c;this.scrollboxNode.scrollTop=_7c;return this.scrollboxNode.scrollTop;},doContentEvent:function(e){if(this.content.decorateEvent(e)){this.grid.onContentEvent(e);}},doHeaderEvent:function(e){if(this.header.decorateEvent(e)){this.grid.onHeaderEvent(e);}},dispatchContentEvent:function(e){return this.content.dispatchEvent(e);},dispatchHeaderEvent:function(e){return this.header.dispatchEvent(e);},setColWidth:function(_7d,_7e){this.grid.setCellWidth(_7d,_7e+"px");},update:function(){if(!this.domNode){return;}this.content.update();this.grid.update();var _7f=this.scrollboxNode.scrollLeft;this.scrollboxNode.scrollLeft=_7f;this.headerNode.scrollLeft=_7f;}});var _80=_19("dojox.grid._GridAvatar",_26,{construct:function(){var dd=win.doc;var a=dd.createElement("table");a.cellPadding=a.cellSpacing="0";a.className="dojoxGridDndAvatar";a.style.position="absolute";a.style.zIndex=1999;a.style.margin="0px";var b=dd.createElement("tbody");var tr=dd.createElement("tr");var td=dd.createElement("td");var img=dd.createElement("td");tr.className="dojoxGridDndAvatarItem";img.className="dojoxGridDndAvatarItemImage";img.style.width="16px";var _81=this.manager.source,_82;if(_81.creator){_82=_81._normalizedCreator(_81.getItem(this.manager.nodes[0].id).data,"avatar").node;}else{_82=this.manager.nodes[0].cloneNode(true);var _83,_84;if(_82.tagName.toLowerCase()=="tr"){_83=dd.createElement("table");_84=dd.createElement("tbody");_84.appendChild(_82);_83.appendChild(_84);_82=_83;}else{if(_82.tagName.toLowerCase()=="th"){_83=dd.createElement("table");_84=dd.createElement("tbody");var r=dd.createElement("tr");_83.cellPadding=_83.cellSpacing="0";r.appendChild(_82);_84.appendChild(r);_83.appendChild(_84);_82=_83;}}}_82.id="";td.appendChild(_82);tr.appendChild(img);tr.appendChild(td);_24.style(tr,"opacity",0.9);b.appendChild(tr);a.appendChild(b);this.node=a;var m=_16.dnd.manager();this.oldOffsetY=m.OFFSET_Y;m.OFFSET_Y=1;},destroy:function(){_16.dnd.manager().OFFSET_Y=this.oldOffsetY;this.inherited(arguments);}});var _85=_16.dnd.manager().makeAvatar;_16.dnd.manager().makeAvatar=function(){var src=this.source;if(src.viewIndex!==undefined&&!_24.hasClass(win.body(),"dijit_a11y")){return new _80(this);}return _85.call(_16.dnd.manager());};return _2a;});},"dijit/_Contained":function(){define("dijit/_Contained",["dojo/_base/declare","./registry"],function(_86,_87){return _86("dijit._Contained",null,{_getSibling:function(_88){var _89=this.domNode;do{_89=_89[_88+"Sibling"];}while(_89&&_89.nodeType!=1);return _89&&_87.byNode(_89);},getPreviousSibling:function(){return this._getSibling("previous");},getNextSibling:function(){return this._getSibling("next");},getIndexInParent:function(){var p=this.getParent();if(!p||!p.getIndexOfChild){return -1;}return p.getIndexOfChild(this);}});});},"dojo/dnd/Selector":function(){define(["../main","./common","./Container"],function(_8a){_8a.declare("dojo.dnd.Selector",_8a.dnd.Container,{constructor:function(_8b,_8c){if(!_8c){_8c={};}this.singular=_8c.singular;this.autoSync=_8c.autoSync;this.selection={};this.anchor=null;this.simpleSelection=false;this.events.push(_8a.connect(this.node,"onmousedown",this,"onMouseDown"),_8a.connect(this.node,"onmouseup",this,"onMouseUp"));},singular:false,getSelectedNodes:function(){var t=new _8a.NodeList();var e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}t.push(_8a.byId(i));}return t;},selectNone:function(){return this._removeSelection()._removeAnchor();},selectAll:function(){this.forInItems(function(_8d,id){this._addItemClass(_8a.byId(id),"Selected");this.selection[id]=1;},this);return this._removeAnchor();},deleteSelectedNodes:function(){var e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}var n=_8a.byId(i);this.delItem(i);_8a.destroy(n);}this.anchor=null;this.selection={};return this;},forInSelectedItems:function(f,o){o=o||_8a.global;var s=this.selection,e=_8a.dnd._empty;for(var i in s){if(i in e){continue;}f.call(o,this.getItem(i),i,this);}},sync:function(){_8a.dnd.Selector.superclass.sync.call(this);if(this.anchor){if(!this.getItem(this.anchor.id)){this.anchor=null;}}var t=[],e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}if(!this.getItem(i)){t.push(i);}}_8a.forEach(t,function(i){delete this.selection[i];},this);return this;},insertNodes:function(_8e,_8f,_90,_91){var _92=this._normalizedCreator;this._normalizedCreator=function(_93,_94){var t=_92.call(this,_93,_94);if(_8e){if(!this.anchor){this.anchor=t.node;this._removeItemClass(t.node,"Selected");this._addItemClass(this.anchor,"Anchor");}else{if(this.anchor!=t.node){this._removeItemClass(t.node,"Anchor");this._addItemClass(t.node,"Selected");}}this.selection[t.node.id]=1;}else{this._removeItemClass(t.node,"Selected");this._removeItemClass(t.node,"Anchor");}return t;};_8a.dnd.Selector.superclass.insertNodes.call(this,_8f,_90,_91);this._normalizedCreator=_92;return this;},destroy:function(){_8a.dnd.Selector.superclass.destroy.call(this);this.selection=this.anchor=null;},onMouseDown:function(e){if(this.autoSync){this.sync();}if(!this.current){return;}if(!this.singular&&!_8a.isCopyKey(e)&&!e.shiftKey&&(this.current.id in this.selection)){this.simpleSelection=true;if(e.button===_8a.mouseButtons.LEFT){_8a.stopEvent(e);}return;}if(!this.singular&&e.shiftKey){if(!_8a.isCopyKey(e)){this._removeSelection();}var c=this.getAllNodes();if(c.length){if(!this.anchor){this.anchor=c[0];this._addItemClass(this.anchor,"Anchor");}this.selection[this.anchor.id]=1;if(this.anchor!=this.current){var i=0;for(;i<c.length;++i){var _95=c[i];if(_95==this.anchor||_95==this.current){break;}}for(++i;i<c.length;++i){var _95=c[i];if(_95==this.anchor||_95==this.current){break;}this._addItemClass(_95,"Selected");this.selection[_95.id]=1;}this._addItemClass(this.current,"Selected");this.selection[this.current.id]=1;}}}else{if(this.singular){if(this.anchor==this.current){if(_8a.isCopyKey(e)){this.selectNone();}}else{this.selectNone();this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}}else{if(_8a.isCopyKey(e)){if(this.anchor==this.current){delete this.selection[this.anchor.id];this._removeAnchor();}else{if(this.current.id in this.selection){this._removeItemClass(this.current,"Selected");delete this.selection[this.current.id];}else{if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this._addItemClass(this.anchor,"Selected");}this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}else{if(!(this.current.id in this.selection)){this.selectNone();this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}}_8a.stopEvent(e);},onMouseUp:function(e){if(!this.simpleSelection){return;}this.simpleSelection=false;this.selectNone();if(this.current){this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}},onMouseMove:function(e){this.simpleSelection=false;},onOverEvent:function(){this.onmousemoveEvent=_8a.connect(this.node,"onmousemove",this,"onMouseMove");},onOutEvent:function(){_8a.disconnect(this.onmousemoveEvent);delete this.onmousemoveEvent;},_removeSelection:function(){var e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}var _96=_8a.byId(i);if(_96){this._removeItemClass(_96,"Selected");}}this.selection={};return this;},_removeAnchor:function(){if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this.anchor=null;}return this;}});return _8a.dnd.Selector;});},"dojo/parser":function(){define(["./_base/kernel","./_base/lang","./_base/array","./_base/html","./_base/window","./_base/url","./_base/json","./aspect","./date/stamp","./query","./on","./ready"],function(_97,_98,_99,_9a,_9b,_9c,_9d,_9e,_9f,_a0,don){new Date("X");var _a1={"dom-attributes-explicit":document.createElement("div").attributes.length<40};function has(_a2){return _a1[_a2];};_97.parser=new function(){var _a3={};function _a4(_a5){var map={};for(var _a6 in _a5){if(_a6.charAt(0)=="_"){continue;}map[_a6.toLowerCase()]=_a6;}return map;};_9e.after(_98,"extend",function(){_a3={};},true);var _a7={};this._functionFromScript=function(_a8,_a9){var _aa="";var _ab="";var _ac=(_a8.getAttribute(_a9+"args")||_a8.getAttribute("args"));if(_ac){_99.forEach(_ac.split(/\s*,\s*/),function(_ad,idx){_aa+="var "+_ad+" = arguments["+idx+"]; ";});}var _ae=_a8.getAttribute("with");if(_ae&&_ae.length){_99.forEach(_ae.split(/\s*,\s*/),function(_af){_aa+="with("+_af+"){";_ab+="}";});}return new Function(_aa+_a8.innerHTML+_ab);};this.instantiate=function(_b0,_b1,_b2){var _b3=[],_b1=_b1||{};_b2=_b2||{};var _b4=(_b2.scope||_97._scopeName)+"Type",_b5="data-"+(_b2.scope||_97._scopeName)+"-",_b6=_b5+"type",_b7=_b5+"props",_b8=_b5+"attach-point",_b9=_b5+"attach-event",_ba=_b5+"id";var _bb={};_99.forEach([_b7,_b6,_b4,_ba,"jsId",_b8,_b9,"dojoAttachPoint","dojoAttachEvent","class","style"],function(_bc){_bb[_bc.toLowerCase()]=_bc.replace(_b2.scope,"dojo");});_99.forEach(_b0,function(obj){if(!obj){return;}var _bd=obj.node||obj,_be=_b4 in _b1?_b1[_b4]:obj.node?obj.type:(_bd.getAttribute(_b6)||_bd.getAttribute(_b4)),_bf=_a7[_be]||(_a7[_be]=_98.getObject(_be)),_c0=_bf&&_bf.prototype;if(!_bf){throw new Error("Could not load class '"+_be);}var _c1={};if(_b2.defaults){_98.mixin(_c1,_b2.defaults);}if(obj.inherited){_98.mixin(_c1,obj.inherited);}var _c2;if(has("dom-attributes-explicit")){_c2=_bd.attributes;}else{var _c3=/^input$|^img$/i.test(_bd.nodeName)?_bd:_bd.cloneNode(false),_c4=_c3.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g,"").replace(/^\s*<[a-zA-Z0-9]*/,"").replace(/>.*$/,"");_c2=_99.map(_c4.split(/\s+/),function(_c5){var _c6=_c5.toLowerCase();return {name:_c5,value:(_bd.nodeName=="LI"&&_c5=="value")||_c6=="enctype"?_bd.getAttribute(_c6):_bd.getAttributeNode(_c6).value,specified:true};});}var i=0,_c7;while(_c7=_c2[i++]){if(!_c7||!_c7.specified){continue;}var _c8=_c7.name,_c9=_c8.toLowerCase(),_ca=_c7.value;if(_c9 in _bb){switch(_bb[_c9]){case "data-dojo-props":var _cb=_ca;break;case "data-dojo-id":case "jsId":var _cc=_ca;break;case "data-dojo-attach-point":case "dojoAttachPoint":_c1.dojoAttachPoint=_ca;break;case "data-dojo-attach-event":case "dojoAttachEvent":_c1.dojoAttachEvent=_ca;break;case "class":_c1["class"]=_bd.className;break;case "style":_c1["style"]=_bd.style&&_bd.style.cssText;break;}}else{if(!(_c8 in _c0)){var map=(_a3[_be]||(_a3[_be]=_a4(_c0)));_c8=map[_c9]||_c8;}if(_c8 in _c0){switch(typeof _c0[_c8]){case "string":_c1[_c8]=_ca;break;case "number":_c1[_c8]=_ca.length?Number(_ca):NaN;break;case "boolean":_c1[_c8]=_ca.toLowerCase()!="false";break;case "function":if(_ca===""||_ca.search(/[^\w\.]+/i)!=-1){_c1[_c8]=new Function(_ca);}else{_c1[_c8]=_98.getObject(_ca,false)||new Function(_ca);}break;default:var _cd=_c0[_c8];_c1[_c8]=(_cd&&"length" in _cd)?(_ca?_ca.split(/\s*,\s*/):[]):(_cd instanceof Date)?(_ca==""?new Date(""):_ca=="now"?new Date():_9f.fromISOString(_ca)):(_cd instanceof _97._Url)?(_97.baseUrl+_ca):_9d.fromJson(_ca);}}else{_c1[_c8]=_ca;}}}if(_cb){try{_cb=_9d.fromJson.call(_b2.propsThis,"{"+_cb+"}");_98.mixin(_c1,_cb);}catch(e){throw new Error(e.toString()+" in data-dojo-props='"+_cb+"'");}}_98.mixin(_c1,_b1);var _ce=obj.node?obj.scripts:(_bf&&(_bf._noScript||_c0._noScript)?[]:_a0("> script[type^='dojo/']",_bd));var _cf=[],_d0=[],_d1=[],on=[];if(_ce){for(i=0;i<_ce.length;i++){var _d2=_ce[i];_bd.removeChild(_d2);var _d3=(_d2.getAttribute(_b5+"event")||_d2.getAttribute("event")),_d4=_d2.getAttribute(_b5+"prop"),_be=_d2.getAttribute("type"),nf=this._functionFromScript(_d2,_b5);if(_d3){if(_be=="dojo/connect"){_cf.push({event:_d3,func:nf});}else{if(_be=="dojo/on"){on.push({event:_d3,func:nf});}else{_c1[_d3]=nf;}}}else{if(_be=="dojo/watch"){_d1.push({prop:_d4,func:nf});}else{_d0.push(nf);}}}}var _d5=_bf.markupFactory||_c0.markupFactory;var _d6=_d5?_d5(_c1,_bd,_bf):new _bf(_c1,_bd);_b3.push(_d6);if(_cc){_98.setObject(_cc,_d6);}for(i=0;i<_cf.length;i++){_9e.after(_d6,_cf[i].event,_97.hitch(_d6,_cf[i].func),true);}for(i=0;i<_d0.length;i++){_d0[i].call(_d6);}for(i=0;i<_d1.length;i++){_d6.watch(_d1[i].prop,_d1[i].func);}for(i=0;i<on.length;i++){don(_d6,on[i].event,on[i].func);}},this);if(!_b1._started){_99.forEach(_b3,function(_d7){if(!_b2.noStart&&_d7&&_98.isFunction(_d7.startup)&&!_d7._started){_d7.startup();}});}return _b3;};this.parse=function(_d8,_d9){var _da;if(!_d9&&_d8&&_d8.rootNode){_d9=_d8;_da=_d9.rootNode;}else{_da=_d8;}_da=_da?_9a.byId(_da):_9b.body();_d9=_d9||{};var _db=(_d9.scope||_97._scopeName)+"Type",_dc="data-"+(_d9.scope||_97._scopeName)+"-",_dd=_dc+"type",_de=_dc+"textdir";var _df=[];var _e0=_da.firstChild;var _e1=_d9&&_d9.inherited;if(!_e1){function _e2(_e3,_e4){return (_e3.getAttribute&&_e3.getAttribute(_e4))||(_e3!==_9b.doc&&_e3!==_9b.doc.documentElement&&_e3.parentNode?_e2(_e3.parentNode,_e4):null);};_e1={dir:_e2(_da,"dir"),lang:_e2(_da,"lang"),textDir:_e2(_da,_de)};for(var key in _e1){if(!_e1[key]){delete _e1[key];}}}var _e5={inherited:_e1};var _e6;var _e7;function _e8(_e9){if(!_e9.inherited){_e9.inherited={};var _ea=_e9.node,_eb=_e8(_e9.parent);var _ec={dir:_ea.getAttribute("dir")||_eb.dir,lang:_ea.getAttribute("lang")||_eb.lang,textDir:_ea.getAttribute(_de)||_eb.textDir};for(var key in _ec){if(_ec[key]){_e9.inherited[key]=_ec[key];}}}return _e9.inherited;};while(true){if(!_e0){if(!_e5||!_e5.node){break;}_e0=_e5.node.nextSibling;_e6=_e5.scripts;_e7=false;_e5=_e5.parent;continue;}if(_e0.nodeType!=1){_e0=_e0.nextSibling;continue;}if(_e6&&_e0.nodeName.toLowerCase()=="script"){_ed=_e0.getAttribute("type");if(_ed&&/^dojo\/\w/i.test(_ed)){_e6.push(_e0);}_e0=_e0.nextSibling;continue;}if(_e7){_e0=_e0.nextSibling;continue;}var _ed=_e0.getAttribute(_dd)||_e0.getAttribute(_db);var _ee=_e0.firstChild;if(!_ed&&(!_ee||(_ee.nodeType==3&&!_ee.nextSibling))){_e0=_e0.nextSibling;continue;}var _ef={node:_e0,scripts:_e6,parent:_e5};var _f0=_ed&&(_a7[_ed]||(_a7[_ed]=_98.getObject(_ed))),_f1=_f0&&!_f0.prototype._noScript?[]:null;if(_ed){_df.push({"type":_ed,node:_e0,scripts:_f1,inherited:_e8(_ef)});}_e0=_ee;_e6=_f1;_e7=_f0&&_f0.prototype.stopParser&&!(_d9&&_d9.template);_e5=_ef;}var _f2=_d9&&_d9.template?{template:true}:null;return this.instantiate(_df,_f2,_d9);};}();if(_97.config.parseOnLoad){_97.ready(100,_97.parser,"parse");}return _97.parser;});},"dojox/grid/DataSelection":function(){define("dojox/grid/DataSelection",["dojo/_base/declare","./_SelectionPreserver","./Selection"],function(_f3,_f4,_f5){return _f3("dojox.grid.DataSelection",_f5,{constructor:function(_f6){if(_f6.keepSelection){this.preserver=new _f4(this);}},destroy:function(){if(this.preserver){this.preserver.destroy();}},getFirstSelected:function(){var idx=_f5.prototype.getFirstSelected.call(this);if(idx==-1){return null;}return this.grid.getItem(idx);},getNextSelected:function(_f7){var _f8=this.grid.getItemIndex(_f7);var idx=_f5.prototype.getNextSelected.call(this,_f8);if(idx==-1){return null;}return this.grid.getItem(idx);},getSelected:function(){var _f9=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_f9.push(this.grid.getItem(i));}}return _f9;},addToSelection:function(_fa){if(this.mode=="none"){return;}var idx=null;if(typeof _fa=="number"||typeof _fa=="string"){idx=_fa;}else{idx=this.grid.getItemIndex(_fa);}_f5.prototype.addToSelection.call(this,idx);},deselect:function(_fb){if(this.mode=="none"){return;}var idx=null;if(typeof _fb=="number"||typeof _fb=="string"){idx=_fb;}else{idx=this.grid.getItemIndex(_fb);}_f5.prototype.deselect.call(this,idx);},deselectAll:function(_fc){var idx=null;if(_fc||typeof _fc=="number"){if(typeof _fc=="number"||typeof _fc=="string"){idx=_fc;}else{idx=this.grid.getItemIndex(_fc);}_f5.prototype.deselectAll.call(this,idx);}else{this.inherited(arguments);}}});});},"url:dijit/templates/CheckedMenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\"> </td>\n</tr>\n","dojo/dnd/Manager":function(){define(["../main","../Evented","./common","./autoscroll","./Avatar"],function(_fd,_fe){var _ff=_fd.declare("dojo.dnd.Manager",[_fe],{constructor:function(){this.avatar=null;this.source=null;this.nodes=[];this.copy=true;this.target=null;this.canDropFlag=false;this.events=[];},OFFSET_X:16,OFFSET_Y:16,overSource:function(_100){if(this.avatar){this.target=(_100&&_100.targetState!="Disabled")?_100:null;this.canDropFlag=Boolean(this.target);this.avatar.update();}_fd.publish("/dnd/source/over",[_100]);},outSource:function(_101){if(this.avatar){if(this.target==_101){this.target=null;this.canDropFlag=false;this.avatar.update();_fd.publish("/dnd/source/over",[null]);}}else{_fd.publish("/dnd/source/over",[null]);}},startDrag:function(_102,_103,copy){this.source=_102;this.nodes=_103;this.copy=Boolean(copy);this.avatar=this.makeAvatar();_fd.body().appendChild(this.avatar.node);_fd.publish("/dnd/start",[_102,_103,this.copy]);this.events=[_fd.connect(_fd.doc,"onmousemove",this,"onMouseMove"),_fd.connect(_fd.doc,"onmouseup",this,"onMouseUp"),_fd.connect(_fd.doc,"onkeydown",this,"onKeyDown"),_fd.connect(_fd.doc,"onkeyup",this,"onKeyUp"),_fd.connect(_fd.doc,"ondragstart",_fd.stopEvent),_fd.connect(_fd.body(),"onselectstart",_fd.stopEvent)];var c="dojoDnd"+(copy?"Copy":"Move");_fd.addClass(_fd.body(),c);},canDrop:function(flag){var _104=Boolean(this.target&&flag);if(this.canDropFlag!=_104){this.canDropFlag=_104;this.avatar.update();}},stopDrag:function(){_fd.removeClass(_fd.body(),["dojoDndCopy","dojoDndMove"]);_fd.forEach(this.events,_fd.disconnect);this.events=[];this.avatar.destroy();this.avatar=null;this.source=this.target=null;this.nodes=[];},makeAvatar:function(){return new _fd.dnd.Avatar(this);},updateAvatar:function(){this.avatar.update();},onMouseMove:function(e){var a=this.avatar;if(a){_fd.dnd.autoScrollNodes(e);var s=a.node.style;s.left=(e.pageX+this.OFFSET_X)+"px";s.top=(e.pageY+this.OFFSET_Y)+"px";var copy=Boolean(this.source.copyState(_fd.isCopyKey(e)));if(this.copy!=copy){this._setCopyStatus(copy);}}},onMouseUp:function(e){if(this.avatar){if(this.target&&this.canDropFlag){var copy=Boolean(this.source.copyState(_fd.isCopyKey(e))),_105=[this.source,this.nodes,copy,this.target,e];_fd.publish("/dnd/drop/before",_105);_fd.publish("/dnd/drop",_105);}else{_fd.publish("/dnd/cancel");}this.stopDrag();}},onKeyDown:function(e){if(this.avatar){switch(e.keyCode){case _fd.keys.CTRL:var copy=Boolean(this.source.copyState(true));if(this.copy!=copy){this._setCopyStatus(copy);}break;case _fd.keys.ESCAPE:_fd.publish("/dnd/cancel");this.stopDrag();break;}}},onKeyUp:function(e){if(this.avatar&&e.keyCode==_fd.keys.CTRL){var copy=Boolean(this.source.copyState(false));if(this.copy!=copy){this._setCopyStatus(copy);}}},_setCopyStatus:function(copy){this.copy=copy;this.source._markDndStatus(this.copy);this.updateAvatar();_fd.replaceClass(_fd.body(),"dojoDnd"+(this.copy?"Copy":"Move"),"dojoDnd"+(this.copy?"Move":"Copy"));}});_fd.dnd._manager=null;_ff.manager=_fd.dnd.manager=function(){if(!_fd.dnd._manager){_fd.dnd._manager=new _fd.dnd.Manager();}return _fd.dnd._manager;};return _ff;});},"dojox/grid/_RowSelector":function(){define("dojox/grid/_RowSelector",["dojo/_base/declare","./_View"],function(_106,_107){return _106("dojox.grid._RowSelector",_107,{defaultWidth:"2em",noscroll:true,padBorderWidth:2,buildRendering:function(){this.inherited("buildRendering",arguments);this.scrollboxNode.style.overflow="hidden";this.headerNode.style.visibility="hidden";},getWidth:function(){return this.viewWidth||this.defaultWidth;},buildRowContent:function(_108,_109){var w=this.contentWidth||0;_109.innerHTML="<table class=\"dojoxGridRowbarTable\" style=\"width:"+w+"px;height:1px;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"><tr><td class=\"dojoxGridRowbarInner\"> </td></tr></table>";},renderHeader:function(){},updateRow:function(){},resize:function(){this.adaptHeight();},adaptWidth:function(){if(!("contentWidth" in this)&&this.contentNode){this.contentWidth=this.contentNode.offsetWidth-this.padBorderWidth;}},doStyleRowNode:function(_10a,_10b){var n=["dojoxGridRowbar dojoxGridNonNormalizedCell"];if(this.grid.rows.isOver(_10a)){n.push("dojoxGridRowbarOver");}if(this.grid.selection.isSelected(_10a)){n.push("dojoxGridRowbarSelected");}_10b.className=n.join(" ");},domouseover:function(e){this.grid.onMouseOverRow(e);},domouseout:function(e){if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}});});},"dojox/grid/_Layout":function(){define("dojox/grid/_Layout",["dojo/_base/kernel","../main","dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/dom-geometry","./cells","./_RowSelector"],function(dojo,_10c,_10d,_10e,lang,_10f){return _10d("dojox.grid._Layout",null,{constructor:function(_110){this.grid=_110;},cells:[],structure:null,defaultWidth:"6em",moveColumn:function(_111,_112,_113,_114,_115){var _116=this.structure[_111].cells[0];var _117=this.structure[_112].cells[0];var cell=null;var _118=0;var _119=0;for(var i=0,c;c=_116[i];i++){if(c.index==_113){_118=i;break;}}cell=_116.splice(_118,1)[0];cell.view=this.grid.views.views[_112];for(i=0,c=null;c=_117[i];i++){if(c.index==_114){_119=i;break;}}if(!_115){_119+=1;}_117.splice(_119,0,cell);var _11a=this.grid.getCell(this.grid.getSortIndex());if(_11a){_11a._currentlySorted=this.grid.getSortAsc();}this.cells=[];_113=0;var v;for(i=0;v=this.structure[i];i++){for(var j=0,cs;cs=v.cells[j];j++){for(var k=0;c=cs[k];k++){c.index=_113;this.cells.push(c);if("_currentlySorted" in c){var si=_113+1;si*=c._currentlySorted?1:-1;this.grid.sortInfo=si;delete c._currentlySorted;}_113++;}}}_10e.forEach(this.cells,function(c){var _11b=c.markup[2].split(" ");var _11c=parseInt(_11b[1].substring(5));if(_11c!=c.index){_11b[1]="idx=\""+c.index+"\"";c.markup[2]=_11b.join(" ");}});this.grid.setupHeaderMenu();},setColumnVisibility:function(_11d,_11e){var cell=this.cells[_11d];if(cell.hidden==_11e){cell.hidden=!_11e;var v=cell.view,w=v.viewWidth;if(w&&w!="auto"){v._togglingColumn=_10f.getMarginBox(cell.getHeaderNode()).w||0;}v.update();return true;}else{return false;}},addCellDef:function(_11f,_120,_121){var self=this;var _122=function(_123){var w=0;if(_123.colSpan>1){w=0;}else{w=_123.width||self._defaultCellProps.width||self.defaultWidth;if(!isNaN(w)){w=w+"em";}}return w;};var _124={grid:this.grid,subrow:_11f,layoutIndex:_120,index:this.cells.length};if(_121&&_121 instanceof _10c.grid.cells._Base){var _125=lang.clone(_121);_124.unitWidth=_122(_125._props);_125=lang.mixin(_125,this._defaultCellProps,_121._props,_124);return _125;}var _126=_121.type||_121.cellType||this._defaultCellProps.type||this._defaultCellProps.cellType||_10c.grid.cells.Cell;if(lang.isString(_126)){_126=lang.getObject(_126);}_124.unitWidth=_122(_121);return new _126(lang.mixin({},this._defaultCellProps,_121,_124));},addRowDef:function(_127,_128){var _129=[];var _12a=0,_12b=0,_12c=true;for(var i=0,def,cell;(def=_128[i]);i++){cell=this.addCellDef(_127,i,def);_129.push(cell);this.cells.push(cell);if(_12c&&cell.relWidth){_12a+=cell.relWidth;}else{if(cell.width){var w=cell.width;if(typeof w=="string"&&w.slice(-1)=="%"){_12b+=window.parseInt(w,10);}else{if(w=="auto"){_12c=false;}}}}}if(_12a&&_12c){_10e.forEach(_129,function(cell){if(cell.relWidth){cell.width=cell.unitWidth=((cell.relWidth/_12a)*(100-_12b))+"%";}});}return _129;},addRowsDef:function(_12d){var _12e=[];if(lang.isArray(_12d)){if(lang.isArray(_12d[0])){for(var i=0,row;_12d&&(row=_12d[i]);i++){_12e.push(this.addRowDef(i,row));}}else{_12e.push(this.addRowDef(0,_12d));}}return _12e;},addViewDef:function(_12f){this._defaultCellProps=_12f.defaultCell||{};if(_12f.width&&_12f.width=="auto"){delete _12f.width;}return lang.mixin({},_12f,{cells:this.addRowsDef(_12f.rows||_12f.cells)});},setStructure:function(_130){this.fieldIndex=0;this.cells=[];var s=this.structure=[];if(this.grid.rowSelector){var sel={type:_10c._scopeName+".grid._RowSelector"};if(lang.isString(this.grid.rowSelector)){var _131=this.grid.rowSelector;if(_131=="false"){sel=null;}else{if(_131!="true"){sel["width"]=_131;}}}else{if(!this.grid.rowSelector){sel=null;}}if(sel){s.push(this.addViewDef(sel));}}var _132=function(def){return ("name" in def||"field" in def||"get" in def);};var _133=function(def){if(lang.isArray(def)){if(lang.isArray(def[0])||_132(def[0])){return true;}}return false;};var _134=function(def){return (def!==null&&lang.isObject(def)&&("cells" in def||"rows" in def||("type" in def&&!_132(def))));};if(lang.isArray(_130)){var _135=false;for(var i=0,st;(st=_130[i]);i++){if(_134(st)){_135=true;break;}}if(!_135){s.push(this.addViewDef({cells:_130}));}else{for(i=0;(st=_130[i]);i++){if(_133(st)){s.push(this.addViewDef({cells:st}));}else{if(_134(st)){s.push(this.addViewDef(st));}}}}}else{if(_134(_130)){s.push(this.addViewDef(_130));}}this.cellCount=this.cells.length;this.grid.setupHeaderMenu();}});});},"dojox/grid/_Grid":function(){require({cache:{"url:dojox/grid/resources/_Grid.html":"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n"}});define("dojox/grid/_Grid",["dojo/_base/kernel","../main","dojo/_base/declare","./_Events","./_Scroller","./_Layout","./_View","./_ViewManager","./_RowManager","./_FocusManager","./_EditManager","./Selection","./_RowSelector","./util","dijit/_Widget","dijit/_TemplatedMixin","dijit/CheckedMenuItem","dojo/text!./resources/_Grid.html","dojo/string","dojo/_base/array","dojo/_base/lang","dojo/_base/sniff","dojox/html/metrics","dojo/_base/html","dojo/query","dojo/dnd/common","dojo/i18n!dijit/nls/loading"],function(dojo,_136,_137,_138,_139,_13a,_13b,_13c,_13d,_13e,_13f,_140,_141,util,_142,_143,_144,_145,_146,_147,lang,has,_148,html,_149){if(!dojo.isCopyKey){dojo.isCopyKey=dojo.dnd.getCopyKeyState;}var _14a=_137("dojox.grid._Grid",[_142,_143,_138],{templateString:_145,classTag:"dojoxGrid",rowCount:5,keepRows:75,rowsPerPage:25,autoWidth:false,initialWidth:"",autoHeight:"",rowHeight:0,autoRender:true,defaultHeight:"15em",height:"",structure:null,elasticView:-1,singleClickEdit:false,selectionMode:"extended",rowSelector:"",columnReordering:false,headerMenu:null,placeholderLabel:"GridColumns",selectable:false,_click:null,loadingMessage:"<span class='dojoxGridLoading'>${loadingState}</span>",errorMessage:"<span class='dojoxGridError'>${errorState}</span>",noDataMessage:"",escapeHTMLInData:true,formatterScope:null,editable:false,sortInfo:0,themeable:true,_placeholders:null,_layoutClass:_13a,buildRendering:function(){this.inherited(arguments);if(!this.domNode.getAttribute("tabIndex")){this.domNode.tabIndex="0";}this.createScroller();this.createLayout();this.createViews();this.createManagers();this.createSelection();this.connect(this.selection,"onSelected","onSelected");this.connect(this.selection,"onDeselected","onDeselected");this.connect(this.selection,"onChanged","onSelectionChanged");_148.initOnFontResize();this.connect(_148,"onFontResize","textSizeChanged");util.funnelEvents(this.domNode,this,"doKeyEvent",util.keyEvents);if(this.selectionMode!="none"){this.domNode.setAttribute("aria-multiselectable",this.selectionMode=="single"?"false":"true");}html.addClass(this.domNode,this.classTag);if(!this.isLeftToRight()){html.addClass(this.domNode,this.classTag+"Rtl");}},postMixInProperties:function(){this.inherited(arguments);var _14b=dojo.i18n.getLocalization("dijit","loading",this.lang);this.loadingMessage=_146.substitute(this.loadingMessage,_14b);this.errorMessage=_146.substitute(this.errorMessage,_14b);if(this.srcNodeRef&&this.srcNodeRef.style.height){this.height=this.srcNodeRef.style.height;}this._setAutoHeightAttr(this.autoHeight,true);this.lastScrollTop=this.scrollTop=0;},postCreate:function(){this._placeholders=[];this._setHeaderMenuAttr(this.headerMenu);this._setStructureAttr(this.structure);this._click=[];this.inherited(arguments);if(this.domNode&&this.autoWidth&&this.initialWidth){this.domNode.style.width=this.initialWidth;}if(this.domNode&&!this.editable){html.attr(this.domNode,"aria-readonly","true");}},destroy:function(){this.domNode.onReveal=null;this.domNode.onSizeChange=null;delete this._click;if(this.scroller){this.scroller.destroy();delete this.scroller;}this.edit.destroy();delete this.edit;this.views.destroyViews();if(this.focus){this.focus.destroy();delete this.focus;}if(this.headerMenu&&this._placeholders.length){_147.forEach(this._placeholders,function(p){p.unReplace(true);});this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.inherited(arguments);},_setAutoHeightAttr:function(ah,_14c){if(typeof ah=="string"){if(!ah||ah=="false"){ah=false;}else{if(ah=="true"){ah=true;}else{ah=window.parseInt(ah,10);}}}if(typeof ah=="number"){if(isNaN(ah)){ah=false;}if(ah<0){ah=true;}else{if(ah===0){ah=false;}}}this.autoHeight=ah;if(typeof ah=="boolean"){this._autoHeight=ah;}else{if(typeof ah=="number"){this._autoHeight=(ah>=this.get("rowCount"));}else{this._autoHeight=false;}}if(this._started&&!_14c){this.render();}},_getRowCountAttr:function(){return this.updating&&this.invalidated&&this.invalidated.rowCount!=undefined?this.invalidated.rowCount:this.rowCount;},textSizeChanged:function(){this.render();},sizeChange:function(){this.update();},createManagers:function(){this.rows=new _13d(this);this.focus=new _13e(this);this.edit=new _13f(this);},createSelection:function(){this.selection=new _140(this);},createScroller:function(){this.scroller=new _139();this.scroller.grid=this;this.scroller.renderRow=lang.hitch(this,"renderRow");this.scroller.removeRow=lang.hitch(this,"rowRemoved");},createLayout:function(){this.layout=new this._layoutClass(this);this.connect(this.layout,"moveColumn","onMoveColumn");},onMoveColumn:function(){this.render();},onResizeColumn:function(_14d){},createViews:function(){this.views=new _13c(this);this.views.createView=lang.hitch(this,"createView");},createView:function(_14e,idx){var c=lang.getObject(_14e);var view=new c({grid:this,index:idx});this.viewsNode.appendChild(view.domNode);this.viewsHeaderNode.appendChild(view.headerNode);this.views.addView(view);html.attr(this.domNode,"align",this.isLeftToRight()?"left":"right");return view;},buildViews:function(){for(var i=0,vs;(vs=this.layout.structure[i]);i++){this.createView(vs.type||_136._scopeName+".grid._View",i).setStructure(vs);}this.scroller.setContentNodes(this.views.getContentNodes());},_setStructureAttr:function(_14f){var s=_14f;if(s&&lang.isString(s)){dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')","use dojox.grid._Grid.set('structure', objVar) instead","2.0");s=lang.getObject(s);}this.structure=s;if(!s){if(this.layout.structure){s=this.layout.structure;}else{return;}}this.views.destroyViews();this.focus.focusView=null;if(s!==this.layout.structure){this.layout.setStructure(s);}this._structureChanged();},setStructure:function(_150){dojo.deprecated("dojox.grid._Grid.setStructure(obj)","use dojox.grid._Grid.set('structure', obj) instead.","2.0");this._setStructureAttr(_150);},getColumnTogglingItems:function(){var _151,_152=[];_151=_147.map(this.layout.cells,function(cell){if(!cell.menuItems){cell.menuItems=[];}var self=this;var item=new _144({label:cell.name,checked:!cell.hidden,_gridCell:cell,onChange:function(_153){if(self.layout.setColumnVisibility(this._gridCell.index,_153)){var _154=this._gridCell.menuItems;if(_154.length>1){_147.forEach(_154,function(item){if(item!==this){item.setAttribute("checked",_153);}},this);}_153=_147.filter(self.layout.cells,function(c){if(c.menuItems.length>1){_147.forEach(c.menuItems,"item.set('disabled', false);");}else{c.menuItems[0].set("disabled",false);}return !c.hidden;});if(_153.length==1){_147.forEach(_153[0].menuItems,"item.set('disabled', true);");}}},destroy:function(){var _155=_147.indexOf(this._gridCell.menuItems,this);this._gridCell.menuItems.splice(_155,1);delete this._gridCell;_144.prototype.destroy.apply(this,arguments);}});cell.menuItems.push(item);if(!cell.hidden){_152.push(item);}return item;},this);if(_152.length==1){_152[0].set("disabled",true);}return _151;},_setHeaderMenuAttr:function(menu){if(this._placeholders&&this._placeholders.length){_147.forEach(this._placeholders,function(p){p.unReplace(true);});this._placeholders=[];}if(this.headerMenu){this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.headerMenu=menu;if(!menu){return;}this.headerMenu.bindDomNode(this.viewsHeaderNode);if(this.headerMenu.getPlaceholders){this._placeholders=this.headerMenu.getPlaceholders(this.placeholderLabel);}},setHeaderMenu:function(menu){dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)","use dojox.grid._Grid.set('headerMenu', obj) instead.","2.0");this._setHeaderMenuAttr(menu);},setupHeaderMenu:function(){if(this._placeholders&&this._placeholders.length){_147.forEach(this._placeholders,function(p){if(p._replaced){p.unReplace(true);}p.replace(this.getColumnTogglingItems());},this);}},_fetch:function(_156){this.setScrollTop(0);},getItem:function(_157){return null;},showMessage:function(_158){if(_158){this.messagesNode.innerHTML=_158;this.messagesNode.style.display="";}else{this.messagesNode.innerHTML="";this.messagesNode.style.display="none";}},_structureChanged:function(){this.buildViews();if(this.autoRender&&this._started){this.render();}},hasLayout:function(){return this.layout.cells.length;},resize:function(_159,_15a){if(dojo.isIE&&!_159&&!_15a&&this._autoHeight){return;}this._pendingChangeSize=_159;this._pendingResultSize=_15a;this.sizeChange();},_getPadBorder:function(){this._padBorder=this._padBorder||html._getPadBorderExtents(this.domNode);return this._padBorder;},_getHeaderHeight:function(){var vns=this.viewsHeaderNode.style,t=vns.display=="none"?0:this.views.measureHeader();vns.height=t+"px";this.views.normalizeHeaderNodeHeight();return t;},_resize:function(_15b,_15c){_15b=_15b||this._pendingChangeSize;_15c=_15c||this._pendingResultSize;delete this._pendingChangeSize;delete this._pendingResultSize;if(!this.domNode){return;}var pn=this.domNode.parentNode;if(!pn||pn.nodeType!=1||!this.hasLayout()||pn.style.visibility=="hidden"||pn.style.display=="none"){return;}var _15d=this._getPadBorder();var hh=undefined;var h;if(this._autoHeight){this.domNode.style.height="auto";}else{if(typeof this.autoHeight=="number"){h=hh=this._getHeaderHeight();h+=(this.scroller.averageRowHeight*this.autoHeight);this.domNode.style.height=h+"px";}else{if(this.domNode.clientHeight<=_15d.h){if(pn==document.body){this.domNode.style.height=this.defaultHeight;}else{if(this.height){this.domNode.style.height=this.height;}else{this.fitTo="parent";}}}}}if(_15c){_15b=_15c;}if(!this._autoHeight&&_15b){html.marginBox(this.domNode,_15b);this.height=this.domNode.style.height;delete this.fitTo;}else{if(this.fitTo=="parent"){h=this._parentContentBoxHeight=this._parentContentBoxHeight||html._getContentBox(pn).h;this.domNode.style.height=Math.max(0,h)+"px";}}var _15e=_147.some(this.views.views,function(v){return v.flexCells;});if(!this._autoHeight&&(h||html._getContentBox(this.domNode).h)===0){this.viewsHeaderNode.style.display="none";}else{this.viewsHeaderNode.style.display="block";if(!_15e&&hh===undefined){hh=this._getHeaderHeight();}}if(_15e){hh=undefined;}this.adaptWidth();this.adaptHeight(hh);this.postresize();},adaptWidth:function(){var _15f=(!this.initialWidth&&this.autoWidth);var w=_15f?0:this.domNode.clientWidth||(this.domNode.offsetWidth-this._getPadBorder().w),vw=this.views.arrange(1,w);this.views.onEach("adaptWidth");if(_15f){this.domNode.style.width=vw+"px";}},adaptHeight:function(_160){var t=_160===undefined?this._getHeaderHeight():_160;var h=(this._autoHeight?-1:Math.max(this.domNode.clientHeight-t,0)||0);this.views.onEach("setSize",[0,h]);this.views.onEach("adaptHeight");if(!this._autoHeight){var _161=0,_162=0;var _163=_147.filter(this.views.views,function(v){var has=v.hasHScrollbar();if(has){_161++;}else{_162++;}return (!has);});if(_161>0&&_162>0){_147.forEach(_163,function(v){v.adaptHeight(true);});}}if(this.autoHeight===true||h!=-1||(typeof this.autoHeight=="number"&&this.autoHeight>=this.get("rowCount"))){this.scroller.windowHeight=h;}else{this.scroller.windowHeight=Math.max(this.domNode.clientHeight-t,0);}},startup:function(){if(this._started){return;}this.inherited(arguments);if(this.autoRender){this.render();}},render:function(){if(!this.domNode){return;}if(!this._started){return;}if(!this.hasLayout()){this.scroller.init(0,this.keepRows,this.rowsPerPage);return;}this.update=this.defaultUpdate;this._render();},_render:function(){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this.setScrollTop(0);this.postrender();},prerender:function(){this.keepRows=this._autoHeight?0:this.keepRows;this.scroller.setKeepInfo(this.keepRows);this.views.render();this._resize();},postrender:function(){this.postresize();this.focus.initFocusView();html.setSelectable(this.domNode,this.selectable);},postresize:function(){if(this._autoHeight){var size=Math.max(this.views.measureContent())+"px";this.viewsNode.style.height=size;}},renderRow:function(_164,_165){this.views.renderRow(_164,_165,this._skipRowRenormalize);},rowRemoved:function(_166){this.views.rowRemoved(_166);},invalidated:null,updating:false,beginUpdate:function(){this.invalidated=[];this.updating=true;},endUpdate:function(){this.updating=false;var i=this.invalidated,r;if(i.all){this.update();}else{if(i.rowCount!=undefined){this.updateRowCount(i.rowCount);}else{for(r in i){this.updateRow(Number(r));}}}this.invalidated=[];},defaultUpdate:function(){if(!this.domNode){return;}if(this.updating){this.invalidated.all=true;return;}this.lastScrollTop=this.scrollTop;this.prerender();this.scroller.invalidateNodes();this.setScrollTop(this.lastScrollTop);this.postrender();},update:function(){this.render();},updateRow:function(_167){_167=Number(_167);if(this.updating){this.invalidated[_167]=true;}else{this.views.updateRow(_167);this.scroller.rowHeightChanged(_167);}},updateRows:function(_168,_169){_168=Number(_168);_169=Number(_169);var i;if(this.updating){for(i=0;i<_169;i++){this.invalidated[i+_168]=true;}}else{for(i=0;i<_169;i++){this.views.updateRow(i+_168,this._skipRowRenormalize);}this.scroller.rowHeightChanged(_168);}},updateRowCount:function(_16a){if(this.updating){this.invalidated.rowCount=_16a;}else{this.rowCount=_16a;this._setAutoHeightAttr(this.autoHeight,true);if(this.layout.cells.length){this.scroller.updateRowCount(_16a);}this._resize();if(this.layout.cells.length){this.setScrollTop(this.scrollTop);}}},updateRowStyles:function(_16b){this.views.updateRowStyles(_16b);},getRowNode:function(_16c){if(this.focus.focusView&&!(this.focus.focusView instanceof _141)){return this.focus.focusView.rowNodes[_16c];}else{for(var i=0,_16d;(_16d=this.views.views[i]);i++){if(!(_16d instanceof _141)){return _16d.rowNodes[_16c];}}}return null;},rowHeightChanged:function(_16e){this.views.renormalizeRow(_16e);this.scroller.rowHeightChanged(_16e);},fastScroll:true,delayScroll:false,scrollRedrawThreshold:(has("ie")?100:50),scrollTo:function(_16f){if(!this.fastScroll){this.setScrollTop(_16f);return;}var _170=Math.abs(this.lastScrollTop-_16f);this.lastScrollTop=_16f;if(_170>this.scrollRedrawThreshold||this.delayScroll){this.delayScroll=true;this.scrollTop=_16f;this.views.setScrollTop(_16f);if(this._pendingScroll){window.clearTimeout(this._pendingScroll);}var _171=this;this._pendingScroll=window.setTimeout(function(){delete _171._pendingScroll;_171.finishScrollJob();},200);}else{this.setScrollTop(_16f);}},finishScrollJob:function(){this.delayScroll=false;this.setScrollTop(this.scrollTop);},setScrollTop:function(_172){this.scroller.scroll(this.views.setScrollTop(_172));},scrollToRow:function(_173){this.setScrollTop(this.scroller.findScrollTop(_173)+1);},styleRowNode:function(_174,_175){if(_175){this.rows.styleRowNode(_174,_175);}},_mouseOut:function(e){this.rows.setOverRow(-2);},getCell:function(_176){return this.layout.cells[_176];},setCellWidth:function(_177,_178){this.getCell(_177).unitWidth=_178;},getCellName:function(_179){return "Cell "+_179.index;},canSort:function(_17a){},sort:function(){},getSortAsc:function(_17b){_17b=_17b==undefined?this.sortInfo:_17b;return Boolean(_17b>0);},getSortIndex:function(_17c){_17c=_17c==undefined?this.sortInfo:_17c;return Math.abs(_17c)-1;},setSortIndex:function(_17d,_17e){var si=_17d+1;if(_17e!=undefined){si*=(_17e?1:-1);}else{if(this.getSortIndex()==_17d){si=-this.sortInfo;}}this.setSortInfo(si);},setSortInfo:function(_17f){if(this.canSort(_17f)){this.sortInfo=_17f;this.sort();this.update();}},doKeyEvent:function(e){e.dispatch="do"+e.type;this.onKeyEvent(e);},_dispatch:function(m,e){if(m in this){return this[m](e);}return false;},dispatchKeyEvent:function(e){this._dispatch(e.dispatch,e);},dispatchContentEvent:function(e){this.edit.dispatchEvent(e)||e.sourceView.dispatchContentEvent(e)||this._dispatch(e.dispatch,e);},dispatchHeaderEvent:function(e){e.sourceView.dispatchHeaderEvent(e)||this._dispatch("doheader"+e.type,e);},dokeydown:function(e){this.onKeyDown(e);},doclick:function(e){if(e.cellNode){this.onCellClick(e);}else{this.onRowClick(e);}},dodblclick:function(e){if(e.cellNode){this.onCellDblClick(e);}else{this.onRowDblClick(e);}},docontextmenu:function(e){if(e.cellNode){this.onCellContextMenu(e);}else{this.onRowContextMenu(e);}},doheaderclick:function(e){if(e.cellNode){this.onHeaderCellClick(e);}else{this.onHeaderClick(e);}},doheaderdblclick:function(e){if(e.cellNode){this.onHeaderCellDblClick(e);}else{this.onHeaderDblClick(e);}},doheadercontextmenu:function(e){if(e.cellNode){this.onHeaderCellContextMenu(e);}else{this.onHeaderContextMenu(e);}},doStartEdit:function(_180,_181){this.onStartEdit(_180,_181);},doApplyCellEdit:function(_182,_183,_184){this.onApplyCellEdit(_182,_183,_184);},doCancelEdit:function(_185){this.onCancelEdit(_185);},doApplyEdit:function(_186){this.onApplyEdit(_186);},addRow:function(){this.updateRowCount(this.get("rowCount")+1);},removeSelectedRows:function(){if(this.allItemsSelected){this.updateRowCount(0);}else{this.updateRowCount(Math.max(0,this.get("rowCount")-this.selection.getSelected().length));}this.selection.clear();}});_14a.markupFactory=function(_187,node,ctor,_188){var _189=function(n){var w=html.attr(n,"width")||"auto";if((w!="auto")&&(w.slice(-2)!="em")&&(w.slice(-1)!="%")){w=parseInt(w,10)+"px";}return w;};if(!_187.structure&&node.nodeName.toLowerCase()=="table"){_187.structure=_149("> colgroup",node).map(function(cg){var sv=html.attr(cg,"span");var v={noscroll:(html.attr(cg,"noscroll")=="true")?true:false,__span:(!!sv?parseInt(sv,10):1),cells:[]};if(html.hasAttr(cg,"width")){v.width=_189(cg);}return v;});if(!_187.structure.length){_187.structure.push({__span:Infinity,cells:[]});}_149("thead > tr",node).forEach(function(tr,_18a){var _18b=0;var _18c=0;var _18d;var _18e=null;_149("> th",tr).map(function(th){if(!_18e){_18d=0;_18e=_187.structure[0];}else{if(_18b>=(_18d+_18e.__span)){_18c++;_18d+=_18e.__span;var _18f=_18e;_18e=_187.structure[_18c];}}var cell={name:lang.trim(html.attr(th,"name")||th.innerHTML),colSpan:parseInt(html.attr(th,"colspan")||1,10),type:lang.trim(html.attr(th,"cellType")||""),id:lang.trim(html.attr(th,"id")||"")};_18b+=cell.colSpan;var _190=html.attr(th,"rowspan");if(_190){cell.rowSpan=_190;}if(html.hasAttr(th,"width")){cell.width=_189(th);}if(html.hasAttr(th,"relWidth")){cell.relWidth=window.parseInt(html.attr(th,"relWidth"),10);}if(html.hasAttr(th,"hidden")){cell.hidden=(html.attr(th,"hidden")=="true"||html.attr(th,"hidden")===true);}if(_188){_188(th,cell);}cell.type=cell.type?lang.getObject(cell.type):_136.grid.cells.Cell;if(cell.type&&cell.type.markupFactory){cell.type.markupFactory(th,cell);}if(!_18e.cells[_18a]){_18e.cells[_18a]=[];}_18e.cells[_18a].push(cell);});});}return new ctor(_187,node);};return _14a;});},"dijit/nls/loading":function(){define("dijit/nls/loading",{root:({loadingState:"Loading...",errorState:"Sorry, an error occurred"}),"zh":true,"zh-tw":true,"tr":true,"th":true,"sv":true,"sl":true,"sk":true,"ru":true,"ro":true,"pt":true,"pt-pt":true,"pl":true,"nl":true,"nb":true,"ko":true,"kk":true,"ja":true,"it":true,"hu":true,"hr":true,"he":true,"fr":true,"fi":true,"es":true,"el":true,"de":true,"da":true,"cs":true,"ca":true,"az":true,"ar":true});},"dojox/main":function(){define("dojox/main",["dojo/_base/kernel"],function(dojo){return dojo.dojox;});},"dojo/dnd/Mover":function(){define(["../main","../Evented","../touch","./common","./autoscroll"],function(dojo,_191,_192){dojo.declare("dojo.dnd.Mover",[_191],{constructor:function(node,e,host){this.node=dojo.byId(node);this.marginBox={l:e.pageX,t:e.pageY};this.mouseButton=e.button;var h=(this.host=host),d=node.ownerDocument;this.events=[dojo.connect(d,_192.move,this,"onFirstMove"),dojo.connect(d,_192.move,this,"onMouseMove"),dojo.connect(d,_192.release,this,"onMouseUp"),dojo.connect(d,"ondragstart",dojo.stopEvent),dojo.connect(d.body,"onselectstart",dojo.stopEvent)];if(h&&h.onMoveStart){h.onMoveStart(this);}},onMouseMove:function(e){dojo.dnd.autoScroll(e);var m=this.marginBox;this.host.onMove(this,{l:m.l+e.pageX,t:m.t+e.pageY},e);dojo.stopEvent(e);},onMouseUp:function(e){if(dojo.isWebKit&&dojo.isMac&&this.mouseButton==2?e.button==0:this.mouseButton==e.button){this.destroy();}dojo.stopEvent(e);},onFirstMove:function(e){var s=this.node.style,l,t,h=this.host;switch(s.position){case "relative":case "absolute":l=Math.round(parseFloat(s.left))||0;t=Math.round(parseFloat(s.top))||0;break;default:s.position="absolute";var m=dojo.marginBox(this.node);var b=dojo.doc.body;var bs=dojo.getComputedStyle(b);var bm=dojo._getMarginBox(b,bs);var bc=dojo._getContentBox(b,bs);l=m.l-(bc.l-bm.l);t=m.t-(bc.t-bm.t);break;}this.marginBox.l=l-this.marginBox.l;this.marginBox.t=t-this.marginBox.t;if(h&&h.onFirstMove){h.onFirstMove(this,e);}dojo.disconnect(this.events.shift());},destroy:function(){dojo.forEach(this.events,dojo.disconnect);var h=this.host;if(h&&h.onMoveStop){h.onMoveStop(this);}this.events=this.node=this.host=null;}});return dojo.dnd.Mover;});},"dojo/Stateful":function(){define(["./_base/kernel","./_base/declare","./_base/lang","./_base/array"],function(dojo,_193,lang,_194){return dojo.declare("dojo.Stateful",null,{postscript:function(_195){if(_195){lang.mixin(this,_195);}},get:function(name){return this[name];},set:function(name,_196){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _197=this[name];this[name]=_196;if(this._watchCallbacks){this._watchCallbacks(name,_197,_196);}return this;},watch:function(name,_198){var _199=this._watchCallbacks;if(!_199){var self=this;_199=this._watchCallbacks=function(name,_19a,_19b,_19c){var _19d=function(_19e){if(_19e){_19e=_19e.slice();for(var i=0,l=_19e.length;i<l;i++){try{_19e[i].call(self,name,_19a,_19b);}catch(e){console.error(e);}}}};_19d(_199["_"+name]);if(!_19c){_19d(_199["*"]);}};}if(!_198&&typeof name==="function"){_198=name;name="*";}else{name="_"+name;}var _19f=_199[name];if(typeof _19f!=="object"){_19f=_199[name]=[];}_19f.push(_198);return {unwatch:function(){_19f.splice(_194.indexOf(_19f,_198),1);}};}});});},"dojo/touch":function(){define(["./_base/kernel","./on","./has","./mouse"],function(dojo,on,has,_1a0){function _1a1(type){return function(node,_1a2){return on(node,type,_1a2);};};var _1a3=has("touch");dojo.touch={press:_1a1(_1a3?"touchstart":"mousedown"),move:_1a1(_1a3?"touchmove":"mousemove"),release:_1a1(_1a3?"touchend":"mouseup"),cancel:_1a3?_1a1("touchcancel"):_1a0.leave};return dojo.touch;});},"dojox/grid/Selection":function(){define("dojox/grid/Selection",["dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/dom-attr"],function(_1a4,_1a5,lang,_1a6){return _1a4("dojox.grid.Selection",null,{constructor:function(_1a7){this.grid=_1a7;this.selected=[];this.setMode(_1a7.selectionMode);},mode:"extended",selected:null,updating:0,selectedIndex:-1,setMode:function(mode){if(this.selected.length){this.deselectAll();}if(mode!="extended"&&mode!="multiple"&&mode!="single"&&mode!="none"){this.mode="extended";}else{this.mode=mode;}},onCanSelect:function(_1a8){return this.grid.onCanSelect(_1a8);},onCanDeselect:function(_1a9){return this.grid.onCanDeselect(_1a9);},onSelected:function(_1aa){},onDeselected:function(_1ab){},onChanging:function(){},onChanged:function(){},isSelected:function(_1ac){if(this.mode=="none"){return false;}return this.selected[_1ac];},getFirstSelected:function(){if(!this.selected.length||this.mode=="none"){return -1;}for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getNextSelected:function(_1ad){if(this.mode=="none"){return -1;}for(var i=_1ad+1,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getSelected:function(){var _1ae=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_1ae.push(i);}}return _1ae;},getSelectedCount:function(){var c=0;for(var i=0;i<this.selected.length;i++){if(this.selected[i]){c++;}}return c;},_beginUpdate:function(){if(this.updating===0){this.onChanging();}this.updating++;},_endUpdate:function(){this.updating--;if(this.updating===0){this.onChanged();}},select:function(_1af){if(this.mode=="none"){return;}if(this.mode!="multiple"){this.deselectAll(_1af);this.addToSelection(_1af);}else{this.toggleSelect(_1af);}},addToSelection:function(_1b0){if(this.mode=="none"){return;}if(lang.isArray(_1b0)){_1a5.forEach(_1b0,this.addToSelection,this);return;}_1b0=Number(_1b0);if(this.selected[_1b0]){this.selectedIndex=_1b0;}else{if(this.onCanSelect(_1b0)!==false){this.selectedIndex=_1b0;var _1b1=this.grid.getRowNode(_1b0);if(_1b1){_1a6.set(_1b1,"aria-selected","true");}this._beginUpdate();this.selected[_1b0]=true;this.onSelected(_1b0);this._endUpdate();}}},deselect:function(_1b2){if(this.mode=="none"){return;}if(lang.isArray(_1b2)){_1a5.forEach(_1b2,this.deselect,this);return;}_1b2=Number(_1b2);if(this.selectedIndex==_1b2){this.selectedIndex=-1;}if(this.selected[_1b2]){if(this.onCanDeselect(_1b2)===false){return;}var _1b3=this.grid.getRowNode(_1b2);if(_1b3){_1a6.set(_1b3,"aria-selected","false");}this._beginUpdate();delete this.selected[_1b2];this.onDeselected(_1b2);this._endUpdate();}},setSelected:function(_1b4,_1b5){this[(_1b5?"addToSelection":"deselect")](_1b4);},toggleSelect:function(_1b6){if(lang.isArray(_1b6)){_1a5.forEach(_1b6,this.toggleSelect,this);return;}this.setSelected(_1b6,!this.selected[_1b6]);},_range:function(_1b7,inTo,func){var s=(_1b7>=0?_1b7:inTo),e=inTo;if(s>e){e=s;s=inTo;}for(var i=s;i<=e;i++){func(i);}},selectRange:function(_1b8,inTo){this._range(_1b8,inTo,lang.hitch(this,"addToSelection"));},deselectRange:function(_1b9,inTo){this._range(_1b9,inTo,lang.hitch(this,"deselect"));},insert:function(_1ba){this.selected.splice(_1ba,0,false);if(this.selectedIndex>=_1ba){this.selectedIndex++;}},remove:function(_1bb){this.selected.splice(_1bb,1);if(this.selectedIndex>=_1bb){this.selectedIndex--;}},deselectAll:function(_1bc){for(var i in this.selected){if((i!=_1bc)&&(this.selected[i]===true)){this.deselect(i);}}},clickSelect:function(_1bd,_1be,_1bf){if(this.mode=="none"){return;}this._beginUpdate();if(this.mode!="extended"){this.select(_1bd);}else{var _1c0=this.selectedIndex;if(!_1be){this.deselectAll(_1bd);}if(_1bf){this.selectRange(_1c0,_1bd);}else{if(_1be){this.toggleSelect(_1bd);}else{this.addToSelection(_1bd);}}}this._endUpdate();},clickSelectEvent:function(e){this.clickSelect(e.rowIndex,dojo.isCopyKey(e),e.shiftKey);},clear:function(){this._beginUpdate();this.deselectAll();this._endUpdate();}});});},"dijit/_CssStateMixin":function(){define("dijit/_CssStateMixin",["dojo/touch","dojo/_base/array","dojo/_base/declare","dojo/dom-class","dojo/_base/lang","dojo/_base/window"],function(_1c1,_1c2,_1c3,_1c4,lang,win){return _1c3("dijit._CssStateMixin",[],{cssStateNodes:{},hovering:false,active:false,_applyAttributes:function(){this.inherited(arguments);_1c2.forEach(["onmouseenter","onmouseleave",_1c1.press],function(e){this.connect(this.domNode,e,"_cssMouseEvent");},this);_1c2.forEach(["disabled","readOnly","checked","selected","focused","state","hovering","active"],function(attr){this.watch(attr,lang.hitch(this,"_setStateClass"));},this);for(var ap in this.cssStateNodes){this._trackMouseState(this[ap],this.cssStateNodes[ap]);}this._setStateClass();},_cssMouseEvent:function(_1c5){if(!this.disabled){switch(_1c5.type){case "mouseenter":case "mouseover":this._set("hovering",true);this._set("active",this._mouseDown);break;case "mouseleave":case "mouseout":this._set("hovering",false);this._set("active",false);break;case "mousedown":case "touchpress":this._set("active",true);this._mouseDown=true;var _1c6=this.connect(win.body(),_1c1.release,function(){this._mouseDown=false;this._set("active",false);this.disconnect(_1c6);});break;}}},_setStateClass:function(){var _1c7=this.baseClass.split(" ");function _1c8(_1c9){_1c7=_1c7.concat(_1c2.map(_1c7,function(c){return c+_1c9;}),"dijit"+_1c9);};if(!this.isLeftToRight()){_1c8("Rtl");}var _1ca=this.checked=="mixed"?"Mixed":(this.checked?"Checked":"");if(this.checked){_1c8(_1ca);}if(this.state){_1c8(this.state);}if(this.selected){_1c8("Selected");}if(this.disabled){_1c8("Disabled");}else{if(this.readOnly){_1c8("ReadOnly");}else{if(this.active){_1c8("Active");}else{if(this.hovering){_1c8("Hover");}}}}if(this.focused){_1c8("Focused");}var tn=this.stateNode||this.domNode,_1cb={};_1c2.forEach(tn.className.split(" "),function(c){_1cb[c]=true;});if("_stateClasses" in this){_1c2.forEach(this._stateClasses,function(c){delete _1cb[c];});}_1c2.forEach(_1c7,function(c){_1cb[c]=true;});var _1cc=[];for(var c in _1cb){_1cc.push(c);}tn.className=_1cc.join(" ");this._stateClasses=_1c7;},_trackMouseState:function(node,_1cd){var _1ce=false,_1cf=false,_1d0=false;var self=this,cn=lang.hitch(this,"connect",node);function _1d1(){var _1d2=("disabled" in self&&self.disabled)||("readonly" in self&&self.readonly);_1c4.toggle(node,_1cd+"Hover",_1ce&&!_1cf&&!_1d2);_1c4.toggle(node,_1cd+"Active",_1cf&&!_1d2);_1c4.toggle(node,_1cd+"Focused",_1d0&&!_1d2);};cn("onmouseenter",function(){_1ce=true;_1d1();});cn("onmouseleave",function(){_1ce=false;_1cf=false;_1d1();});cn(_1c1.press,function(){_1cf=true;_1d1();});cn(_1c1.release,function(){_1cf=false;_1d1();});cn("onfocus",function(){_1d0=true;_1d1();});cn("onblur",function(){_1d0=false;_1d1();});this.watch("disabled",_1d1);this.watch("readOnly",_1d1);}});});},"url:dojox/grid/resources/_Grid.html":"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n","dojox/grid/_RowManager":function(){define("dojox/grid/_RowManager",["dojo/_base/declare","dojo/_base/lang","dojo/dom-class"],function(_1d3,lang,_1d4){var _1d5=function(_1d6,_1d7){if(_1d6.style.cssText==undefined){_1d6.setAttribute("style",_1d7);}else{_1d6.style.cssText=_1d7;}};return _1d3("dojox.grid._RowManager",null,{constructor:function(_1d8){this.grid=_1d8;},linesToEms:2,overRow:-2,prepareStylingRow:function(_1d9,_1da){return {index:_1d9,node:_1da,odd:Boolean(_1d9&1),selected:!!this.grid.selection.isSelected(_1d9),over:this.isOver(_1d9),customStyles:"",customClasses:"dojoxGridRow"};},styleRowNode:function(_1db,_1dc){var row=this.prepareStylingRow(_1db,_1dc);this.grid.onStyleRow(row);this.applyStyles(row);},applyStyles:function(_1dd){var i=_1dd;i.node.className=i.customClasses;var h=i.node.style.height;_1d5(i.node,i.customStyles+";"+(i.node._style||""));i.node.style.height=h;},updateStyles:function(_1de){this.grid.updateRowStyles(_1de);},setOverRow:function(_1df){var last=this.overRow;this.overRow=_1df;if((last!=this.overRow)&&(lang.isString(last)||last>=0)){this.updateStyles(last);}this.updateStyles(this.overRow);},isOver:function(_1e0){return (this.overRow==_1e0&&!_1d4.contains(this.grid.domNode,"dojoxGridColumnResizing"));}});});},"dojo/_base/url":function(){define(["./kernel"],function(dojo){var ore=new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),ire=new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),_1e1=function(){var n=null,_1e2=arguments,uri=[_1e2[0]];for(var i=1;i<_1e2.length;i++){if(!_1e2[i]){continue;}var _1e3=new _1e1(_1e2[i]+""),_1e4=new _1e1(uri[0]+"");if(_1e3.path==""&&!_1e3.scheme&&!_1e3.authority&&!_1e3.query){if(_1e3.fragment!=n){_1e4.fragment=_1e3.fragment;}_1e3=_1e4;}else{if(!_1e3.scheme){_1e3.scheme=_1e4.scheme;if(!_1e3.authority){_1e3.authority=_1e4.authority;if(_1e3.path.charAt(0)!="/"){var path=_1e4.path.substring(0,_1e4.path.lastIndexOf("/")+1)+_1e3.path;var segs=path.split("/");for(var j=0;j<segs.length;j++){if(segs[j]=="."){if(j==segs.length-1){segs[j]="";}else{segs.splice(j,1);j--;}}else{if(j>0&&!(j==1&&segs[0]=="")&&segs[j]==".."&&segs[j-1]!=".."){if(j==(segs.length-1)){segs.splice(j,1);segs[j-1]="";}else{segs.splice(j-1,2);j-=2;}}}}_1e3.path=segs.join("/");}}}}uri=[];if(_1e3.scheme){uri.push(_1e3.scheme,":");}if(_1e3.authority){uri.push("//",_1e3.authority);}uri.push(_1e3.path);if(_1e3.query){uri.push("?",_1e3.query);}if(_1e3.fragment){uri.push("#",_1e3.fragment);}}this.uri=uri.join("");var r=this.uri.match(ore);this.scheme=r[2]||(r[1]?"":n);this.authority=r[4]||(r[3]?"":n);this.path=r[5];this.query=r[7]||(r[6]?"":n);this.fragment=r[9]||(r[8]?"":n);if(this.authority!=n){r=this.authority.match(ire);this.user=r[3]||n;this.password=r[4]||n;this.host=r[6]||r[7];this.port=r[9]||n;}};_1e1.prototype.toString=function(){return this.uri;};return dojo._Url=_1e1;});},"dojo/string":function(){define(["./_base/kernel","./_base/lang"],function(dojo,lang){lang.getObject("string",true,dojo);dojo.string.rep=function(str,num){if(num<=0||!str){return "";}var buf=[];for(;;){if(num&1){buf.push(str);}if(!(num>>=1)){break;}str+=str;}return buf.join("");};dojo.string.pad=function(text,size,ch,end){if(!ch){ch="0";}var out=String(text),pad=dojo.string.rep(ch,Math.ceil((size-out.length)/ch.length));return end?out+pad:pad+out;};dojo.string.substitute=function(_1e5,map,_1e6,_1e7){_1e7=_1e7||dojo.global;_1e6=_1e6?lang.hitch(_1e7,_1e6):function(v){return v;};return _1e5.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,function(_1e8,key,_1e9){var _1ea=lang.getObject(key,false,map);if(_1e9){_1ea=lang.getObject(_1e9,false,_1e7).call(_1e7,_1ea,key);}return _1e6(_1ea,key).toString();});};dojo.string.trim=String.prototype.trim?lang.trim:function(str){str=str.replace(/^\s+/,"");for(var i=str.length-1;i>=0;i--){if(/\S/.test(str.charAt(i))){str=str.substring(0,i+1);break;}}return str;};return dojo.string;});},"dojo/dnd/Avatar":function(){define(["../main","./common"],function(dojo){dojo.declare("dojo.dnd.Avatar",null,{constructor:function(_1eb){this.manager=_1eb;this.construct();},construct:function(){this.isA11y=dojo.hasClass(dojo.body(),"dijit_a11y");var a=dojo.create("table",{"class":"dojoDndAvatar",style:{position:"absolute",zIndex:"1999",margin:"0px"}}),_1ec=this.manager.source,node,b=dojo.create("tbody",null,a),tr=dojo.create("tr",null,b),td=dojo.create("td",null,tr),icon=this.isA11y?dojo.create("span",{id:"a11yIcon",innerHTML:this.manager.copy?"+":"<"},td):null,span=dojo.create("span",{innerHTML:_1ec.generateText?this._generateText():""},td),k=Math.min(5,this.manager.nodes.length),i=0;dojo.attr(tr,{"class":"dojoDndAvatarHeader",style:{opacity:0.9}});for(;i<k;++i){if(_1ec.creator){node=_1ec._normalizedCreator(_1ec.getItem(this.manager.nodes[i].id).data,"avatar").node;}else{node=this.manager.nodes[i].cloneNode(true);if(node.tagName.toLowerCase()=="tr"){var _1ed=dojo.create("table"),_1ee=dojo.create("tbody",null,_1ed);_1ee.appendChild(node);node=_1ed;}}node.id="";tr=dojo.create("tr",null,b);td=dojo.create("td",null,tr);td.appendChild(node);dojo.attr(tr,{"class":"dojoDndAvatarItem",style:{opacity:(9-i)/10}});}this.node=a;},destroy:function(){dojo.destroy(this.node);this.node=false;},update:function(){dojo[(this.manager.canDropFlag?"add":"remove")+"Class"](this.node,"dojoDndAvatarCanDrop");if(this.isA11y){var icon=dojo.byId("a11yIcon");var text="+";if(this.manager.canDropFlag&&!this.manager.copy){text="< ";}else{if(!this.manager.canDropFlag&&!this.manager.copy){text="o";}else{if(!this.manager.canDropFlag){text="x";}}}icon.innerHTML=text;}dojo.query(("tr.dojoDndAvatarHeader td span"+(this.isA11y?" span":"")),this.node).forEach(function(node){node.innerHTML=this._generateText();},this);},_generateText:function(){return this.manager.nodes.length.toString();}});return dojo.dnd.Avatar;});},"dojox/grid/_Scroller":function(){define("dojox/grid/_Scroller",["dijit/registry","dojo/_base/declare","dojo/_base/lang","./util","dojo/_base/html"],function(_1ef,_1f0,lang,util,html){var _1f1=function(_1f2){var i=0,n,p=_1f2.parentNode;while((n=p.childNodes[i++])){if(n==_1f2){return i-1;}}return -1;};var _1f3=function(_1f4){if(!_1f4){return;}dojo.forEach(_1ef.toArray(),function(w){if(w.domNode&&html.isDescendant(w.domNode,_1f4,true)){w.destroy();}});};var _1f5=function(_1f6){var node=html.byId(_1f6);return (node&&node.tagName?node.tagName.toLowerCase():"");};var _1f7=function(_1f8,_1f9){var _1fa=[];var i=0,n;while((n=_1f8.childNodes[i])){i++;if(_1f5(n)==_1f9){_1fa.push(n);}}return _1fa;};var _1fb=function(_1fc){return _1f7(_1fc,"div");};return _1f0("dojox.grid._Scroller",null,{constructor:function(_1fd){this.setContentNodes(_1fd);this.pageHeights=[];this.pageNodes=[];this.stack=[];},rowCount:0,defaultRowHeight:32,keepRows:100,contentNode:null,scrollboxNode:null,defaultPageHeight:0,keepPages:10,pageCount:0,windowHeight:0,firstVisibleRow:0,lastVisibleRow:0,averageRowHeight:0,page:0,pageTop:0,init:function(_1fe,_1ff,_200){switch(arguments.length){case 3:this.rowsPerPage=_200;case 2:this.keepRows=_1ff;case 1:this.rowCount=_1fe;default:break;}this.defaultPageHeight=this.defaultRowHeight*this.rowsPerPage;this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);this.setKeepInfo(this.keepRows);this.invalidate();if(this.scrollboxNode){this.scrollboxNode.scrollTop=0;this.scroll(0);this.scrollboxNode.onscroll=lang.hitch(this,"onscroll");}},_getPageCount:function(_201,_202){return _201?(Math.ceil(_201/_202)||1):0;},destroy:function(){this.invalidateNodes();delete this.contentNodes;delete this.contentNode;delete this.scrollboxNode;},setKeepInfo:function(_203){this.keepRows=_203;this.keepPages=!this.keepRows?this.keepPages:Math.max(Math.ceil(this.keepRows/this.rowsPerPage),2);},setContentNodes:function(_204){this.contentNodes=_204;this.colCount=(this.contentNodes?this.contentNodes.length:0);this.pageNodes=[];for(var i=0;i<this.colCount;i++){this.pageNodes[i]=[];}},getDefaultNodes:function(){return this.pageNodes[0]||[];},invalidate:function(){this._invalidating=true;this.invalidateNodes();this.pageHeights=[];this.height=(this.pageCount?(this.pageCount-1)*this.defaultPageHeight+this.calcLastPageHeight():0);this.resize();this._invalidating=false;},updateRowCount:function(_205){this.invalidateNodes();this.rowCount=_205;var _206=this.pageCount;if(_206===0){this.height=1;}this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);if(this.pageCount<_206){for(var i=_206-1;i>=this.pageCount;i--){this.height-=this.getPageHeight(i);delete this.pageHeights[i];}}else{if(this.pageCount>_206){this.height+=this.defaultPageHeight*(this.pageCount-_206-1)+this.calcLastPageHeight();}}this.resize();},pageExists:function(_207){return Boolean(this.getDefaultPageNode(_207));},measurePage:function(_208){if(this.grid.rowHeight){var _209=this.grid.rowHeight+1;return ((_208+1)*this.rowsPerPage>this.rowCount?this.rowCount-_208*this.rowsPerPage:this.rowsPerPage)*_209;}var n=this.getDefaultPageNode(_208);return (n&&n.innerHTML)?n.offsetHeight:undefined;},positionPage:function(_20a,_20b){for(var i=0;i<this.colCount;i++){this.pageNodes[i][_20a].style.top=_20b+"px";}},repositionPages:function(_20c){var _20d=this.getDefaultNodes();var last=0;for(var i=0;i<this.stack.length;i++){last=Math.max(this.stack[i],last);}var n=_20d[_20c];var y=(n?this.getPageNodePosition(n)+this.getPageHeight(_20c):0);for(var p=_20c+1;p<=last;p++){n=_20d[p];if(n){if(this.getPageNodePosition(n)==y){return;}this.positionPage(p,y);}y+=this.getPageHeight(p);}},installPage:function(_20e){for(var i=0;i<this.colCount;i++){this.contentNodes[i].appendChild(this.pageNodes[i][_20e]);}},preparePage:function(_20f,_210){var p=(_210?this.popPage():null);for(var i=0;i<this.colCount;i++){var _211=this.pageNodes[i];var _212=(p===null?this.createPageNode():this.invalidatePageNode(p,_211));_212.pageIndex=_20f;_211[_20f]=_212;}},renderPage:function(_213){var _214=[];var i,j;for(i=0;i<this.colCount;i++){_214[i]=this.pageNodes[i][_213];}for(i=0,j=_213*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){this.renderRow(j,_214);}},removePage:function(_215){for(var i=0,j=_215*this.rowsPerPage;i<this.rowsPerPage;i++,j++){this.removeRow(j);}},destroyPage:function(_216){for(var i=0;i<this.colCount;i++){var n=this.invalidatePageNode(_216,this.pageNodes[i]);if(n){html.destroy(n);}}},pacify:function(_217){},pacifying:false,pacifyTicks:200,setPacifying:function(_218){if(this.pacifying!=_218){this.pacifying=_218;this.pacify(this.pacifying);}},startPacify:function(){this.startPacifyTicks=new Date().getTime();},doPacify:function(){var _219=(new Date().getTime()-this.startPacifyTicks)>this.pacifyTicks;this.setPacifying(true);this.startPacify();return _219;},endPacify:function(){this.setPacifying(false);},resize:function(){if(this.scrollboxNode){this.windowHeight=this.scrollboxNode.clientHeight;}for(var i=0;i<this.colCount;i++){util.setStyleHeightPx(this.contentNodes[i],Math.max(1,this.height));}var _21a=(!this._invalidating);if(!_21a){var ah=this.grid.get("autoHeight");if(typeof ah=="number"&&ah<=Math.min(this.rowsPerPage,this.rowCount)){_21a=true;}}if(_21a){this.needPage(this.page,this.pageTop);}var _21b=(this.page<this.pageCount-1)?this.rowsPerPage:((this.rowCount%this.rowsPerPage)||this.rowsPerPage);var _21c=this.getPageHeight(this.page);this.averageRowHeight=(_21c>0&&_21b>0)?(_21c/_21b):0;},calcLastPageHeight:function(){if(!this.pageCount){return 0;}var _21d=this.pageCount-1;var _21e=((this.rowCount%this.rowsPerPage)||(this.rowsPerPage))*this.defaultRowHeight;this.pageHeights[_21d]=_21e;return _21e;},updateContentHeight:function(inDh){this.height+=inDh;this.resize();},updatePageHeight:function(_21f,_220,_221){if(this.pageExists(_21f)){var oh=this.getPageHeight(_21f);var h=(this.measurePage(_21f));if(h===undefined){h=oh;}this.pageHeights[_21f]=h;if(oh!=h){this.updateContentHeight(h-oh);var ah=this.grid.get("autoHeight");if((typeof ah=="number"&&ah>this.rowCount)||(ah===true&&!_220)){if(!_221){this.grid.sizeChange();}else{var ns=this.grid.viewsNode.style;ns.height=parseInt(ns.height)+h-oh+"px";this.repositionPages(_21f);}}else{this.repositionPages(_21f);}}return h;}return 0;},rowHeightChanged:function(_222,_223){this.updatePageHeight(Math.floor(_222/this.rowsPerPage),false,_223);},invalidateNodes:function(){while(this.stack.length){this.destroyPage(this.popPage());}},createPageNode:function(){var p=document.createElement("div");html.attr(p,"role","presentation");p.style.position="absolute";p.style[this.grid.isLeftToRight()?"left":"right"]="0";return p;},getPageHeight:function(_224){var ph=this.pageHeights[_224];return (ph!==undefined?ph:this.defaultPageHeight);},pushPage:function(_225){return this.stack.push(_225);},popPage:function(){return this.stack.shift();},findPage:function(_226){var i=0,h=0;for(var ph=0;i<this.pageCount;i++,h+=ph){ph=this.getPageHeight(i);if(h+ph>=_226){break;}}this.page=i;this.pageTop=h;},buildPage:function(_227,_228,_229){this.preparePage(_227,_228);this.positionPage(_227,_229);this.installPage(_227);this.renderPage(_227);this.pushPage(_227);},needPage:function(_22a,_22b){var h=this.getPageHeight(_22a),oh=h;if(!this.pageExists(_22a)){this.buildPage(_22a,(!this.grid._autoHeight&&this.keepPages&&(this.stack.length>=this.keepPages)),_22b);h=this.updatePageHeight(_22a,true);}else{this.positionPage(_22a,_22b);}return h;},onscroll:function(){this.scroll(this.scrollboxNode.scrollTop);},scroll:function(_22c){this.grid.scrollTop=_22c;if(this.colCount){this.startPacify();this.findPage(_22c);var h=this.height;var b=this.getScrollBottom(_22c);for(var p=this.page,y=this.pageTop;(p<this.pageCount)&&((b<0)||(y<b));p++){y+=this.needPage(p,y);}this.firstVisibleRow=this.getFirstVisibleRow(this.page,this.pageTop,_22c);this.lastVisibleRow=this.getLastVisibleRow(p-1,y,b);if(h!=this.height){this.repositionPages(p-1);}this.endPacify();}},getScrollBottom:function(_22d){return (this.windowHeight>=0?_22d+this.windowHeight:-1);},processNodeEvent:function(e,_22e){var t=e.target;while(t&&(t!=_22e)&&t.parentNode&&(t.parentNode.parentNode!=_22e)){t=t.parentNode;}if(!t||!t.parentNode||(t.parentNode.parentNode!=_22e)){return false;}var page=t.parentNode;e.topRowIndex=page.pageIndex*this.rowsPerPage;e.rowIndex=e.topRowIndex+_1f1(t);e.rowTarget=t;return true;},processEvent:function(e){return this.processNodeEvent(e,this.contentNode);},renderRow:function(_22f,_230){},removeRow:function(_231){},getDefaultPageNode:function(_232){return this.getDefaultNodes()[_232];},positionPageNode:function(_233,_234){},getPageNodePosition:function(_235){return _235.offsetTop;},invalidatePageNode:function(_236,_237){var p=_237[_236];if(p){delete _237[_236];this.removePage(_236,p);_1f3(p);p.innerHTML="";}return p;},getPageRow:function(_238){return _238*this.rowsPerPage;},getLastPageRow:function(_239){return Math.min(this.rowCount,this.getPageRow(_239+1))-1;},getFirstVisibleRow:function(_23a,_23b,_23c){if(!this.pageExists(_23a)){return 0;}var row=this.getPageRow(_23a);var _23d=this.getDefaultNodes();var rows=_1fb(_23d[_23a]);for(var i=0,l=rows.length;i<l&&_23b<_23c;i++,row++){_23b+=rows[i].offsetHeight;}return (row?row-1:row);},getLastVisibleRow:function(_23e,_23f,_240){if(!this.pageExists(_23e)){return 0;}var _241=this.getDefaultNodes();var row=this.getLastPageRow(_23e);var rows=_1fb(_241[_23e]);for(var i=rows.length-1;i>=0&&_23f>_240;i--,row--){_23f-=rows[i].offsetHeight;}return row+1;},findTopRow:function(_242){var _243=this.getDefaultNodes();var rows=_1fb(_243[this.page]);for(var i=0,l=rows.length,t=this.pageTop,h;i<l;i++){h=rows[i].offsetHeight;t+=h;if(t>=_242){this.offset=h-(t-_242);return i+this.page*this.rowsPerPage;}}return -1;},findScrollTop:function(_244){var _245=Math.floor(_244/this.rowsPerPage);var t=0;var i,l;for(i=0;i<_245;i++){t+=this.getPageHeight(i);}this.pageTop=t;this.page=_245;this.needPage(_245,this.pageTop);var _246=this.getDefaultNodes();var rows=_1fb(_246[_245]);var r=_244-this.rowsPerPage*_245;for(i=0,l=rows.length;i<l&&i<r;i++){t+=rows[i].offsetHeight;}return t;},dummy:0});});},"dojox/grid/_Events":function(){define("dojox/grid/_Events",["dojo/keys","dojo/dom-class","dojo/_base/declare","dojo/_base/event","dojo/_base/sniff"],function(keys,_247,_248,_249,has){return _248("dojox.grid._Events",null,{cellOverClass:"dojoxGridCellOver",onKeyEvent:function(e){this.dispatchKeyEvent(e);},onContentEvent:function(e){this.dispatchContentEvent(e);},onHeaderEvent:function(e){this.dispatchHeaderEvent(e);},onStyleRow:function(_24a){var i=_24a;i.customClasses+=(i.odd?" dojoxGridRowOdd":"")+(i.selected?" dojoxGridRowSelected":"")+(i.over?" dojoxGridRowOver":"");this.focus.styleRow(_24a);this.edit.styleRow(_24a);},onKeyDown:function(e){if(e.altKey||e.metaKey){return;}var _24b;switch(e.keyCode){case keys.ESCAPE:this.edit.cancel();break;case keys.ENTER:if(!this.edit.isEditing()){_24b=this.focus.getHeaderIndex();if(_24b>=0){this.setSortIndex(_24b);break;}else{this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);}_249.stop(e);}if(!e.shiftKey){var _24c=this.edit.isEditing();this.edit.apply();if(!_24c){this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);}}if(!this.edit.isEditing()){var _24d=this.focus.focusView||this.views.views[0];_24d.content.decorateEvent(e);this.onRowClick(e);_249.stop(e);}break;case keys.SPACE:if(!this.edit.isEditing()){_24b=this.focus.getHeaderIndex();if(_24b>=0){this.setSortIndex(_24b);break;}else{this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);}_249.stop(e);}break;case keys.TAB:this.focus[e.shiftKey?"previousKey":"nextKey"](e);break;case keys.LEFT_ARROW:case keys.RIGHT_ARROW:if(!this.edit.isEditing()){var _24e=e.keyCode;_249.stop(e);_24b=this.focus.getHeaderIndex();if(_24b>=0&&(e.shiftKey&&e.ctrlKey)){this.focus.colSizeAdjust(e,_24b,(_24e==keys.LEFT_ARROW?-1:1)*5);}else{var _24f=(_24e==keys.LEFT_ARROW)?1:-1;if(this.isLeftToRight()){_24f*=-1;}this.focus.move(0,_24f);}}break;case keys.UP_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){_249.stop(e);this.focus.move(-1,0);}break;case keys.DOWN_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){_249.stop(e);this.focus.move(1,0);}break;case keys.PAGE_UP:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){_249.stop(e);if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);}}break;case keys.PAGE_DOWN:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){_249.stop(e);if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);}}break;default:break;}},onMouseOver:function(e){e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);},onMouseOut:function(e){e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);},onMouseDown:function(e){e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);},onMouseOverRow:function(e){if(!this.rows.isOver(e.rowIndex)){this.rows.setOverRow(e.rowIndex);e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);}},onMouseOutRow:function(e){if(this.rows.isOver(-1)){this.onHeaderMouseOut(e);}else{if(!this.rows.isOver(-2)){this.rows.setOverRow(-2);this.onRowMouseOut(e);}}},onMouseDownRow:function(e){if(e.rowIndex!=-1){this.onRowMouseDown(e);}},onCellMouseOver:function(e){if(e.cellNode){_247.add(e.cellNode,this.cellOverClass);}},onCellMouseOut:function(e){if(e.cellNode){_247.remove(e.cellNode,this.cellOverClass);}},onCellMouseDown:function(e){},onCellClick:function(e){this._click[0]=this._click[1];this._click[1]=e;if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){this.focus.setFocusCell(e.cell,e.rowIndex);}if(this._click.length>1&&this._click[0]==null){this._click.shift();}this.onRowClick(e);},onCellDblClick:function(e){var _250;if(this._click.length>1&&has("ie")){_250=this._click[1];}else{if(this._click.length>1&&this._click[0].rowIndex!=this._click[1].rowIndex){_250=this._click[0];}else{_250=e;}}this.focus.setFocusCell(_250.cell,_250.rowIndex);this.onRowClick(_250);this.edit.setEditCell(_250.cell,_250.rowIndex);this.onRowDblClick(e);},onCellContextMenu:function(e){this.onRowContextMenu(e);},onCellFocus:function(_251,_252){this.edit.cellFocus(_251,_252);},onRowClick:function(e){this.edit.rowClick(e);this.selection.clickSelectEvent(e);},onRowDblClick:function(e){},onRowMouseOver:function(e){},onRowMouseOut:function(e){},onRowMouseDown:function(e){},onRowContextMenu:function(e){_249.stop(e);},onHeaderMouseOver:function(e){},onHeaderMouseOut:function(e){},onHeaderCellMouseOver:function(e){if(e.cellNode){_247.add(e.cellNode,this.cellOverClass);}},onHeaderCellMouseOut:function(e){if(e.cellNode){_247.remove(e.cellNode,this.cellOverClass);}},onHeaderCellMouseDown:function(e){},onHeaderClick:function(e){},onHeaderCellClick:function(e){this.setSortIndex(e.cell.index);this.onHeaderClick(e);},onHeaderDblClick:function(e){},onHeaderCellDblClick:function(e){this.onHeaderDblClick(e);},onHeaderCellContextMenu:function(e){this.onHeaderContextMenu(e);},onHeaderContextMenu:function(e){if(!this.headerMenu){_249.stop(e);}},onStartEdit:function(_253,_254){},onApplyCellEdit:function(_255,_256,_257){},onCancelEdit:function(_258){},onApplyEdit:function(_259){},onCanSelect:function(_25a){return true;},onCanDeselect:function(_25b){return true;},onSelected:function(_25c){this.updateRowStyles(_25c);},onDeselected:function(_25d){this.updateRowStyles(_25d);},onSelectionChanged:function(){}});});},"dojo/dnd/autoscroll":function(){define(["../main","../window"],function(dojo){dojo.getObject("dnd",true,dojo);dojo.dnd.getViewport=dojo.window.getBox;dojo.dnd.V_TRIGGER_AUTOSCROLL=32;dojo.dnd.H_TRIGGER_AUTOSCROLL=32;dojo.dnd.V_AUTOSCROLL_VALUE=16;dojo.dnd.H_AUTOSCROLL_VALUE=16;dojo.dnd.autoScroll=function(e){var v=dojo.window.getBox(),dx=0,dy=0;if(e.clientX<dojo.dnd.H_TRIGGER_AUTOSCROLL){dx=-dojo.dnd.H_AUTOSCROLL_VALUE;}else{if(e.clientX>v.w-dojo.dnd.H_TRIGGER_AUTOSCROLL){dx=dojo.dnd.H_AUTOSCROLL_VALUE;}}if(e.clientY<dojo.dnd.V_TRIGGER_AUTOSCROLL){dy=-dojo.dnd.V_AUTOSCROLL_VALUE;}else{if(e.clientY>v.h-dojo.dnd.V_TRIGGER_AUTOSCROLL){dy=dojo.dnd.V_AUTOSCROLL_VALUE;}}window.scrollBy(dx,dy);};dojo.dnd._validNodes={"div":1,"p":1,"td":1};dojo.dnd._validOverflow={"auto":1,"scroll":1};dojo.dnd.autoScrollNodes=function(e){var b,t,w,h,rx,ry,dx=0,dy=0,_25e,_25f;for(var n=e.target;n;){if(n.nodeType==1&&(n.tagName.toLowerCase() in dojo.dnd._validNodes)){var s=dojo.getComputedStyle(n),_260=(s.overflow.toLowerCase() in dojo.dnd._validOverflow),_261=(s.overflowX.toLowerCase() in dojo.dnd._validOverflow),_262=(s.overflowY.toLowerCase() in dojo.dnd._validOverflow);if(_260||_261||_262){b=dojo._getContentBox(n,s);t=dojo.position(n,true);}if(_260||_261){w=Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL,b.w/2);rx=e.pageX-t.x;if(dojo.isWebKit||dojo.isOpera){rx+=dojo.body().scrollLeft;}dx=0;if(rx>0&&rx<b.w){if(rx<w){dx=-w;}else{if(rx>b.w-w){dx=w;}}_25e=n.scrollLeft;n.scrollLeft=n.scrollLeft+dx;}}if(_260||_262){h=Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL,b.h/2);ry=e.pageY-t.y;if(dojo.isWebKit||dojo.isOpera){ry+=dojo.body().scrollTop;}dy=0;if(ry>0&&ry<b.h){if(ry<h){dy=-h;}else{if(ry>b.h-h){dy=h;}}_25f=n.scrollTop;n.scrollTop=n.scrollTop+dy;}}if(dx||dy){return;}}try{n=n.parentNode;}catch(x){n=null;}}dojo.dnd.autoScroll(e);};return dojo.dnd;});},"dijit/registry":function(){define("dijit/registry",["dojo/_base/array","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window","."],function(_263,has,_264,win,_265){var _266={},hash={};var _267={length:0,add:function(_268){if(hash[_268.id]){throw new Error("Tried to register widget with id=="+_268.id+" but that id is already registered");}hash[_268.id]=_268;this.length++;},remove:function(id){if(hash[id]){delete hash[id];this.length--;}},byId:function(id){return typeof id=="string"?hash[id]:id;},byNode:function(node){return hash[node.getAttribute("widgetId")];},toArray:function(){var ar=[];for(var id in hash){ar.push(hash[id]);}return ar;},getUniqueId:function(_269){var id;do{id=_269+"_"+(_269 in _266?++_266[_269]:_266[_269]=0);}while(hash[id]);return _265._scopeName=="dijit"?id:_265._scopeName+"_"+id;},findWidgets:function(root){var _26a=[];function _26b(root){for(var node=root.firstChild;node;node=node.nextSibling){if(node.nodeType==1){var _26c=node.getAttribute("widgetId");if(_26c){var _26d=hash[_26c];if(_26d){_26a.push(_26d);}}else{_26b(node);}}}};_26b(root);return _26a;},_destroyAll:function(){_265._curFocus=null;_265._prevFocus=null;_265._activeStack=[];_263.forEach(_267.findWidgets(win.body()),function(_26e){if(!_26e._destroyed){if(_26e.destroyRecursive){_26e.destroyRecursive();}else{if(_26e.destroy){_26e.destroy();}}}});},getEnclosingWidget:function(node){while(node){var id=node.getAttribute&&node.getAttribute("widgetId");if(id){return hash[id];}node=node.parentNode;}return null;},_hash:hash};if(has("ie")){_264.addOnWindowUnload(function(){_267._destroyAll();});}_265.registry=_267;return _267;});},"dijit/_base/manager":function(){define("dijit/_base/manager",["dojo/_base/array","dojo/_base/config","../registry",".."],function(_26f,_270,_271,_272){_26f.forEach(["byId","getUniqueId","findWidgets","_destroyAll","byNode","getEnclosingWidget"],function(name){_272[name]=_271[name];});_272.defaultDuration=_270["defaultDuration"]||200;return _272;});},"dojox/html/metrics":function(){define("dojox/html/metrics",["dojo/_base/kernel","dojo/_base/lang","dojo/_base/sniff","dojo/ready","dojo/_base/unload","dojo/_base/window","dojo/dom-geometry"],function(_273,lang,has,_274,_275,_276,_277){var dhm=lang.getObject("dojox.html.metrics",true);var _278=lang.getObject("dojox");dhm.getFontMeasurements=function(){var _279={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};if(has("ie")){_276.doc.documentElement.style.fontSize="100%";}var div=_276.doc.createElement("div");var ds=div.style;ds.position="absolute";ds.left="-100px";ds.top="0";ds.width="30px";ds.height="1000em";ds.borderWidth="0";ds.margin="0";ds.padding="0";ds.outline="0";ds.lineHeight="1";ds.overflow="hidden";_276.body().appendChild(div);for(var p in _279){ds.fontSize=p;_279[p]=Math.round(div.offsetHeight*12/16)*16/12/1000;}_276.body().removeChild(div);div=null;return _279;};var _27a=null;dhm.getCachedFontMeasurements=function(_27b){if(_27b||!_27a){_27a=dhm.getFontMeasurements();}return _27a;};var _27c=null,_27d={};dhm.getTextBox=function(text,_27e,_27f){var m,s;if(!_27c){m=_27c=_276.doc.createElement("div");var c=_276.doc.createElement("div");c.appendChild(m);s=c.style;s.overflow="scroll";s.position="absolute";s.left="0px";s.top="-10000px";s.width="1px";s.height="1px";s.visibility="hidden";s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";_276.body().appendChild(c);}else{m=_27c;}m.className="";s=m.style;s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";if(arguments.length>1&&_27e){for(var i in _27e){if(i in _27d){continue;}s[i]=_27e[i];}}if(arguments.length>2&&_27f){m.className=_27f;}m.innerHTML=text;var box=_277.position(m);box.w=m.parentNode.scrollWidth;return box;};var _280={w:16,h:16};dhm.getScrollbar=function(){return {w:_280.w,h:_280.h};};dhm._fontResizeNode=null;dhm.initOnFontResize=function(_281){var f=dhm._fontResizeNode=_276.doc.createElement("iframe");var fs=f.style;fs.position="absolute";fs.width="5em";fs.height="10em";fs.top="-10000px";if(has("ie")){f.onreadystatechange=function(){if(f.contentWindow.document.readyState=="complete"){f.onresize=f.contentWindow.parent[_278._scopeName].html.metrics._fontresize;}};}else{f.onload=function(){f.contentWindow.onresize=f.contentWindow.parent[_278._scopeName].html.metrics._fontresize;};}f.setAttribute("src","javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");_276.body().appendChild(f);dhm.initOnFontResize=function(){};};dhm.onFontResize=function(){};dhm._fontresize=function(){dhm.onFontResize();};_275.addOnUnload(function(){var f=dhm._fontResizeNode;if(f){if(has("ie")&&f.onresize){f.onresize=null;}else{if(f.contentWindow&&f.contentWindow.onresize){f.contentWindow.onresize=null;}}dhm._fontResizeNode=null;}});_274(function(){try{var n=_276.doc.createElement("div");n.style.cssText="top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";_276.body().appendChild(n);_280.w=n.offsetWidth-n.clientWidth;_280.h=n.offsetHeight-n.clientHeight;_276.body().removeChild(n);delete n;}catch(e){}if("fontSizeWatch" in _273.config&&!!_273.config.fontSizeWatch){dhm.initOnFontResize();}});return dhm;});},"dojox/grid/_EditManager":function(){define("dojox/grid/_EditManager",["dojo/_base/lang","dojo/_base/array","dojo/_base/declare","dojo/_base/connect","dojo/_base/sniff","./util"],function(lang,_282,_283,_284,has,util){return _283("dojox.grid._EditManager",null,{constructor:function(_285){this.grid=_285;if(has("ie")){this.connections=[_284.connect(document.body,"onfocus",lang.hitch(this,"_boomerangFocus"))];}else{this.connections=[_284.connect(this.grid,"onBlur",this,"apply")];}},info:{},destroy:function(){_282.forEach(this.connections,_284.disconnect);},cellFocus:function(_286,_287){if(this.grid.singleClickEdit||this.isEditRow(_287)){this.setEditCell(_286,_287);}else{this.apply();}if(this.isEditing()||(_286&&_286.editable&&_286.alwaysEditing)){this._focusEditor(_286,_287);}},rowClick:function(e){if(this.isEditing()&&!this.isEditRow(e.rowIndex)){this.apply();}},styleRow:function(_288){if(_288.index==this.info.rowIndex){_288.customClasses+=" dojoxGridRowEditing";}},dispatchEvent:function(e){var c=e.cell,ed=(c&&c["editable"])?c:0;return ed&&ed.dispatchEvent(e.dispatch,e);},isEditing:function(){return this.info.rowIndex!==undefined;},isEditCell:function(_289,_28a){return (this.info.rowIndex===_289)&&(this.info.cell.index==_28a);},isEditRow:function(_28b){return this.info.rowIndex===_28b;},setEditCell:function(_28c,_28d){if(!this.isEditCell(_28d,_28c.index)&&this.grid.canEdit&&this.grid.canEdit(_28c,_28d)){this.start(_28c,_28d,this.isEditRow(_28d)||_28c.editable);}},_focusEditor:function(_28e,_28f){util.fire(_28e,"focus",[_28f]);},focusEditor:function(){if(this.isEditing()){this._focusEditor(this.info.cell,this.info.rowIndex);}},_boomerangWindow:500,_shouldCatchBoomerang:function(){return this._catchBoomerang>new Date().getTime();},_boomerangFocus:function(){if(this._shouldCatchBoomerang()){this.grid.focus.focusGrid();this.focusEditor();this._catchBoomerang=0;}},_doCatchBoomerang:function(){if(has("ie")){this._catchBoomerang=new Date().getTime()+this._boomerangWindow;}},start:function(_290,_291,_292){if(!this._isValidInput()){return;}this.grid.beginUpdate();this.editorApply();if(this.isEditing()&&!this.isEditRow(_291)){this.applyRowEdit();this.grid.updateRow(_291);}if(_292){this.info={cell:_290,rowIndex:_291};this.grid.doStartEdit(_290,_291);this.grid.updateRow(_291);}else{this.info={};}this.grid.endUpdate();this.grid.focus.focusGrid();this._focusEditor(_290,_291);this._doCatchBoomerang();},_editorDo:function(_293){var c=this.info.cell;if(c&&c.editable){c[_293](this.info.rowIndex);}},editorApply:function(){this._editorDo("apply");},editorCancel:function(){this._editorDo("cancel");},applyCellEdit:function(_294,_295,_296){if(this.grid.canEdit(_295,_296)){this.grid.doApplyCellEdit(_294,_296,_295.field);}},applyRowEdit:function(){this.grid.doApplyEdit(this.info.rowIndex,this.info.cell.field);},apply:function(){if(this.isEditing()&&this._isValidInput()){this.grid.beginUpdate();this.editorApply();this.applyRowEdit();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},cancel:function(){if(this.isEditing()){this.grid.beginUpdate();this.editorCancel();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},save:function(_297,_298){var c=this.info.cell;if(this.isEditRow(_297)&&(!_298||c.view==_298)&&c.editable){c.save(c,this.info.rowIndex);}},restore:function(_299,_29a){var c=this.info.cell;if(this.isEditRow(_29a)&&c.view==_299&&c.editable){c.restore(this.info.rowIndex);}},_isValidInput:function(){var w=(this.info.cell||{}).widget;if(!w||!w.isValid){return true;}w.focused=true;return w.isValid(true);}});});},"dijit/a11y":function(){define("dijit/a11y",["dojo/_base/array","dojo/_base/config","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-style","dojo/_base/sniff","./_base/manager","."],function(_29b,_29c,_29d,dom,_29e,_29f,has,_2a0,_2a1){var _2a2=(_2a1._isElementShown=function(elem){var s=_29f.get(elem);return (s.visibility!="hidden")&&(s.visibility!="collapsed")&&(s.display!="none")&&(_29e.get(elem,"type")!="hidden");});_2a1.hasDefaultTabStop=function(elem){switch(elem.nodeName.toLowerCase()){case "a":return _29e.has(elem,"href");case "area":case "button":case "input":case "object":case "select":case "textarea":return true;case "iframe":var body;try{var _2a3=elem.contentDocument;if("designMode" in _2a3&&_2a3.designMode=="on"){return true;}body=_2a3.body;}catch(e1){try{body=elem.contentWindow.document.body;}catch(e2){return false;}}return body&&(body.contentEditable=="true"||(body.firstChild&&body.firstChild.contentEditable=="true"));default:return elem.contentEditable=="true";}};var _2a4=(_2a1.isTabNavigable=function(elem){if(_29e.get(elem,"disabled")){return false;}else{if(_29e.has(elem,"tabIndex")){return _29e.get(elem,"tabIndex")>=0;}else{return _2a1.hasDefaultTabStop(elem);}}});_2a1._getTabNavigable=function(root){var _2a5,last,_2a6,_2a7,_2a8,_2a9,_2aa={};function _2ab(node){return node&&node.tagName.toLowerCase()=="input"&&node.type&&node.type.toLowerCase()=="radio"&&node.name&&node.name.toLowerCase();};var _2ac=function(_2ad){for(var _2ae=_2ad.firstChild;_2ae;_2ae=_2ae.nextSibling){if(_2ae.nodeType!=1||(has("ie")&&_2ae.scopeName!=="HTML")||!_2a2(_2ae)){continue;}if(_2a4(_2ae)){var _2af=_29e.get(_2ae,"tabIndex");if(!_29e.has(_2ae,"tabIndex")||_2af==0){if(!_2a5){_2a5=_2ae;}last=_2ae;}else{if(_2af>0){if(!_2a6||_2af<_2a7){_2a7=_2af;_2a6=_2ae;}if(!_2a8||_2af>=_2a9){_2a9=_2af;_2a8=_2ae;}}}var rn=_2ab(_2ae);if(_29e.get(_2ae,"checked")&&rn){_2aa[rn]=_2ae;}}if(_2ae.nodeName.toUpperCase()!="SELECT"){_2ac(_2ae);}}};if(_2a2(root)){_2ac(root);}function rs(node){return _2aa[_2ab(node)]||node;};return {first:rs(_2a5),last:rs(last),lowest:rs(_2a6),highest:rs(_2a8)};};_2a1.getFirstInTabbingOrder=function(root){var _2b0=_2a1._getTabNavigable(dom.byId(root));return _2b0.lowest?_2b0.lowest:_2b0.first;};_2a1.getLastInTabbingOrder=function(root){var _2b1=_2a1._getTabNavigable(dom.byId(root));return _2b1.last?_2b1.last:_2b1.highest;};return {hasDefaultTabStop:_2a1.hasDefaultTabStop,isTabNavigable:_2a1.isTabNavigable,_getTabNavigable:_2a1._getTabNavigable,getFirstInTabbingOrder:_2a1.getFirstInTabbingOrder,getLastInTabbingOrder:_2a1.getLastInTabbingOrder};});},"dijit/CheckedMenuItem":function(){require({cache:{"url:dijit/templates/CheckedMenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\"> </td>\n</tr>\n"}});define("dijit/CheckedMenuItem",["dojo/_base/declare","dojo/dom-class","./MenuItem","dojo/text!./templates/CheckedMenuItem.html","./hccss"],function(_2b2,_2b3,_2b4,_2b5){return _2b2("dijit.CheckedMenuItem",_2b4,{templateString:_2b5,checked:false,_setCheckedAttr:function(_2b6){_2b3.toggle(this.domNode,"dijitCheckedMenuItemChecked",_2b6);this.domNode.setAttribute("aria-checked",_2b6);this._set("checked",_2b6);},iconClass:"",onChange:function(){},_onClick:function(e){if(!this.disabled){this.set("checked",!this.checked);this.onChange(this.checked);}this.inherited(arguments);}});});},"dojo/dnd/Container":function(){define(["../main","../Evented","./common","../parser"],function(dojo,_2b7){dojo.declare("dojo.dnd.Container",_2b7,{skipForm:false,constructor:function(node,_2b8){this.node=dojo.byId(node);if(!_2b8){_2b8={};}this.creator=_2b8.creator||null;this.skipForm=_2b8.skipForm;this.parent=_2b8.dropParent&&dojo.byId(_2b8.dropParent);this.map={};this.current=null;this.containerState="";dojo.addClass(this.node,"dojoDndContainer");if(!(_2b8&&_2b8._skipStartup)){this.startup();}this.events=[dojo.connect(this.node,"onmouseover",this,"onMouseOver"),dojo.connect(this.node,"onmouseout",this,"onMouseOut"),dojo.connect(this.node,"ondragstart",this,"onSelectStart"),dojo.connect(this.node,"onselectstart",this,"onSelectStart")];},creator:function(){},getItem:function(key){return this.map[key];},setItem:function(key,data){this.map[key]=data;},delItem:function(key){delete this.map[key];},forInItems:function(f,o){o=o||dojo.global;var m=this.map,e=dojo.dnd._empty;for(var i in m){if(i in e){continue;}f.call(o,m[i],i,this);}return o;},clearItems:function(){this.map={};},getAllNodes:function(){return dojo.query("> .dojoDndItem",this.parent);},sync:function(){var map={};this.getAllNodes().forEach(function(node){if(node.id){var item=this.getItem(node.id);if(item){map[node.id]=item;return;}}else{node.id=dojo.dnd.getUniqueId();}var type=node.getAttribute("dndType"),data=node.getAttribute("dndData");map[node.id]={data:data||node.innerHTML,type:type?type.split(/\s*,\s*/):["text"]};},this);this.map=map;return this;},insertNodes:function(data,_2b9,_2ba){if(!this.parent.firstChild){_2ba=null;}else{if(_2b9){if(!_2ba){_2ba=this.parent.firstChild;}}else{if(_2ba){_2ba=_2ba.nextSibling;}}}if(_2ba){for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.insertBefore(t.node,_2ba);}}else{for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.appendChild(t.node);}}return this;},destroy:function(){dojo.forEach(this.events,dojo.disconnect);this.clearItems();this.node=this.parent=this.current=null;},markupFactory:function(_2bb,node,ctor){_2bb._skipStartup=true;return new ctor(node,_2bb);},startup:function(){if(!this.parent){this.parent=this.node;if(this.parent.tagName.toLowerCase()=="table"){var c=this.parent.getElementsByTagName("tbody");if(c&&c.length){this.parent=c[0];}}}this.defaultCreator=dojo.dnd._defaultCreator(this.parent);this.sync();},onMouseOver:function(e){var n=e.relatedTarget;while(n){if(n==this.node){break;}try{n=n.parentNode;}catch(x){n=null;}}if(!n){this._changeState("Container","Over");this.onOverEvent();}n=this._getChildByEvent(e);if(this.current==n){return;}if(this.current){this._removeItemClass(this.current,"Over");}if(n){this._addItemClass(n,"Over");}this.current=n;},onMouseOut:function(e){for(var n=e.relatedTarget;n;){if(n==this.node){return;}try{n=n.parentNode;}catch(x){n=null;}}if(this.current){this._removeItemClass(this.current,"Over");this.current=null;}this._changeState("Container","");this.onOutEvent();},onSelectStart:function(e){if(!this.skipForm||!dojo.dnd.isFormElement(e)){dojo.stopEvent(e);}},onOverEvent:function(){},onOutEvent:function(){},_changeState:function(type,_2bc){var _2bd="dojoDnd"+type;var _2be=type.toLowerCase()+"State";dojo.replaceClass(this.node,_2bd+_2bc,_2bd+this[_2be]);this[_2be]=_2bc;},_addItemClass:function(node,type){dojo.addClass(node,"dojoDndItem"+type);},_removeItemClass:function(node,type){dojo.removeClass(node,"dojoDndItem"+type);},_getChildByEvent:function(e){var node=e.target;if(node){for(var _2bf=node.parentNode;_2bf;node=_2bf,_2bf=node.parentNode){if(_2bf==this.parent&&dojo.hasClass(node,"dojoDndItem")){return node;}}}return null;},_normalizedCreator:function(item,hint){var t=(this.creator||this.defaultCreator).call(this,item,hint);if(!dojo.isArray(t.type)){t.type=["text"];}if(!t.node.id){t.node.id=dojo.dnd.getUniqueId();}dojo.addClass(t.node,"dojoDndItem");return t;}});dojo.dnd._createNode=function(tag){if(!tag){return dojo.dnd._createSpan;}return function(text){return dojo.create(tag,{innerHTML:text});};};dojo.dnd._createTrTd=function(text){var tr=dojo.create("tr");dojo.create("td",{innerHTML:text},tr);return tr;};dojo.dnd._createSpan=function(text){return dojo.create("span",{innerHTML:text});};dojo.dnd._defaultCreatorNodes={ul:"li",ol:"li",div:"div",p:"div"};dojo.dnd._defaultCreator=function(node){var tag=node.tagName.toLowerCase();var c=tag=="tbody"||tag=="thead"?dojo.dnd._createTrTd:dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);return function(item,hint){var _2c0=item&&dojo.isObject(item),data,type,n;if(_2c0&&item.tagName&&item.nodeType&&item.getAttribute){data=item.getAttribute("dndData")||item.innerHTML;type=item.getAttribute("dndType");type=type?type.split(/\s*,\s*/):["text"];n=item;}else{data=(_2c0&&item.data)?item.data:item;type=(_2c0&&item.type)?item.type:["text"];n=(hint=="avatar"?dojo.dnd._createSpan:c)(String(data));}if(!n.id){n.id=dojo.dnd.getUniqueId();}return {node:n,data:data,type:type};};};return dojo.dnd.Container;});},"dojo/dnd/common":function(){define(["../main"],function(dojo){dojo.getObject("dnd",true,dojo);dojo.dnd.getCopyKeyState=dojo.isCopyKey;dojo.dnd._uniqueId=0;dojo.dnd.getUniqueId=function(){var id;do{id=dojo._scopeName+"Unique"+(++dojo.dnd._uniqueId);}while(dojo.byId(id));return id;};dojo.dnd._empty={};dojo.dnd.isFormElement=function(e){var t=e.target;if(t.nodeType==3){t=t.parentNode;}return " button textarea input select option ".indexOf(" "+t.tagName.toLowerCase()+" ")>=0;};return dojo.dnd;});},"dojox/grid/_ViewManager":function(){define("dojox/grid/_ViewManager",["dojo/_base/declare","dojo/_base/sniff","dojo/dom-class"],function(_2c1,has,_2c2){return _2c1("dojox.grid._ViewManager",null,{constructor:function(_2c3){this.grid=_2c3;},defaultWidth:200,views:[],resize:function(){this.onEach("resize");},render:function(){this.onEach("render");},addView:function(_2c4){_2c4.idx=this.views.length;this.views.push(_2c4);},destroyViews:function(){for(var i=0,v;v=this.views[i];i++){v.destroy();}this.views=[];},getContentNodes:function(){var _2c5=[];for(var i=0,v;v=this.views[i];i++){_2c5.push(v.contentNode);}return _2c5;},forEach:function(_2c6){for(var i=0,v;v=this.views[i];i++){_2c6(v,i);}},onEach:function(_2c7,_2c8){_2c8=_2c8||[];for(var i=0,v;v=this.views[i];i++){if(_2c7 in v){v[_2c7].apply(v,_2c8);}}},normalizeHeaderNodeHeight:function(){var _2c9=[];for(var i=0,v;(v=this.views[i]);i++){if(v.headerContentNode.firstChild){_2c9.push(v.headerContentNode);}}this.normalizeRowNodeHeights(_2c9);},normalizeRowNodeHeights:function(_2ca){var h=0;var _2cb=[];if(this.grid.rowHeight){h=this.grid.rowHeight;}else{if(_2ca.length<=1){return;}for(var i=0,n;(n=_2ca[i]);i++){if(!_2c2.contains(n,"dojoxGridNonNormalizedCell")){_2cb[i]=n.firstChild.offsetHeight;h=Math.max(h,_2cb[i]);}}h=(h>=0?h:0);if((has("mozilla")||has("ie")>8)&&h){h++;}}for(i=0;(n=_2ca[i]);i++){if(_2cb[i]!=h){n.firstChild.style.height=h+"px";}}},resetHeaderNodeHeight:function(){for(var i=0,v,n;(v=this.views[i]);i++){n=v.headerContentNode.firstChild;if(n){n.style.height="";}}},renormalizeRow:function(_2cc){var _2cd=[];for(var i=0,v,n;(v=this.views[i])&&(n=v.getRowNode(_2cc));i++){n.firstChild.style.height="";_2cd.push(n);}this.normalizeRowNodeHeights(_2cd);},getViewWidth:function(_2ce){return this.views[_2ce].getWidth()||this.defaultWidth;},measureHeader:function(){this.resetHeaderNodeHeight();this.forEach(function(_2cf){_2cf.headerContentNode.style.height="";});var h=0;this.forEach(function(_2d0){h=Math.max(_2d0.headerNode.offsetHeight,h);});return h;},measureContent:function(){var h=0;this.forEach(function(_2d1){h=Math.max(_2d1.domNode.offsetHeight,h);});return h;},findClient:function(_2d2){var c=this.grid.elasticView||-1;if(c<0){for(var i=1,v;(v=this.views[i]);i++){if(v.viewWidth){for(i=1;(v=this.views[i]);i++){if(!v.viewWidth){c=i;break;}}break;}}}if(c<0){c=Math.floor(this.views.length/2);}return c;},arrange:function(l,w){var i,v,vw,len=this.views.length,self=this;var c=(w<=0?len:this.findClient());var _2d3=function(v,l){var ds=v.domNode.style;var hs=v.headerNode.style;if(!self.grid.isLeftToRight()){ds.right=l+"px";if(has("ff")<4||has("webkit")){hs.right=l+v.getScrollbarWidth()+"px";hs.width=parseInt(hs.width,10)-v.getScrollbarWidth()+"px";}else{hs.right=l+"px";}}else{ds.left=l+"px";hs.left=l+"px";}ds.top=0+"px";hs.top=0;};for(i=0;(v=this.views[i])&&(i<c);i++){vw=this.getViewWidth(i);v.setSize(vw,0);_2d3(v,l);if(v.headerContentNode&&v.headerContentNode.firstChild){vw=v.getColumnsWidth()+v.getScrollbarWidth();}else{vw=v.domNode.offsetWidth;}l+=vw;}i++;var r=w;for(var j=len-1;(v=this.views[j])&&(i<=j);j--){vw=this.getViewWidth(j);v.setSize(vw,0);vw=v.domNode.offsetWidth;r-=vw;_2d3(v,r);}if(c<len){v=this.views[c];vw=Math.max(1,r-l);v.setSize(vw+"px",0);_2d3(v,l);}return l;},renderRow:function(_2d4,_2d5,_2d6){var _2d7=[];for(var i=0,v,n,_2d8;(v=this.views[i])&&(n=_2d5[i]);i++){_2d8=v.renderRow(_2d4);n.appendChild(_2d8);_2d7.push(_2d8);}if(!_2d6){this.normalizeRowNodeHeights(_2d7);}},rowRemoved:function(_2d9){this.onEach("rowRemoved",[_2d9]);},updateRow:function(_2da,_2db){for(var i=0,v;v=this.views[i];i++){v.updateRow(_2da);}if(!_2db){this.renormalizeRow(_2da);}},updateRowStyles:function(_2dc){this.onEach("updateRowStyles",[_2dc]);},setScrollTop:function(_2dd){var top=_2dd;for(var i=0,v;v=this.views[i];i++){top=v.setScrollTop(_2dd);if(has("ie")&&v.headerNode&&v.scrollboxNode){v.headerNode.scrollLeft=v.scrollboxNode.scrollLeft;}}return top;},getFirstScrollingView:function(){for(var i=0,v;(v=this.views[i]);i++){if(v.hasHScrollbar()||v.hasVScrollbar()){return v;}}return null;}});});},"dojox/grid/cells":function(){define("dojox/grid/cells",["../main","./cells/_base"],function(_2de){return _2de.grid.cells;});},"dijit/_Widget":function(){define("dijit/_Widget",["dojo/aspect","dojo/_base/config","dojo/_base/connect","dojo/_base/declare","dojo/_base/kernel","dojo/_base/lang","dojo/query","dojo/ready","./registry","./_WidgetBase","./_OnDijitClickMixin","./_FocusMixin","dojo/uacss","./hccss"],function(_2df,_2e0,_2e1,_2e2,_2e3,lang,_2e4,_2e5,_2e6,_2e7,_2e8,_2e9){function _2ea(){};function _2eb(_2ec){return function(obj,_2ed,_2ee,_2ef){if(obj&&typeof _2ed=="string"&&obj[_2ed]==_2ea){return obj.on(_2ed.substring(2).toLowerCase(),lang.hitch(_2ee,_2ef));}return _2ec.apply(_2e1,arguments);};};_2df.around(_2e1,"connect",_2eb);if(_2e3.connect){_2df.around(_2e3,"connect",_2eb);}var _2f0=_2e2("dijit._Widget",[_2e7,_2e8,_2e9],{onClick:_2ea,onDblClick:_2ea,onKeyDown:_2ea,onKeyPress:_2ea,onKeyUp:_2ea,onMouseDown:_2ea,onMouseMove:_2ea,onMouseOut:_2ea,onMouseOver:_2ea,onMouseLeave:_2ea,onMouseEnter:_2ea,onMouseUp:_2ea,constructor:function(_2f1){this._toConnect={};for(var name in _2f1){if(this[name]===_2ea){this._toConnect[name.replace(/^on/,"").toLowerCase()]=_2f1[name];delete _2f1[name];}}},postCreate:function(){this.inherited(arguments);for(var name in this._toConnect){this.on(name,this._toConnect[name]);}delete this._toConnect;},on:function(type,func){if(this[this._onMap(type)]===_2ea){return _2e1.connect(this.domNode,type.toLowerCase(),this,func);}return this.inherited(arguments);},_setFocusedAttr:function(val){this._focused=val;this._set("focused",val);},setAttribute:function(attr,_2f2){_2e3.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.","","2.0");this.set(attr,_2f2);},attr:function(name,_2f3){if(_2e0.isDebug){var _2f4=arguments.callee._ach||(arguments.callee._ach={}),_2f5=(arguments.callee.caller||"unknown caller").toString();if(!_2f4[_2f5]){_2e3.deprecated(this.declaredClass+"::attr() is deprecated. Use get() or set() instead, called from "+_2f5,"","2.0");_2f4[_2f5]=true;}}var args=arguments.length;if(args>=2||typeof name==="object"){return this.set.apply(this,arguments);}else{return this.get(name);}},getDescendants:function(){_2e3.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.","","2.0");return this.containerNode?_2e4("[widgetId]",this.containerNode).map(_2e6.byNode):[];},_onShow:function(){this.onShow();},onShow:function(){},onHide:function(){},onClose:function(){return true;}});if(!_2e3.isAsync){_2e5(0,function(){var _2f6=["dijit/_base"];require(_2f6);});}return _2f0;});},"dijit/_FocusMixin":function(){define("dijit/_FocusMixin",["./focus","./_WidgetBase","dojo/_base/declare","dojo/_base/lang"],function(_2f7,_2f8,_2f9,lang){lang.extend(_2f8,{focused:false,onFocus:function(){},onBlur:function(){},_onFocus:function(){this.onFocus();},_onBlur:function(){this.onBlur();}});return _2f9("dijit._FocusMixin",null,{_focusManager:_2f7});});},"dijit/_OnDijitClickMixin":function(){define("dijit/_OnDijitClickMixin",["dojo/on","dojo/_base/array","dojo/keys","dojo/_base/declare","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window"],function(on,_2fa,keys,_2fb,has,_2fc,win){var _2fd=null;if(has("ie")){(function(){var _2fe=function(evt){_2fd=evt.srcElement;};win.doc.attachEvent("onkeydown",_2fe);_2fc.addOnWindowUnload(function(){win.doc.detachEvent("onkeydown",_2fe);});})();}else{win.doc.addEventListener("keydown",function(evt){_2fd=evt.target;},true);}var _2ff=function(node,_300){if(/input|button/i.test(node.nodeName)){return on(node,"click",_300);}else{function _301(e){return (e.keyCode==keys.ENTER||e.keyCode==keys.SPACE)&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey;};var _302=[on(node,"keypress",function(e){if(_301(e)){_2fd=e.target;e.preventDefault();}}),on(node,"keyup",function(e){if(_301(e)&&e.target==_2fd){_2fd=null;_300.call(this,e);}}),on(node,"click",function(e){_300.call(this,e);})];return {remove:function(){_2fa.forEach(_302,function(h){h.remove();});}};}};return _2fb("dijit._OnDijitClickMixin",null,{connect:function(obj,_303,_304){return this.inherited(arguments,[obj,_303=="ondijitclick"?_2ff:_303,_304]);}});});},"dojo/cache":function(){define(["./_base/kernel","./text"],function(dojo,text){return dojo.cache;});},"dijit/focus":function(){define("dijit/focus",["dojo/aspect","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-construct","dojo/Evented","dojo/_base/lang","dojo/on","dojo/ready","dojo/_base/sniff","dojo/Stateful","dojo/_base/unload","dojo/_base/window","dojo/window","./a11y","./registry","."],function(_305,_306,dom,_307,_308,_309,lang,on,_30a,has,_30b,_30c,win,_30d,a11y,_30e,_30f){var _310=_306([_30b,_309],{curNode:null,activeStack:[],constructor:function(){var _311=lang.hitch(this,function(node){if(dom.isDescendant(this.curNode,node)){this.set("curNode",null);}if(dom.isDescendant(this.prevNode,node)){this.set("prevNode",null);}});_305.before(_308,"empty",_311);_305.before(_308,"destroy",_311);},registerIframe:function(_312){return this.registerWin(_312.contentWindow,_312);},registerWin:function(_313,_314){var _315=this;var _316=function(evt){_315._justMouseDowned=true;setTimeout(function(){_315._justMouseDowned=false;},0);if(has("ie")&&evt&&evt.srcElement&&evt.srcElement.parentNode==null){return;}_315._onTouchNode(_314||evt.target||evt.srcElement,"mouse");};var doc=has("ie")?_313.document.documentElement:_313.document;if(doc){if(has("ie")){_313.document.body.attachEvent("onmousedown",_316);var _317=function(evt){var tag=evt.srcElement.tagName.toLowerCase();if(tag=="#document"||tag=="body"){return;}if(a11y.isTabNavigable(evt.srcElement)){_315._onFocusNode(_314||evt.srcElement);}else{_315._onTouchNode(_314||evt.srcElement);}};doc.attachEvent("onactivate",_317);var _318=function(evt){_315._onBlurNode(_314||evt.srcElement);};doc.attachEvent("ondeactivate",_318);return {remove:function(){_313.document.detachEvent("onmousedown",_316);doc.detachEvent("onactivate",_317);doc.detachEvent("ondeactivate",_318);doc=null;}};}else{doc.body.addEventListener("mousedown",_316,true);doc.body.addEventListener("touchstart",_316,true);var _319=function(evt){_315._onFocusNode(_314||evt.target);};doc.addEventListener("focus",_319,true);var _31a=function(evt){_315._onBlurNode(_314||evt.target);};doc.addEventListener("blur",_31a,true);return {remove:function(){doc.body.removeEventListener("mousedown",_316,true);doc.body.removeEventListener("touchstart",_316,true);doc.removeEventListener("focus",_319,true);doc.removeEventListener("blur",_31a,true);doc=null;}};}}},_onBlurNode:function(){this.set("prevNode",this.curNode);this.set("curNode",null);if(this._justMouseDowned){return;}if(this._clearActiveWidgetsTimer){clearTimeout(this._clearActiveWidgetsTimer);}this._clearActiveWidgetsTimer=setTimeout(lang.hitch(this,function(){delete this._clearActiveWidgetsTimer;this._setStack([]);this.prevNode=null;}),100);},_onTouchNode:function(node,by){if(this._clearActiveWidgetsTimer){clearTimeout(this._clearActiveWidgetsTimer);delete this._clearActiveWidgetsTimer;}var _31b=[];try{while(node){var _31c=_307.get(node,"dijitPopupParent");if(_31c){node=_30e.byId(_31c).domNode;}else{if(node.tagName&&node.tagName.toLowerCase()=="body"){if(node===win.body()){break;}node=_30d.get(node.ownerDocument).frameElement;}else{var id=node.getAttribute&&node.getAttribute("widgetId"),_31d=id&&_30e.byId(id);if(_31d&&!(by=="mouse"&&_31d.get("disabled"))){_31b.unshift(id);}node=node.parentNode;}}}}catch(e){}this._setStack(_31b,by);},_onFocusNode:function(node){if(!node){return;}if(node.nodeType==9){return;}this._onTouchNode(node);if(node==this.curNode){return;}this.set("curNode",node);},_setStack:function(_31e,by){var _31f=this.activeStack;this.set("activeStack",_31e);for(var _320=0;_320<Math.min(_31f.length,_31e.length);_320++){if(_31f[_320]!=_31e[_320]){break;}}var _321;for(var i=_31f.length-1;i>=_320;i--){_321=_30e.byId(_31f[i]);if(_321){_321._hasBeenBlurred=true;_321.set("focused",false);if(_321._focusManager==this){_321._onBlur(by);}this.emit("widget-blur",_321,by);}}for(i=_320;i<_31e.length;i++){_321=_30e.byId(_31e[i]);if(_321){_321.set("focused",true);if(_321._focusManager==this){_321._onFocus(by);}this.emit("widget-focus",_321,by);}}},focus:function(node){if(node){try{node.focus();}catch(e){}}}});var _322=new _310();_30a(function(){var _323=_322.registerWin(win.doc.parentWindow||win.doc.defaultView);if(has("ie")){_30c.addOnWindowUnload(function(){_323.remove();_323=null;});}});_30f.focus=function(node){_322.focus(node);};for(var attr in _322){if(!/^_/.test(attr)){_30f.focus[attr]=typeof _322[attr]=="function"?lang.hitch(_322,attr):_322[attr];}}_322.watch(function(attr,_324,_325){_30f.focus[attr]=_325;});return _322;});},"dojox/grid/util":function(){define("dojox/grid/util",["../main","dojo/_base/lang","dojo/dom"],function(_326,lang,dom){var dgu=lang.getObject("grid.util",true,_326);dgu.na="...";dgu.rowIndexTag="gridRowIndex";dgu.gridViewTag="gridView";dgu.fire=function(ob,ev,args){var fn=ob&&ev&&ob[ev];return fn&&(args?fn.apply(ob,args):ob[ev]());};dgu.setStyleHeightPx=function(_327,_328){if(_328>=0){var s=_327.style;var v=_328+"px";if(_327&&s["height"]!=v){s["height"]=v;}}};dgu.mouseEvents=["mouseover","mouseout","mousedown","mouseup","click","dblclick","contextmenu"];dgu.keyEvents=["keyup","keydown","keypress"];dgu.funnelEvents=function(_329,_32a,_32b,_32c){var evts=(_32c?_32c:dgu.mouseEvents.concat(dgu.keyEvents));for(var i=0,l=evts.length;i<l;i++){_32a.connect(_329,"on"+evts[i],_32b);}};dgu.removeNode=function(_32d){_32d=dom.byId(_32d);_32d&&_32d.parentNode&&_32d.parentNode.removeChild(_32d);return _32d;};dgu.arrayCompare=function(inA,inB){for(var i=0,l=inA.length;i<l;i++){if(inA[i]!=inB[i]){return false;}}return (inA.length==inB.length);};dgu.arrayInsert=function(_32e,_32f,_330){if(_32e.length<=_32f){_32e[_32f]=_330;}else{_32e.splice(_32f,0,_330);}};dgu.arrayRemove=function(_331,_332){_331.splice(_332,1);};dgu.arraySwap=function(_333,inI,inJ){var _334=_333[inI];_333[inI]=_333[inJ];_333[inJ]=_334;};return _326.grid.util;});},"url:dijit/templates/MenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n","dijit/main":function(){define("dijit/main",["dojo/_base/kernel"],function(dojo){return dojo.dijit;});},"dojo/date/stamp":function(){define(["../_base/kernel","../_base/lang","../_base/array"],function(dojo,lang,_335){lang.getObject("date.stamp",true,dojo);dojo.date.stamp.fromISOString=function(_336,_337){if(!dojo.date.stamp._isoRegExp){dojo.date.stamp._isoRegExp=/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;}var _338=dojo.date.stamp._isoRegExp.exec(_336),_339=null;if(_338){_338.shift();if(_338[1]){_338[1]--;}if(_338[6]){_338[6]*=1000;}if(_337){_337=new Date(_337);_335.forEach(_335.map(["FullYear","Month","Date","Hours","Minutes","Seconds","Milliseconds"],function(prop){return _337["get"+prop]();}),function(_33a,_33b){_338[_33b]=_338[_33b]||_33a;});}_339=new Date(_338[0]||1970,_338[1]||0,_338[2]||1,_338[3]||0,_338[4]||0,_338[5]||0,_338[6]||0);if(_338[0]<100){_339.setFullYear(_338[0]||1970);}var _33c=0,_33d=_338[7]&&_338[7].charAt(0);if(_33d!="Z"){_33c=((_338[8]||0)*60)+(Number(_338[9])||0);if(_33d!="-"){_33c*=-1;}}if(_33d){_33c-=_339.getTimezoneOffset();}if(_33c){_339.setTime(_339.getTime()+_33c*60000);}}return _339;};dojo.date.stamp.toISOString=function(_33e,_33f){var _340=function(n){return (n<10)?"0"+n:n;};_33f=_33f||{};var _341=[],_342=_33f.zulu?"getUTC":"get",date="";if(_33f.selector!="time"){var year=_33e[_342+"FullYear"]();date=["0000".substr((year+"").length)+year,_340(_33e[_342+"Month"]()+1),_340(_33e[_342+"Date"]())].join("-");}_341.push(date);if(_33f.selector!="date"){var time=[_340(_33e[_342+"Hours"]()),_340(_33e[_342+"Minutes"]()),_340(_33e[_342+"Seconds"]())].join(":");var _343=_33e[_342+"Milliseconds"]();if(_33f.milliseconds){time+="."+(_343<100?"0":"")+_340(_343);}if(_33f.zulu){time+="Z";}else{if(_33f.selector!="time"){var _344=_33e.getTimezoneOffset();var _345=Math.abs(_344);time+=(_344>0?"-":"+")+_340(Math.floor(_345/60))+":"+_340(_345%60);}}_341.push(time);}return _341.join("T");};return dojo.date.stamp;});},"url:dojox/grid/resources/View.html":"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n","dojox/grid/_FocusManager":function(){define("dojox/grid/_FocusManager",["dojo/_base/array","dojo/_base/lang","dojo/_base/declare","dojo/_base/connect","dojo/_base/event","dojo/_base/sniff","dojo/query","./util","dojo/_base/html"],function(_346,lang,_347,_348,_349,has,_34a,util,html){return _347("dojox.grid._FocusManager",null,{constructor:function(_34b){this.grid=_34b;this.cell=null;this.rowIndex=-1;this._connects=[];this._headerConnects=[];this.headerMenu=this.grid.headerMenu;this._connects.push(_348.connect(this.grid.domNode,"onfocus",this,"doFocus"));this._connects.push(_348.connect(this.grid.domNode,"onblur",this,"doBlur"));this._connects.push(_348.connect(this.grid.domNode,"mousedown",this,"_mouseDown"));this._connects.push(_348.connect(this.grid.domNode,"mouseup",this,"_mouseUp"));this._connects.push(_348.connect(this.grid.domNode,"oncontextmenu",this,"doContextMenu"));this._connects.push(_348.connect(this.grid.lastFocusNode,"onfocus",this,"doLastNodeFocus"));this._connects.push(_348.connect(this.grid.lastFocusNode,"onblur",this,"doLastNodeBlur"));this._connects.push(_348.connect(this.grid,"_onFetchComplete",this,"_delayedCellFocus"));this._connects.push(_348.connect(this.grid,"postrender",this,"_delayedHeaderFocus"));},destroy:function(){_346.forEach(this._connects,_348.disconnect);_346.forEach(this._headerConnects,_348.disconnect);delete this.grid;delete this.cell;},_colHeadNode:null,_colHeadFocusIdx:null,_contextMenuBindNode:null,tabbingOut:false,focusClass:"dojoxGridCellFocus",focusView:null,initFocusView:function(){this.focusView=this.grid.views.getFirstScrollingView()||this.focusView||this.grid.views.views[0];this._initColumnHeaders();},isFocusCell:function(_34c,_34d){return (this.cell==_34c)&&(this.rowIndex==_34d);},isLastFocusCell:function(){if(this.cell){return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);}return false;},isFirstFocusCell:function(){if(this.cell){return (this.rowIndex===0)&&(this.cell.index===0);}return false;},isNoFocusCell:function(){return (this.rowIndex<0)||!this.cell;},isNavHeader:function(){return (!!this._colHeadNode);},getHeaderIndex:function(){if(this._colHeadNode){return _346.indexOf(this._findHeaderCells(),this._colHeadNode);}else{return -1;}},_focusifyCellNode:function(_34e){var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){html.toggleClass(n,this.focusClass,_34e);if(_34e){var sl=this.scrollIntoView();try{if(!this.grid.edit.isEditing()){util.fire(n,"focus");if(sl){this.cell.view.scrollboxNode.scrollLeft=sl;}}}catch(e){}}}},_delayedCellFocus:function(){if(this.isNavHeader()||!this.grid.focused){return;}var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){try{if(!this.grid.edit.isEditing()){html.toggleClass(n,this.focusClass,true);if(this._colHeadNode){this.blurHeader();}util.fire(n,"focus");}}catch(e){}}},_delayedHeaderFocus:function(){if(this.isNavHeader()){this.focusHeader();this.grid.domNode.focus();}},_initColumnHeaders:function(){_346.forEach(this._headerConnects,_348.disconnect);this._headerConnects=[];var _34f=this._findHeaderCells();for(var i=0;i<_34f.length;i++){this._headerConnects.push(_348.connect(_34f[i],"onfocus",this,"doColHeaderFocus"));this._headerConnects.push(_348.connect(_34f[i],"onblur",this,"doColHeaderBlur"));}},_findHeaderCells:function(){var _350=_34a("th",this.grid.viewsHeaderNode);var _351=[];for(var i=0;i<_350.length;i++){var _352=_350[i];var _353=html.hasAttr(_352,"tabIndex");var _354=html.attr(_352,"tabIndex");if(_353&&_354<0){_351.push(_352);}}return _351;},_setActiveColHeader:function(_355,_356,_357){this.grid.domNode.setAttribute("aria-activedescendant",_355.id);if(_357!=null&&_357>=0&&_357!=_356){html.toggleClass(this._findHeaderCells()[_357],this.focusClass,false);}html.toggleClass(_355,this.focusClass,true);this._colHeadNode=_355;this._colHeadFocusIdx=_356;this._scrollHeader(this._colHeadFocusIdx);},scrollIntoView:function(){var info=(this.cell?this._scrollInfo(this.cell):null);if(!info||!info.s){return null;}var rt=this.grid.scroller.findScrollTop(this.rowIndex);if(info.n&&info.sr){if(info.n.offsetLeft+info.n.offsetWidth>info.sr.l+info.sr.w){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}}}if(info.r&&info.sr){if(rt+info.r.offsetHeight>info.sr.t+info.sr.h){this.grid.setScrollTop(rt+info.r.offsetHeight-info.sr.h);}else{if(rt<info.sr.t){this.grid.setScrollTop(rt);}}}return info.s.scrollLeft;},_scrollInfo:function(cell,_358){if(cell){var cl=cell,sbn=cl.view.scrollboxNode,sbnr={w:sbn.clientWidth,l:sbn.scrollLeft,t:sbn.scrollTop,h:sbn.clientHeight},rn=cl.view.getRowNode(this.rowIndex);return {c:cl,s:sbn,sr:sbnr,n:(_358?_358:cell.getNode(this.rowIndex)),r:rn};}return null;},_scrollHeader:function(_359){var info=null;if(this._colHeadNode){var cell=this.grid.getCell(_359);if(!cell){return;}info=this._scrollInfo(cell,cell.getNode(0));}if(info&&info.s&&info.sr&&info.n){var _35a=info.sr.l+info.sr.w;if(info.n.offsetLeft+info.n.offsetWidth>_35a){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}else{if(has("ie")<=7&&cell&&cell.view.headerNode){cell.view.headerNode.scrollLeft=info.s.scrollLeft;}}}}},_isHeaderHidden:function(){var _35b=this.focusView;if(!_35b){for(var i=0,_35c;(_35c=this.grid.views.views[i]);i++){if(_35c.headerNode){_35b=_35c;break;}}}return (_35b&&html.getComputedStyle(_35b.headerNode).display=="none");},colSizeAdjust:function(e,_35d,_35e){var _35f=this._findHeaderCells();var view=this.focusView;if(!view){for(var i=0,_360;(_360=this.grid.views.views[i]);i++){if(_360.header.tableMap.map){view=_360;break;}}}var _361=_35f[_35d];if(!view||(_35d==_35f.length-1&&_35d===0)){return;}view.content.baseDecorateEvent(e);e.cellNode=_361;e.cellIndex=view.content.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);if(view.header.canResize(e)){var _362={l:_35e};var drag=view.header.colResizeSetup(e,false);view.header.doResizeColumn(drag,null,_362);view.update();}},styleRow:function(_363){return;},setFocusIndex:function(_364,_365){this.setFocusCell(this.grid.getCell(_365),_364);},setFocusCell:function(_366,_367){if(_366&&!this.isFocusCell(_366,_367)){this.tabbingOut=false;if(this._colHeadNode){this.blurHeader();}this._colHeadNode=this._colHeadFocusIdx=null;this.focusGridView();this._focusifyCellNode(false);this.cell=_366;this.rowIndex=_367;this._focusifyCellNode(true);}if(has("opera")){setTimeout(lang.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);}else{this.grid.onCellFocus(this.cell,this.rowIndex);}},next:function(){if(this.cell){var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;if(col>cc){col=0;row++;}if(row>rc){col=cc;row=rc;}if(this.grid.edit.isEditing()){var _368=this.grid.getCell(col);if(!this.isLastFocusCell()&&(!_368.editable||this.grid.canEdit&&!this.grid.canEdit(_368,row))){this.cell=_368;this.rowIndex=row;this.next();return;}}this.setFocusIndex(row,col);}},previous:function(){if(this.cell){var row=(this.rowIndex||0),col=(this.cell.index||0)-1;if(col<0){col=this.grid.layout.cellCount-1;row--;}if(row<0){row=0;col=0;}if(this.grid.edit.isEditing()){var _369=this.grid.getCell(col);if(!this.isFirstFocusCell()&&!_369.editable){this.cell=_369;this.rowIndex=row;this.previous();return;}}this.setFocusIndex(row,col);}},move:function(_36a,_36b){var _36c=_36b<0?-1:1;if(this.isNavHeader()){var _36d=this._findHeaderCells();var _36e=currentIdx=_346.indexOf(_36d,this._colHeadNode);currentIdx+=_36b;while(currentIdx>=0&¤tIdx<_36d.length&&_36d[currentIdx].style.display=="none"){currentIdx+=_36c;}if((currentIdx>=0)&&(currentIdx<_36d.length)){this._setActiveColHeader(_36d[currentIdx],currentIdx,_36e);}}else{if(this.cell){var sc=this.grid.scroller,r=this.rowIndex,rc=this.grid.rowCount-1,row=Math.min(rc,Math.max(0,r+_36a));if(_36a){if(_36a>0){if(row>sc.getLastPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));}}else{if(_36a<0){if(row<=sc.getPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));}}}}var cc=this.grid.layout.cellCount-1,i=this.cell.index,col=Math.min(cc,Math.max(0,i+_36b));var cell=this.grid.getCell(col);while(col>=0&&col<cc&&cell&&cell.hidden===true){col+=_36c;cell=this.grid.getCell(col);}if(!cell||cell.hidden===true){col=i;}var n=cell.getNode(row);if(!n&&_36a){if((row+_36a)>=0&&(row+_36a)<=rc){this.move(_36a>0?++_36a:--_36a,_36b);}return;}else{if((!n||html.style(n,"display")==="none")&&_36b){if((col+_36a)>=0&&(col+_36a)<=cc){this.move(_36a,_36b>0?++_36b:--_36b);}return;}}this.setFocusIndex(row,col);if(_36a){this.grid.updateRow(r);}}}},previousKey:function(e){if(this.grid.edit.isEditing()){_349.stop(e);this.previous();}else{if(!this.isNavHeader()&&!this._isHeaderHidden()){this.grid.domNode.focus();_349.stop(e);}else{this.tabOut(this.grid.domNode);if(this._colHeadFocusIdx!=null){html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx],this.focusClass,false);this._colHeadFocusIdx=null;}this._focusifyCellNode(false);}}},nextKey:function(e){var _36f=(this.grid.rowCount===0);if(e.target===this.grid.domNode&&this._colHeadFocusIdx==null){this.focusHeader();_349.stop(e);}else{if(this.isNavHeader()){this.blurHeader();if(!this.findAndFocusGridCell()){this.tabOut(this.grid.lastFocusNode);}this._colHeadNode=this._colHeadFocusIdx=null;}else{if(this.grid.edit.isEditing()){_349.stop(e);this.next();}else{this.tabOut(this.grid.lastFocusNode);}}}},tabOut:function(_370){this.tabbingOut=true;_370.focus();},focusGridView:function(){util.fire(this.focusView,"focus");},focusGrid:function(_371){this.focusGridView();this._focusifyCellNode(true);},findAndFocusGridCell:function(){var _372=true;var _373=(this.grid.rowCount===0);if(this.isNoFocusCell()&&!_373){var _374=0;var cell=this.grid.getCell(_374);if(cell.hidden){_374=this.isNavHeader()?this._colHeadFocusIdx:0;}this.setFocusIndex(0,_374);}else{if(this.cell&&!_373){if(this.focusView&&!this.focusView.rowNodes[this.rowIndex]){this.grid.scrollToRow(this.rowIndex);}this.focusGrid();}else{_372=false;}}this._colHeadNode=this._colHeadFocusIdx=null;return _372;},focusHeader:function(){var _375=this._findHeaderCells();var _376=this._colHeadFocusIdx;if(this._isHeaderHidden()){this.findAndFocusGridCell();}else{if(!this._colHeadFocusIdx){if(this.isNoFocusCell()){this._colHeadFocusIdx=0;}else{this._colHeadFocusIdx=this.cell.index;}}}this._colHeadNode=_375[this._colHeadFocusIdx];while(this._colHeadNode&&this._colHeadFocusIdx>=0&&this._colHeadFocusIdx<_375.length&&this._colHeadNode.style.display=="none"){this._colHeadFocusIdx++;this._colHeadNode=_375[this._colHeadFocusIdx];}if(this._colHeadNode&&this._colHeadNode.style.display!="none"){if(this.headerMenu&&this._contextMenuBindNode!=this.grid.domNode){this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);this.headerMenu.bindDomNode(this.grid.domNode);this._contextMenuBindNode=this.grid.domNode;}this._setActiveColHeader(this._colHeadNode,this._colHeadFocusIdx,_376);this._scrollHeader(this._colHeadFocusIdx);this._focusifyCellNode(false);}else{this.findAndFocusGridCell();}},blurHeader:function(){html.removeClass(this._colHeadNode,this.focusClass);html.removeAttr(this.grid.domNode,"aria-activedescendant");if(this.headerMenu&&this._contextMenuBindNode==this.grid.domNode){var _377=this.grid.viewsHeaderNode;this.headerMenu.unBindDomNode(this.grid.domNode);this.headerMenu.bindDomNode(_377);this._contextMenuBindNode=_377;}},doFocus:function(e){if(e&&e.target!=e.currentTarget){_349.stop(e);return;}if(this._clickFocus){return;}if(!this.tabbingOut){this.focusHeader();}this.tabbingOut=false;_349.stop(e);},doBlur:function(e){_349.stop(e);},doContextMenu:function(e){if(!this.headerMenu){_349.stop(e);}},doLastNodeFocus:function(e){if(this.tabbingOut){this._focusifyCellNode(false);}else{if(this.grid.rowCount>0){if(this.isNoFocusCell()){this.setFocusIndex(0,0);}this._focusifyCellNode(true);}else{this.focusHeader();}}this.tabbingOut=false;_349.stop(e);},doLastNodeBlur:function(e){_349.stop(e);},doColHeaderFocus:function(e){this._setActiveColHeader(e.target,html.attr(e.target,"idx"),this._colHeadFocusIdx);this._scrollHeader(this.getHeaderIndex());_349.stop(e);},doColHeaderBlur:function(e){html.toggleClass(e.target,this.focusClass,false);},_mouseDown:function(e){this._clickFocus=dojo.some(this.grid.views.views,function(v){return v.scrollboxNode===e.target;});},_mouseUp:function(e){this._clickFocus=false;}});});},"dijit/MenuItem":function(){require({cache:{"url:dijit/templates/MenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n"}});define("dijit/MenuItem",["dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/_base/event","dojo/_base/kernel","dojo/_base/sniff","./_Widget","./_TemplatedMixin","./_Contained","./_CssStateMixin","dojo/text!./templates/MenuItem.html"],function(_378,dom,_379,_37a,_37b,_37c,has,_37d,_37e,_37f,_380,_381){return _378("dijit.MenuItem",[_37d,_37e,_37f,_380],{templateString:_381,baseClass:"dijitMenuItem",label:"",_setLabelAttr:{node:"containerNode",type:"innerHTML"},iconClass:"dijitNoIcon",_setIconClassAttr:{node:"iconNode",type:"class"},accelKey:"",disabled:false,_fillContent:function(_382){if(_382&&!("label" in this.params)){this.set("label",_382.innerHTML);}},buildRendering:function(){this.inherited(arguments);var _383=this.id+"_text";_379.set(this.containerNode,"id",_383);if(this.accelKeyNode){_379.set(this.accelKeyNode,"id",this.id+"_accel");_383+=" "+this.id+"_accel";}this.domNode.setAttribute("aria-labelledby",_383);dom.setSelectable(this.domNode,false);},_onHover:function(){this.getParent().onItemHover(this);},_onUnhover:function(){this.getParent().onItemUnhover(this);this._set("hovering",false);},_onClick:function(evt){this.getParent().onItemClick(this,evt);_37b.stop(evt);},onClick:function(){},focus:function(){try{if(has("ie")==8){this.containerNode.focus();}this.focusNode.focus();}catch(e){}},_onFocus:function(){this._setSelected(true);this.getParent()._onItemFocus(this);this.inherited(arguments);},_setSelected:function(_384){_37a.toggle(this.domNode,"dijitMenuItemSelected",_384);},setLabel:function(_385){_37c.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.","","2.0");this.set("label",_385);},setDisabled:function(_386){_37c.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");this.set("disabled",_386);},_setDisabledAttr:function(_387){this.focusNode.setAttribute("aria-disabled",_387?"true":"false");this._set("disabled",_387);},_setAccelKeyAttr:function(_388){this.accelKeyNode.style.display=_388?"":"none";this.accelKeyNode.innerHTML=_388;_379.set(this.containerNode,"colSpan",_388?"1":"2");this._set("accelKey",_388);}});});},"dijit/_TemplatedMixin":function(){define("dijit/_TemplatedMixin",["dojo/_base/lang","dojo/touch","./_WidgetBase","dojo/string","dojo/cache","dojo/_base/array","dojo/_base/declare","dojo/dom-construct","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window"],function(lang,_389,_38a,_38b,_38c,_38d,_38e,_38f,has,_390,win){var _391=_38e("dijit._TemplatedMixin",null,{templateString:null,templatePath:null,_skipNodeCache:false,_earlyTemplatedStartup:false,constructor:function(){this._attachPoints=[];this._attachEvents=[];},_stringRepl:function(tmpl){var _392=this.declaredClass,_393=this;return _38b.substitute(tmpl,this,function(_394,key){if(key.charAt(0)=="!"){_394=lang.getObject(key.substr(1),false,_393);}if(typeof _394=="undefined"){throw new Error(_392+" template:"+key);}if(_394==null){return "";}return key.charAt(0)=="!"?_394:_394.toString().replace(/"/g,""");},this);},buildRendering:function(){if(!this.templateString){this.templateString=_38c(this.templatePath,{sanitize:true});}var _395=_391.getCachedTemplate(this.templateString,this._skipNodeCache);var node;if(lang.isString(_395)){node=_38f.toDom(this._stringRepl(_395));if(node.nodeType!=1){throw new Error("Invalid template: "+_395);}}else{node=_395.cloneNode(true);}this.domNode=node;this.inherited(arguments);this._attachTemplateNodes(node,function(n,p){return n.getAttribute(p);});this._beforeFillContent();this._fillContent(this.srcNodeRef);},_beforeFillContent:function(){},_fillContent:function(_396){var dest=this.containerNode;if(_396&&dest){while(_396.hasChildNodes()){dest.appendChild(_396.firstChild);}}},_attachTemplateNodes:function(_397,_398){var _399=lang.isArray(_397)?_397:(_397.all||_397.getElementsByTagName("*"));var x=lang.isArray(_397)?0:-1;for(;x<_399.length;x++){var _39a=(x==-1)?_397:_399[x];if(this.widgetsInTemplate&&(_398(_39a,"dojoType")||_398(_39a,"data-dojo-type"))){continue;}var _39b=_398(_39a,"dojoAttachPoint")||_398(_39a,"data-dojo-attach-point");if(_39b){var _39c,_39d=_39b.split(/\s*,\s*/);while((_39c=_39d.shift())){if(lang.isArray(this[_39c])){this[_39c].push(_39a);}else{this[_39c]=_39a;}this._attachPoints.push(_39c);}}var _39e=_398(_39a,"dojoAttachEvent")||_398(_39a,"data-dojo-attach-event");if(_39e){var _39f,_3a0=_39e.split(/\s*,\s*/);var trim=lang.trim;while((_39f=_3a0.shift())){if(_39f){var _3a1=null;if(_39f.indexOf(":")!=-1){var _3a2=_39f.split(":");_39f=trim(_3a2[0]);_3a1=trim(_3a2[1]);}else{_39f=trim(_39f);}if(!_3a1){_3a1=_39f;}this._attachEvents.push(this.connect(_39a,_389[_39f]||_39f,_3a1));}}}}},destroyRendering:function(){_38d.forEach(this._attachPoints,function(_3a3){delete this[_3a3];},this);this._attachPoints=[];_38d.forEach(this._attachEvents,this.disconnect,this);this._attachEvents=[];this.inherited(arguments);}});_391._templateCache={};_391.getCachedTemplate=function(_3a4,_3a5){var _3a6=_391._templateCache;var key=_3a4;var _3a7=_3a6[key];if(_3a7){try{if(!_3a7.ownerDocument||_3a7.ownerDocument==win.doc){return _3a7;}}catch(e){}_38f.destroy(_3a7);}_3a4=_38b.trim(_3a4);if(_3a5||_3a4.match(/\$\{([^\}]+)\}/g)){return (_3a6[key]=_3a4);}else{var node=_38f.toDom(_3a4);if(node.nodeType!=1){throw new Error("Invalid template: "+_3a4);}return (_3a6[key]=node);}};if(has("ie")){_390.addOnWindowUnload(function(){var _3a8=_391._templateCache;for(var key in _3a8){var _3a9=_3a8[key];if(typeof _3a9=="object"){_38f.destroy(_3a9);}delete _3a8[key];}});}lang.extend(_38a,{dojoAttachEvent:"",dojoAttachPoint:""});return _391;});},"dojox/grid/_SelectionPreserver":function(){define("dojox/grid/_SelectionPreserver",["dojo/_base/declare","dojo/_base/connect","dojo/_base/lang","dojo/_base/array"],function(_3aa,_3ab,lang,_3ac){return _3aa("dojox.grid._SelectionPreserver",null,{constructor:function(_3ad){this.selection=_3ad;var grid=this.grid=_3ad.grid;this.reset();this._connects=[_3ab.connect(grid,"_setStore",this,"reset"),_3ab.connect(grid,"_addItem",this,"_reSelectById"),_3ab.connect(_3ad,"addToSelection",lang.hitch(this,"_selectById",true)),_3ab.connect(_3ad,"deselect",lang.hitch(this,"_selectById",false)),_3ab.connect(_3ad,"deselectAll",this,"reset")];},destroy:function(){this.reset();_3ac.forEach(this._connects,_3ab.disconnect);delete this._connects;},reset:function(){this._selectedById={};},_reSelectById:function(item,_3ae){if(item&&this.grid._hasIdentity){this.selection.selected[_3ae]=this._selectedById[this.grid.store.getIdentity(item)];}},_selectById:function(_3af,_3b0){if(this.selection.mode=="none"||!this.grid._hasIdentity){return;}var item=_3b0,g=this.grid;if(typeof _3b0=="number"||typeof _3b0=="string"){var _3b1=g._by_idx[_3b0];item=_3b1&&_3b1.item;}if(item){this._selectedById[g.store.getIdentity(item)]=!!_3af;}return item;}});});},"dojo/window":function(){define(["./_base/lang","./_base/sniff","./_base/window","./dom","./dom-geometry","./dom-style"],function(lang,has,_3b2,dom,geom,_3b3){var _3b4=lang.getObject("dojo.window",true);_3b4.getBox=function(){var _3b5=(_3b2.doc.compatMode=="BackCompat")?_3b2.body():_3b2.doc.documentElement,_3b6=geom.docScroll(),w,h;if(has("touch")){var _3b7=_3b2.doc.parentWindow||_3b2.doc.defaultView;w=_3b7.innerWidth||_3b5.clientWidth;h=_3b7.innerHeight||_3b5.clientHeight;}else{w=_3b5.clientWidth;h=_3b5.clientHeight;}return {l:_3b6.x,t:_3b6.y,w:w,h:h};};_3b4.get=function(doc){if(has("ie")&&_3b4!==document.parentWindow){doc.parentWindow.execScript("document._parentWindow = window;","Javascript");var win=doc._parentWindow;doc._parentWindow=null;return win;}return doc.parentWindow||doc.defaultView;};_3b4.scrollIntoView=function(node,pos){try{node=dom.byId(node);var doc=node.ownerDocument||_3b2.doc,body=doc.body||_3b2.body(),html=doc.documentElement||body.parentNode,isIE=has("ie"),isWK=has("webkit");if((!(has("mozilla")||isIE||isWK||has("opera"))||node==body||node==html)&&(typeof node.scrollIntoView!="undefined")){node.scrollIntoView(false);return;}var _3b8=doc.compatMode=="BackCompat",_3b9=(isIE>=9&&node.ownerDocument.parentWindow.frameElement)?((html.clientHeight>0&&html.clientWidth>0&&(body.clientHeight==0||body.clientWidth==0||body.clientHeight>html.clientHeight||body.clientWidth>html.clientWidth))?html:body):(_3b8?body:html),_3ba=isWK?body:_3b9,_3bb=_3b9.clientWidth,_3bc=_3b9.clientHeight,rtl=!geom.isBodyLtr(),_3bd=pos||geom.position(node),el=node.parentNode,_3be=function(el){return ((isIE<=6||(isIE&&_3b8))?false:(_3b3.get(el,"position").toLowerCase()=="fixed"));};if(_3be(node)){return;}while(el){if(el==body){el=_3ba;}var _3bf=geom.position(el),_3c0=_3be(el);if(el==_3ba){_3bf.w=_3bb;_3bf.h=_3bc;if(_3ba==html&&isIE&&rtl){_3bf.x+=_3ba.offsetWidth-_3bf.w;}if(_3bf.x<0||!isIE){_3bf.x=0;}if(_3bf.y<0||!isIE){_3bf.y=0;}}else{var pb=geom.getPadBorderExtents(el);_3bf.w-=pb.w;_3bf.h-=pb.h;_3bf.x+=pb.l;_3bf.y+=pb.t;var _3c1=el.clientWidth,_3c2=_3bf.w-_3c1;if(_3c1>0&&_3c2>0){_3bf.w=_3c1;_3bf.x+=(rtl&&(isIE||el.clientLeft>pb.l))?_3c2:0;}_3c1=el.clientHeight;_3c2=_3bf.h-_3c1;if(_3c1>0&&_3c2>0){_3bf.h=_3c1;}}if(_3c0){if(_3bf.y<0){_3bf.h+=_3bf.y;_3bf.y=0;}if(_3bf.x<0){_3bf.w+=_3bf.x;_3bf.x=0;}if(_3bf.y+_3bf.h>_3bc){_3bf.h=_3bc-_3bf.y;}if(_3bf.x+_3bf.w>_3bb){_3bf.w=_3bb-_3bf.x;}}var l=_3bd.x-_3bf.x,t=_3bd.y-Math.max(_3bf.y,0),r=l+_3bd.w-_3bf.w,bot=t+_3bd.h-_3bf.h;if(r*l>0){var s=Math[l<0?"max":"min"](l,r);if(rtl&&((isIE==8&&!_3b8)||isIE>=9)){s=-s;}_3bd.x+=el.scrollLeft;el.scrollLeft+=s;_3bd.x-=el.scrollLeft;}if(bot*t>0){_3bd.y+=el.scrollTop;el.scrollTop+=Math[t<0?"max":"min"](t,bot);_3bd.y-=el.scrollTop;}el=(el!=_3ba)&&!_3c0&&el.parentNode;}}catch(error){console.error("scrollIntoView: "+error);node.scrollIntoView(false);}};return _3b4;});},"dojox/grid/_Builder":function(){define("dojox/grid/_Builder",["../main","dojo/_base/array","dojo/_base/lang","dojo/_base/window","dojo/_base/event","dojo/_base/sniff","dojo/_base/connect","dojo/dnd/Moveable","dojox/html/metrics","./util","dojo/_base/html"],function(_3c3,_3c4,lang,win,_3c5,has,_3c6,_3c7,_3c8,util,html){var dg=_3c3.grid;var _3c9=function(td){return td.cellIndex>=0?td.cellIndex:_3c4.indexOf(td.parentNode.cells,td);};var _3ca=function(tr){return tr.rowIndex>=0?tr.rowIndex:_3c4.indexOf(tr.parentNode.childNodes,tr);};var _3cb=function(_3cc,_3cd){return _3cc&&((_3cc.rows||0)[_3cd]||_3cc.childNodes[_3cd]);};var _3ce=function(node){for(var n=node;n&&n.tagName!="TABLE";n=n.parentNode){}return n;};var _3cf=function(_3d0,_3d1){for(var n=_3d0;n&&_3d1(n);n=n.parentNode){}return n;};var _3d2=function(_3d3){var name=_3d3.toUpperCase();return function(node){return node.tagName!=name;};};var _3d4=util.rowIndexTag;var _3d5=util.gridViewTag;var _3d6=dg._Builder=lang.extend(function(view){if(view){this.view=view;this.grid=view.grid;}},{view:null,_table:"<table class=\"dojoxGridRowTable\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"",getTableArray:function(){var html=[this._table];if(this.view.viewWidth){html.push([" style=\"width:",this.view.viewWidth,";\""].join(""));}html.push(">");return html;},generateCellMarkup:function(_3d7,_3d8,_3d9,_3da){var _3db=[],html;if(_3da){var _3dc=_3d7.index!=_3d7.grid.getSortIndex()?"":_3d7.grid.sortInfo>0?"aria-sort=\"ascending\"":"aria-sort=\"descending\"";if(!_3d7.id){_3d7.id=this.grid.id+"Hdr"+_3d7.index;}html=["<th tabIndex=\"-1\" aria-readonly=\"true\" role=\"columnheader\"",_3dc,"id=\"",_3d7.id,"\""];}else{var _3dd=this.grid.editable&&!_3d7.editable?"aria-readonly=\"true\"":"";html=["<td tabIndex=\"-1\" role=\"gridcell\"",_3dd];}if(_3d7.colSpan){html.push(" colspan=\"",_3d7.colSpan,"\"");}if(_3d7.rowSpan){html.push(" rowspan=\"",_3d7.rowSpan,"\"");}html.push(" class=\"dojoxGridCell ");if(_3d7.classes){html.push(_3d7.classes," ");}if(_3d9){html.push(_3d9," ");}_3db.push(html.join(""));_3db.push("");html=["\" idx=\"",_3d7.index,"\" style=\""];if(_3d8&&_3d8[_3d8.length-1]!=";"){_3d8+=";";}html.push(_3d7.styles,_3d8||"",_3d7.hidden?"display:none;":"");if(_3d7.unitWidth){html.push("width:",_3d7.unitWidth,";");}_3db.push(html.join(""));_3db.push("");html=["\""];if(_3d7.attrs){html.push(" ",_3d7.attrs);}html.push(">");_3db.push(html.join(""));_3db.push("");_3db.push(_3da?"</th>":"</td>");return _3db;},isCellNode:function(_3de){return Boolean(_3de&&_3de!=win.doc&&html.attr(_3de,"idx"));},getCellNodeIndex:function(_3df){return _3df?Number(html.attr(_3df,"idx")):-1;},getCellNode:function(_3e0,_3e1){for(var i=0,row;((row=_3cb(_3e0.firstChild,i))&&row.cells);i++){for(var j=0,cell;(cell=row.cells[j]);j++){if(this.getCellNodeIndex(cell)==_3e1){return cell;}}}return null;},findCellTarget:function(_3e2,_3e3){var n=_3e2;while(n&&(!this.isCellNode(n)||(n.offsetParent&&_3d5 in n.offsetParent.parentNode&&n.offsetParent.parentNode[_3d5]!=this.view.id))&&(n!=_3e3)){n=n.parentNode;}return n!=_3e3?n:null;},baseDecorateEvent:function(e){e.dispatch="do"+e.type;e.grid=this.grid;e.sourceView=this.view;e.cellNode=this.findCellTarget(e.target,e.rowNode);e.cellIndex=this.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);},findTarget:function(_3e4,_3e5){var n=_3e4;while(n&&(n!=this.domNode)&&(!(_3e5 in n)||(_3d5 in n&&n[_3d5]!=this.view.id))){n=n.parentNode;}return (n!=this.domNode)?n:null;},findRowTarget:function(_3e6){return this.findTarget(_3e6,_3d4);},isIntraNodeEvent:function(e){try{return (e.cellNode&&e.relatedTarget&&html.isDescendant(e.relatedTarget,e.cellNode));}catch(x){return false;}},isIntraRowEvent:function(e){try{var row=e.relatedTarget&&this.findRowTarget(e.relatedTarget);return !row&&(e.rowIndex==-1)||row&&(e.rowIndex==row.gridRowIndex);}catch(x){return false;}},dispatchEvent:function(e){if(e.dispatch in this){return this[e.dispatch](e);}return false;},domouseover:function(e){if(e.cellNode&&(e.cellNode!=this.lastOverCellNode)){this.lastOverCellNode=e.cellNode;this.grid.onMouseOver(e);}this.grid.onMouseOverRow(e);},domouseout:function(e){if(e.cellNode&&(e.cellNode==this.lastOverCellNode)&&!this.isIntraNodeEvent(e,this.lastOverCellNode)){this.lastOverCellNode=null;this.grid.onMouseOut(e);if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}},domousedown:function(e){if(e.cellNode){this.grid.onMouseDown(e);}this.grid.onMouseDownRow(e);}});var _3e7=dg._ContentBuilder=lang.extend(function(view){_3d6.call(this,view);},_3d6.prototype,{update:function(){this.prepareHtml();},prepareHtml:function(){var _3e8=this.grid.get,_3e9=this.view.structure.cells;for(var j=0,row;(row=_3e9[j]);j++){for(var i=0,cell;(cell=row[i]);i++){cell.get=cell.get||(cell.value==undefined)&&_3e8;cell.markup=this.generateCellMarkup(cell,cell.cellStyles,cell.cellClasses,false);if(!this.grid.editable&&cell.editable){this.grid.editable=true;}}}},generateHtml:function(_3ea,_3eb){var html=this.getTableArray(),v=this.view,_3ec=v.structure.cells,item=this.grid.getItem(_3eb);util.fire(this.view,"onBeforeRow",[_3eb,_3ec]);for(var j=0,row;(row=_3ec[j]);j++){if(row.hidden||row.header){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,m,cc,cs;(cell=row[i]);i++){m=cell.markup;cc=cell.customClasses=[];cs=cell.customStyles=[];m[5]=cell.format(_3eb,item);if(has("ie")<8&&(m[5]===null||m[5]===""||/^\s+$/.test(m[5]))){m[5]=" ";}m[1]=cc.join(" ");m[3]=cs.join(";");html.push.apply(html,m);}html.push("</tr>");}html.push("</table>");return html.join("");},decorateEvent:function(e){e.rowNode=this.findRowTarget(e.target);if(!e.rowNode){return false;}e.rowIndex=e.rowNode[_3d4];this.baseDecorateEvent(e);e.cell=this.grid.getCell(e.cellIndex);return true;}});var _3ed=dg._HeaderBuilder=lang.extend(function(view){this.moveable=null;_3d6.call(this,view);},_3d6.prototype,{_skipBogusClicks:false,overResizeWidth:4,minColWidth:1,update:function(){if(this.tableMap){this.tableMap.mapRows(this.view.structure.cells);}else{this.tableMap=new dg._TableMap(this.view.structure.cells);}},generateHtml:function(_3ee,_3ef){var html=this.getTableArray(),_3f0=this.view.structure.cells;util.fire(this.view,"onBeforeRow",[-1,_3f0]);for(var j=0,row;(row=_3f0[j]);j++){if(row.hidden){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,_3f1;(cell=row[i]);i++){cell.customClasses=[];cell.customStyles=[];if(this.view.simpleStructure){if(cell.draggable){if(cell.headerClasses){if(cell.headerClasses.indexOf("dojoDndItem")==-1){cell.headerClasses+=" dojoDndItem";}}else{cell.headerClasses="dojoDndItem";}}if(cell.attrs){if(cell.attrs.indexOf("dndType='gridColumn_")==-1){cell.attrs+=" dndType='gridColumn_"+this.grid.id+"'";}}else{cell.attrs="dndType='gridColumn_"+this.grid.id+"'";}}_3f1=this.generateCellMarkup(cell,cell.headerStyles,cell.headerClasses,true);_3f1[5]=(_3ef!=undefined?_3ef:_3ee(cell));_3f1[3]=cell.customStyles.join(";");_3f1[1]=cell.customClasses.join(" ");html.push(_3f1.join(""));}html.push("</tr>");}html.push("</table>");return html.join("");},getCellX:function(e){var n,x=e.layerX;if(has("mozilla")||has("ie")>=9){n=_3cf(e.target,_3d2("th"));x-=(n&&n.offsetLeft)||0;var t=e.sourceView.getScrollbarWidth();if(!this.grid.isLeftToRight()){table=_3cf(n,_3d2("table"));x-=(table&&table.offsetLeft)||0;}}n=_3cf(e.target,function(){if(!n||n==e.cellNode){return false;}x+=(n.offsetLeft<0?0:n.offsetLeft);return true;});return x;},decorateEvent:function(e){this.baseDecorateEvent(e);e.rowIndex=-1;e.cellX=this.getCellX(e);return true;},prepareResize:function(e,mod){do{var i=e.cellIndex;e.cellNode=(i?e.cellNode.parentNode.cells[i+mod]:null);e.cellIndex=(e.cellNode?this.getCellNodeIndex(e.cellNode):-1);}while(e.cellNode&&e.cellNode.style.display=="none");return Boolean(e.cellNode);},canResize:function(e){if(!e.cellNode||e.cellNode.colSpan>1){return false;}var cell=this.grid.getCell(e.cellIndex);return !cell.noresize&&cell.canResize();},overLeftResizeArea:function(e){if(html.hasClass(win.body(),"dojoDndMove")){return false;}if(has("ie")){var tN=e.target;if(html.hasClass(tN,"dojoxGridArrowButtonNode")||html.hasClass(tN,"dojoxGridArrowButtonChar")||html.hasClass(tN,"dojoxGridColCaption")){return false;}}if(this.grid.isLeftToRight()){return (e.cellIndex>0)&&(e.cellX>0&&e.cellX<this.overResizeWidth)&&this.prepareResize(e,-1);}var t=e.cellNode&&(e.cellX>0&&e.cellX<this.overResizeWidth);return t;},overRightResizeArea:function(e){if(html.hasClass(win.body(),"dojoDndMove")){return false;}if(has("ie")){var tN=e.target;if(html.hasClass(tN,"dojoxGridArrowButtonNode")||html.hasClass(tN,"dojoxGridArrowButtonChar")||html.hasClass(tN,"dojoxGridColCaption")){return false;}}if(this.grid.isLeftToRight()){return e.cellNode&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth);}return (e.cellIndex>0)&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth)&&this.prepareResize(e,-1);},domousemove:function(e){if(!this.moveable){var c=(this.overRightResizeArea(e)?"dojoxGridColResize":(this.overLeftResizeArea(e)?"dojoxGridColResize":""));if(c&&!this.canResize(e)){c="dojoxGridColNoResize";}html.toggleClass(e.sourceView.headerNode,"dojoxGridColNoResize",(c=="dojoxGridColNoResize"));html.toggleClass(e.sourceView.headerNode,"dojoxGridColResize",(c=="dojoxGridColResize"));if(c){_3c5.stop(e);}}},domousedown:function(e){if(!this.moveable){if((this.overRightResizeArea(e)||this.overLeftResizeArea(e))&&this.canResize(e)){this.beginColumnResize(e);}else{this.grid.onMouseDown(e);this.grid.onMouseOverRow(e);}}},doclick:function(e){if(this._skipBogusClicks){_3c5.stop(e);return true;}return false;},colResizeSetup:function(e,_3f2){var _3f3=html.contentBox(e.sourceView.headerNode);if(_3f2){this.lineDiv=document.createElement("div");var vw=html.position(e.sourceView.headerNode,true);var _3f4=html.contentBox(e.sourceView.domNode);var l=e.pageX;if(!this.grid.isLeftToRight()&&has("ie")<8){l-=_3c8.getScrollbar().w;}html.style(this.lineDiv,{top:vw.y+"px",left:l+"px",height:(_3f4.h+_3f3.h)+"px"});html.addClass(this.lineDiv,"dojoxGridResizeColLine");this.lineDiv._origLeft=l;win.body().appendChild(this.lineDiv);}var _3f5=[],_3f6=this.tableMap.findOverlappingNodes(e.cellNode);for(var i=0,cell;(cell=_3f6[i]);i++){_3f5.push({node:cell,index:this.getCellNodeIndex(cell),width:cell.offsetWidth});}var view=e.sourceView;var adj=this.grid.isLeftToRight()?1:-1;var _3f7=e.grid.views.views;var _3f8=[];for(var j=view.idx+adj,_3f9;(_3f9=_3f7[j]);j=j+adj){_3f8.push({node:_3f9.headerNode,left:window.parseInt(_3f9.headerNode.style.left)});}var _3fa=view.headerContentNode.firstChild;var drag={scrollLeft:e.sourceView.headerNode.scrollLeft,view:view,node:e.cellNode,index:e.cellIndex,w:html.contentBox(e.cellNode).w,vw:_3f3.w,table:_3fa,tw:html.contentBox(_3fa).w,spanners:_3f5,followers:_3f8};return drag;},beginColumnResize:function(e){this.moverDiv=document.createElement("div");html.style(this.moverDiv,{position:"absolute",left:0});win.body().appendChild(this.moverDiv);html.addClass(this.grid.domNode,"dojoxGridColumnResizing");var m=(this.moveable=new _3c7(this.moverDiv));var drag=this.colResizeSetup(e,true);m.onMove=lang.hitch(this,"doResizeColumn",drag);_3c6.connect(m,"onMoveStop",lang.hitch(this,function(){this.endResizeColumn(drag);if(drag.node.releaseCapture){drag.node.releaseCapture();}this.moveable.destroy();delete this.moveable;this.moveable=null;html.removeClass(this.grid.domNode,"dojoxGridColumnResizing");}));if(e.cellNode.setCapture){e.cellNode.setCapture();}m.onMouseDown(e);},doResizeColumn:function(_3fb,_3fc,_3fd){var _3fe=_3fd.l;var data={deltaX:_3fe,w:_3fb.w+(this.grid.isLeftToRight()?_3fe:-_3fe),vw:_3fb.vw+_3fe,tw:_3fb.tw+_3fe};this.dragRecord={inDrag:_3fb,mover:_3fc,leftTop:_3fd};if(data.w>=this.minColWidth){if(!_3fc){this.doResizeNow(_3fb,data);}else{html.style(this.lineDiv,"left",(this.lineDiv._origLeft+data.deltaX)+"px");}}},endResizeColumn:function(_3ff){if(this.dragRecord){var _400=this.dragRecord.leftTop;var _401=this.grid.isLeftToRight()?_400.l:-_400.l;_401+=Math.max(_3ff.w+_401,this.minColWidth)-(_3ff.w+_401);if(has("webkit")&&_3ff.spanners.length){_401+=html._getPadBorderExtents(_3ff.spanners[0].node).w;}var data={deltaX:_401,w:_3ff.w+_401,vw:_3ff.vw+_401,tw:_3ff.tw+_401};this.doResizeNow(_3ff,data);delete this.dragRecord;}html.destroy(this.lineDiv);html.destroy(this.moverDiv);html.destroy(this.moverDiv);delete this.moverDiv;this._skipBogusClicks=true;_3ff.view.update();this._skipBogusClicks=false;this.grid.onResizeColumn(_3ff.index);},doResizeNow:function(_402,data){_402.view.convertColPctToFixed();if(_402.view.flexCells&&!_402.view.testFlexCells()){var t=_3ce(_402.node);if(t){(t.style.width="");}}var i,s,sw,f,fl;for(i=0;(s=_402.spanners[i]);i++){sw=s.width+data.deltaX;if(sw>0){s.node.style.width=sw+"px";_402.view.setColWidth(s.index,sw);}}if(this.grid.isLeftToRight()||!has("ie")){for(i=0;(f=_402.followers[i]);i++){fl=f.left+data.deltaX;f.node.style.left=fl+"px";}}_402.node.style.width=data.w+"px";_402.view.setColWidth(_402.index,data.w);_402.view.headerNode.style.width=data.vw+"px";_402.view.setColumnsWidth(data.tw);if(!this.grid.isLeftToRight()){_402.view.headerNode.scrollLeft=_402.scrollLeft+data.deltaX;}}});dg._TableMap=lang.extend(function(rows){this.mapRows(rows);},{map:null,mapRows:function(_403){var _404=_403.length;if(!_404){return;}this.map=[];var row;for(var k=0;(row=_403[k]);k++){this.map[k]=[];}for(var j=0;(row=_403[j]);j++){for(var i=0,x=0,cell,_405,_406;(cell=row[i]);i++){while(this.map[j][x]){x++;}this.map[j][x]={c:i,r:j};_406=cell.rowSpan||1;_405=cell.colSpan||1;for(var y=0;y<_406;y++){for(var s=0;s<_405;s++){this.map[j+y][x+s]=this.map[j][x];}}x+=_405;}}},dumpMap:function(){for(var j=0,row,h="";(row=this.map[j]);j++,h=""){for(var i=0,cell;(cell=row[i]);i++){h+=cell.r+","+cell.c+" ";}}},getMapCoords:function(_407,_408){for(var j=0,row;(row=this.map[j]);j++){for(var i=0,cell;(cell=row[i]);i++){if(cell.c==_408&&cell.r==_407){return {j:j,i:i};}}}return {j:-1,i:-1};},getNode:function(_409,_40a,_40b){var row=_409&&_409.rows[_40a];return row&&row.cells[_40b];},_findOverlappingNodes:function(_40c,_40d,_40e){var _40f=[];var m=this.getMapCoords(_40d,_40e);for(var j=0,row;(row=this.map[j]);j++){if(j==m.j){continue;}var rw=row[m.i];var n=(rw?this.getNode(_40c,rw.r,rw.c):null);if(n){_40f.push(n);}}return _40f;},findOverlappingNodes:function(_410){return this._findOverlappingNodes(_3ce(_410),_3ca(_410.parentNode),_3c9(_410));}});return {_Builder:_3d6,_HeaderBuilder:_3ed,_ContentBuilder:_3e7};});},"dojo/dnd/Source":function(){define(["../main","./Selector","./Manager"],function(dojo,_411,_412){if(!dojo.isAsync){dojo.ready(0,function(){var _413=["dojo/dnd/AutoSource","dojo/dnd/Target"];require(_413);});}return dojo.declare("dojo.dnd.Source",_411,{isSource:true,horizontal:false,copyOnly:false,selfCopy:false,selfAccept:true,skipForm:false,withHandles:false,autoSync:false,delay:0,accept:["text"],generateText:true,constructor:function(node,_414){dojo.mixin(this,dojo.mixin({},_414));var type=this.accept;if(type.length){this.accept={};for(var i=0;i<type.length;++i){this.accept[type[i]]=1;}}this.isDragging=false;this.mouseDown=false;this.targetAnchor=null;this.targetBox=null;this.before=true;this._lastX=0;this._lastY=0;this.sourceState="";if(this.isSource){dojo.addClass(this.node,"dojoDndSource");}this.targetState="";if(this.accept){dojo.addClass(this.node,"dojoDndTarget");}if(this.horizontal){dojo.addClass(this.node,"dojoDndHorizontal");}this.topics=[dojo.subscribe("/dnd/source/over",this,"onDndSourceOver"),dojo.subscribe("/dnd/start",this,"onDndStart"),dojo.subscribe("/dnd/drop",this,"onDndDrop"),dojo.subscribe("/dnd/cancel",this,"onDndCancel")];},checkAcceptance:function(_415,_416){if(this==_415){return !this.copyOnly||this.selfAccept;}for(var i=0;i<_416.length;++i){var type=_415.getItem(_416[i].id).type;var flag=false;for(var j=0;j<type.length;++j){if(type[j] in this.accept){flag=true;break;}}if(!flag){return false;}}return true;},copyState:function(_417,self){if(_417){return true;}if(arguments.length<2){self=this==_412.manager().target;}if(self){if(this.copyOnly){return this.selfCopy;}}else{return this.copyOnly;}return false;},destroy:function(){dojo.dnd.Source.superclass.destroy.call(this);dojo.forEach(this.topics,dojo.unsubscribe);this.targetAnchor=null;},onMouseMove:function(e){if(this.isDragging&&this.targetState=="Disabled"){return;}dojo.dnd.Source.superclass.onMouseMove.call(this,e);var m=_412.manager();if(!this.isDragging){if(this.mouseDown&&this.isSource&&(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay)){var _418=this.getSelectedNodes();if(_418.length){m.startDrag(this,_418,this.copyState(dojo.isCopyKey(e),true));}}}if(this.isDragging){var _419=false;if(this.current){if(!this.targetBox||this.targetAnchor!=this.current){this.targetBox=dojo.position(this.current,true);}if(this.horizontal){_419=(e.pageX-this.targetBox.x)<(this.targetBox.w/2);}else{_419=(e.pageY-this.targetBox.y)<(this.targetBox.h/2);}}if(this.current!=this.targetAnchor||_419!=this.before){this._markTargetAnchor(_419);m.canDrop(!this.current||m.source!=this||!(this.current.id in this.selection));}}},onMouseDown:function(e){if(!this.mouseDown&&this._legalMouseDown(e)&&(!this.skipForm||!dojo.dnd.isFormElement(e))){this.mouseDown=true;this._lastX=e.pageX;this._lastY=e.pageY;dojo.dnd.Source.superclass.onMouseDown.call(this,e);}},onMouseUp:function(e){if(this.mouseDown){this.mouseDown=false;dojo.dnd.Source.superclass.onMouseUp.call(this,e);}},onDndSourceOver:function(_41a){if(this!=_41a){this.mouseDown=false;if(this.targetAnchor){this._unmarkTargetAnchor();}}else{if(this.isDragging){var m=_412.manager();m.canDrop(this.targetState!="Disabled"&&(!this.current||m.source!=this||!(this.current.id in this.selection)));}}},onDndStart:function(_41b,_41c,copy){if(this.autoSync){this.sync();}if(this.isSource){this._changeState("Source",this==_41b?(copy?"Copied":"Moved"):"");}var _41d=this.accept&&this.checkAcceptance(_41b,_41c);this._changeState("Target",_41d?"":"Disabled");if(this==_41b){_412.manager().overSource(this);}this.isDragging=true;},onDndDrop:function(_41e,_41f,copy,_420){if(this==_420){this.onDrop(_41e,_41f,copy);}this.onDndCancel();},onDndCancel:function(){if(this.targetAnchor){this._unmarkTargetAnchor();this.targetAnchor=null;}this.before=true;this.isDragging=false;this.mouseDown=false;this._changeState("Source","");this._changeState("Target","");},onDrop:function(_421,_422,copy){if(this!=_421){this.onDropExternal(_421,_422,copy);}else{this.onDropInternal(_422,copy);}},onDropExternal:function(_423,_424,copy){var _425=this._normalizedCreator;if(this.creator){this._normalizedCreator=function(node,hint){return _425.call(this,_423.getItem(node.id).data,hint);};}else{if(copy){this._normalizedCreator=function(node,hint){var t=_423.getItem(node.id);var n=node.cloneNode(true);n.id=dojo.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}else{this._normalizedCreator=function(node,hint){var t=_423.getItem(node.id);_423.delItem(node.id);return {node:node,data:t.data,type:t.type};};}}this.selectNone();if(!copy&&!this.creator){_423.selectNone();}this.insertNodes(true,_424,this.before,this.current);if(!copy&&this.creator){_423.deleteSelectedNodes();}this._normalizedCreator=_425;},onDropInternal:function(_426,copy){var _427=this._normalizedCreator;if(this.current&&this.current.id in this.selection){return;}if(copy){if(this.creator){this._normalizedCreator=function(node,hint){return _427.call(this,this.getItem(node.id).data,hint);};}else{this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);var n=node.cloneNode(true);n.id=dojo.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}}else{if(!this.current){return;}this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);return {node:node,data:t.data,type:t.type};};}this._removeSelection();this.insertNodes(true,_426,this.before,this.current);this._normalizedCreator=_427;},onDraggingOver:function(){},onDraggingOut:function(){},onOverEvent:function(){dojo.dnd.Source.superclass.onOverEvent.call(this);_412.manager().overSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOver();}},onOutEvent:function(){dojo.dnd.Source.superclass.onOutEvent.call(this);_412.manager().outSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOut();}},_markTargetAnchor:function(_428){if(this.current==this.targetAnchor&&this.before==_428){return;}if(this.targetAnchor){this._removeItemClass(this.targetAnchor,this.before?"Before":"After");}this.targetAnchor=this.current;this.targetBox=null;this.before=_428;if(this.targetAnchor){this._addItemClass(this.targetAnchor,this.before?"Before":"After");}},_unmarkTargetAnchor:function(){if(!this.targetAnchor){return;}this._removeItemClass(this.targetAnchor,this.before?"Before":"After");this.targetAnchor=null;this.targetBox=null;this.before=true;},_markDndStatus:function(copy){this._changeState("Source",copy?"Copied":"Moved");},_legalMouseDown:function(e){if(!dojo.mouseButtons.isLeft(e)){return false;}if(!this.withHandles){return true;}for(var node=e.target;node&&node!==this.node;node=node.parentNode){if(dojo.hasClass(node,"dojoDndHandle")){return true;}if(dojo.hasClass(node,"dojoDndItem")||dojo.hasClass(node,"dojoDndIgnore")){break;}}return false;}});});},"dojox/grid/cells/_base":function(){define("dojox/grid/cells/_base",["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/event","dojo/_base/connect","dojo/_base/array","dojo/_base/sniff","dojo/dom","dojo/dom-attr","dojo/dom-construct","dijit/_Widget","../util"],function(dojo,_429,lang,_42a,_42b,_42c,has,dom,_42d,_42e,_42f,util){var _430=_429("dojox.grid._DeferredTextWidget",_42f,{deferred:null,_destroyOnRemove:true,postCreate:function(){if(this.deferred){this.deferred.addBoth(lang.hitch(this,function(text){if(this.domNode){this.domNode.innerHTML=text;}}));}}});var _431=function(_432){try{util.fire(_432,"focus");util.fire(_432,"select");}catch(e){}};var _433=function(){setTimeout(lang.hitch.apply(dojo,arguments),0);};var _434=_429("dojox.grid.cells._Base",null,{styles:"",classes:"",editable:false,alwaysEditing:false,formatter:null,defaultValue:"...",value:null,hidden:false,noresize:false,draggable:true,_valueProp:"value",_formatPending:false,constructor:function(_435){this._props=_435||{};lang.mixin(this,_435);if(this.draggable===undefined){this.draggable=true;}},_defaultFormat:function(_436,_437){var s=this.grid.formatterScope||this;var f=this.formatter;if(f&&s&&typeof f=="string"){f=this.formatter=s[f];}var v=(_436!=this.defaultValue&&f)?f.apply(s,_437):_436;if(typeof v=="undefined"){return this.defaultValue;}if(v&&v.addBoth){v=new _430({deferred:v},_42e.create("span",{innerHTML:this.defaultValue}));}if(v&&v.declaredClass&&v.startup){return "<div class='dojoxGridStubNode' linkWidget='"+v.id+"' cellIdx='"+this.index+"'>"+this.defaultValue+"</div>";}return v;},format:function(_438,_439){var f,i=this.grid.edit.info,d=this.get?this.get(_438,_439):(this.value||this.defaultValue);d=(d&&d.replace&&this.grid.escapeHTMLInData)?d.replace(/&/g,"&").replace(/</g,"<"):d;if(this.editable&&(this.alwaysEditing||(i.rowIndex==_438&&i.cell==this))){return this.formatEditing(d,_438);}else{return this._defaultFormat(d,[d,_438,this]);}},formatEditing:function(_43a,_43b){},getNode:function(_43c){return this.view.getCellNode(_43c,this.index);},getHeaderNode:function(){return this.view.getHeaderCellNode(this.index);},getEditNode:function(_43d){return (this.getNode(_43d)||0).firstChild||0;},canResize:function(){var uw=this.unitWidth;return uw&&(uw!=="auto");},isFlex:function(){var uw=this.unitWidth;return uw&&lang.isString(uw)&&(uw=="auto"||uw.slice(-1)=="%");},applyEdit:function(_43e,_43f){this.grid.edit.applyCellEdit(_43e,this,_43f);},cancelEdit:function(_440){this.grid.doCancelEdit(_440);},_onEditBlur:function(_441){if(this.grid.edit.isEditCell(_441,this.index)){this.grid.edit.apply();}},registerOnBlur:function(_442,_443){if(this.commitOnBlur){_42b.connect(_442,"onblur",function(e){setTimeout(lang.hitch(this,"_onEditBlur",_443),250);});}},needFormatNode:function(_444,_445){this._formatPending=true;_433(this,"_formatNode",_444,_445);},cancelFormatNode:function(){this._formatPending=false;},_formatNode:function(_446,_447){if(this._formatPending){this._formatPending=false;if(!has("ie")){dom.setSelectable(this.grid.domNode,true);}this.formatNode(this.getEditNode(_447),_446,_447);}},formatNode:function(_448,_449,_44a){if(has("ie")){_433(this,"focus",_44a,_448);}else{this.focus(_44a,_448);}},dispatchEvent:function(m,e){if(m in this){return this[m](e);}},getValue:function(_44b){return this.getEditNode(_44b)[this._valueProp];},setValue:function(_44c,_44d){var n=this.getEditNode(_44c);if(n){n[this._valueProp]=_44d;}},focus:function(_44e,_44f){_431(_44f||this.getEditNode(_44e));},save:function(_450){this.value=this.value||this.getValue(_450);},restore:function(_451){this.setValue(_451,this.value);},_finish:function(_452){dom.setSelectable(this.grid.domNode,false);this.cancelFormatNode();},apply:function(_453){this.applyEdit(this.getValue(_453),_453);this._finish(_453);},cancel:function(_454){this.cancelEdit(_454);this._finish(_454);}});_434.markupFactory=function(node,_455){var _456=lang.trim(_42d.get(node,"formatter")||"");if(_456){_455.formatter=lang.getObject(_456)||_456;}var get=lang.trim(_42d.get(node,"get")||"");if(get){_455.get=lang.getObject(get);}var _457=function(attr,cell,_458){var _459=lang.trim(_42d.get(node,attr)||"");if(_459){cell[_458||attr]=!(_459.toLowerCase()=="false");}};_457("sortDesc",_455);_457("editable",_455);_457("alwaysEditing",_455);_457("noresize",_455);_457("draggable",_455);var _45a=lang.trim(_42d.get(node,"loadingText")||_42d.get(node,"defaultValue")||"");if(_45a){_455.defaultValue=_45a;}var _45b=function(attr,cell,_45c){var _45d=lang.trim(_42d.get(node,attr)||"")||undefined;if(_45d){cell[_45c||attr]=_45d;}};_45b("styles",_455);_45b("headerStyles",_455);_45b("cellStyles",_455);_45b("classes",_455);_45b("headerClasses",_455);_45b("cellClasses",_455);};var Cell=_429("dojox.grid.cells.Cell",_434,{constructor:function(){this.keyFilter=this.keyFilter;},keyFilter:null,formatEditing:function(_45e,_45f){this.needFormatNode(_45e,_45f);return "<input class=\"dojoxGridInput\" type=\"text\" value=\""+_45e+"\">";},formatNode:function(_460,_461,_462){this.inherited(arguments);this.registerOnBlur(_460,_462);},doKey:function(e){if(this.keyFilter){var key=String.fromCharCode(e.charCode);if(key.search(this.keyFilter)==-1){_42a.stop(e);}}},_finish:function(_463){this.inherited(arguments);var n=this.getEditNode(_463);try{util.fire(n,"blur");}catch(e){}}});Cell.markupFactory=function(node,_464){_434.markupFactory(node,_464);var _465=lang.trim(_42d.get(node,"keyFilter")||"");if(_465){_464.keyFilter=new RegExp(_465);}};var _466=_429("dojox.grid.cells.RowIndex",Cell,{name:"Row",postscript:function(){this.editable=false;},get:function(_467){return _467+1;}});_466.markupFactory=function(node,_468){Cell.markupFactory(node,_468);};var _469=_429("dojox.grid.cells.Select",Cell,{options:null,values:null,returnIndex:-1,constructor:function(_46a){this.values=this.values||this.options;},formatEditing:function(_46b,_46c){this.needFormatNode(_46b,_46c);var h=["<select class=\"dojoxGridSelect\">"];for(var i=0,o,v;((o=this.options[i])!==undefined)&&((v=this.values[i])!==undefined);i++){v=v.replace?v.replace(/&/g,"&").replace(/</g,"<"):v;o=o.replace?o.replace(/&/g,"&").replace(/</g,"<"):o;h.push("<option",(_46b==v?" selected":"")," value=\""+v+"\"",">",o,"</option>");}h.push("</select>");return h.join("");},_defaultFormat:function(_46d,_46e){var v=this.inherited(arguments);if(!this.formatter&&this.values&&this.options){var i=_42c.indexOf(this.values,v);if(i>=0){v=this.options[i];}}return v;},getValue:function(_46f){var n=this.getEditNode(_46f);if(n){var i=n.selectedIndex,o=n.options[i];return this.returnIndex>-1?i:o.value||o.innerHTML;}}});_469.markupFactory=function(node,cell){Cell.markupFactory(node,cell);var _470=lang.trim(_42d.get(node,"options")||"");if(_470){var o=_470.split(",");if(o[0]!=_470){cell.options=o;}}var _471=lang.trim(_42d.get(node,"values")||"");if(_471){var v=_471.split(",");if(v[0]!=_471){cell.values=v;}}};var _472=_429("dojox.grid.cells.AlwaysEdit",Cell,{alwaysEditing:true,_formatNode:function(_473,_474){this.formatNode(this.getEditNode(_474),_473,_474);},applyStaticValue:function(_475){var e=this.grid.edit;e.applyCellEdit(this.getValue(_475),this,_475);e.start(this,_475,true);}});_472.markupFactory=function(node,cell){Cell.markupFactory(node,cell);};var Bool=_429("dojox.grid.cells.Bool",_472,{_valueProp:"checked",formatEditing:function(_476,_477){return "<input class=\"dojoxGridInput\" type=\"checkbox\""+(_476?" checked=\"checked\"":"")+" style=\"width: auto\" />";},doclick:function(e){if(e.target.tagName=="INPUT"){this.applyStaticValue(e.rowIndex);}}});Bool.markupFactory=function(node,cell){_472.markupFactory(node,cell);};return _434;});},"dijit/_WidgetBase":function(){define("dijit/_WidgetBase",["require","dojo/_base/array","dojo/aspect","dojo/_base/config","dojo/_base/connect","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/dom-construct","dojo/dom-geometry","dojo/dom-style","dojo/_base/kernel","dojo/_base/lang","dojo/on","dojo/ready","dojo/Stateful","dojo/topic","dojo/_base/window","./registry"],function(_478,_479,_47a,_47b,_47c,_47d,dom,_47e,_47f,_480,_481,_482,_483,lang,on,_484,_485,_486,win,_487){if(!_483.isAsync){_484(0,function(){var _488=["dijit/_base/manager"];_478(_488);});}var _489={};function _48a(obj){var ret={};for(var attr in obj){ret[attr.toLowerCase()]=true;}return ret;};function _48b(attr){return function(val){_47e[val?"set":"remove"](this.domNode,attr,val);this._set(attr,val);};};return _47d("dijit._WidgetBase",_485,{id:"",_setIdAttr:"domNode",lang:"",_setLangAttr:_48b("lang"),dir:"",_setDirAttr:_48b("dir"),textDir:"","class":"",_setClassAttr:{node:"domNode",type:"class"},style:"",title:"",tooltip:"",baseClass:"",srcNodeRef:null,domNode:null,containerNode:null,attributeMap:{},_blankGif:_47b.blankGif||_478.toUrl("dojo/resources/blank.gif"),postscript:function(_48c,_48d){this.create(_48c,_48d);},create:function(_48e,_48f){this.srcNodeRef=dom.byId(_48f);this._connects=[];this._supportingWidgets=[];if(this.srcNodeRef&&(typeof this.srcNodeRef.id=="string")){this.id=this.srcNodeRef.id;}if(_48e){this.params=_48e;lang.mixin(this,_48e);}this.postMixInProperties();if(!this.id){this.id=_487.getUniqueId(this.declaredClass.replace(/\./g,"_"));}_487.add(this);this.buildRendering();if(this.domNode){this._applyAttributes();var _490=this.srcNodeRef;if(_490&&_490.parentNode&&this.domNode!==_490){_490.parentNode.replaceChild(this.domNode,_490);}}if(this.domNode){this.domNode.setAttribute("widgetId",this.id);}this.postCreate();if(this.srcNodeRef&&!this.srcNodeRef.parentNode){delete this.srcNodeRef;}this._created=true;},_applyAttributes:function(){var ctor=this.constructor,list=ctor._setterAttrs;if(!list){list=(ctor._setterAttrs=[]);for(var attr in this.attributeMap){list.push(attr);}var _491=ctor.prototype;for(var _492 in _491){if(_492 in this.attributeMap){continue;}var _493="_set"+_492.replace(/^[a-z]|-[a-zA-Z]/g,function(c){return c.charAt(c.length-1).toUpperCase();})+"Attr";if(_493 in _491){list.push(_492);}}}_479.forEach(list,function(attr){if(this.params&&attr in this.params){}else{if(this[attr]){this.set(attr,this[attr]);}}},this);for(var _494 in this.params){this.set(_494,this[_494]);}},postMixInProperties:function(){},buildRendering:function(){if(!this.domNode){this.domNode=this.srcNodeRef||_480.create("div");}if(this.baseClass){var _495=this.baseClass.split(" ");if(!this.isLeftToRight()){_495=_495.concat(_479.map(_495,function(name){return name+"Rtl";}));}_47f.add(this.domNode,_495);}},postCreate:function(){},startup:function(){if(this._started){return;}this._started=true;_479.forEach(this.getChildren(),function(obj){if(!obj._started&&!obj._destroyed&&lang.isFunction(obj.startup)){obj.startup();obj._started=true;}});},destroyRecursive:function(_496){this._beingDestroyed=true;this.destroyDescendants(_496);this.destroy(_496);},destroy:function(_497){this._beingDestroyed=true;this.uninitialize();var c;while(c=this._connects.pop()){c.remove();}var w;while(w=this._supportingWidgets.pop()){if(w.destroyRecursive){w.destroyRecursive();}else{if(w.destroy){w.destroy();}}}this.destroyRendering(_497);_487.remove(this.id);this._destroyed=true;},destroyRendering:function(_498){if(this.bgIframe){this.bgIframe.destroy(_498);delete this.bgIframe;}if(this.domNode){if(_498){_47e.remove(this.domNode,"widgetId");}else{_480.destroy(this.domNode);}delete this.domNode;}if(this.srcNodeRef){if(!_498){_480.destroy(this.srcNodeRef);}delete this.srcNodeRef;}},destroyDescendants:function(_499){_479.forEach(this.getChildren(),function(_49a){if(_49a.destroyRecursive){_49a.destroyRecursive(_499);}});},uninitialize:function(){return false;},_setStyleAttr:function(_49b){var _49c=this.domNode;if(lang.isObject(_49b)){_482.set(_49c,_49b);}else{if(_49c.style.cssText){_49c.style.cssText+="; "+_49b;}else{_49c.style.cssText=_49b;}}this._set("style",_49b);},_attrToDom:function(attr,_49d,_49e){_49e=arguments.length>=3?_49e:this.attributeMap[attr];_479.forEach(lang.isArray(_49e)?_49e:[_49e],function(_49f){var _4a0=this[_49f.node||_49f||"domNode"];var type=_49f.type||"attribute";switch(type){case "attribute":if(lang.isFunction(_49d)){_49d=lang.hitch(this,_49d);}var _4a1=_49f.attribute?_49f.attribute:(/^on[A-Z][a-zA-Z]*$/.test(attr)?attr.toLowerCase():attr);_47e.set(_4a0,_4a1,_49d);break;case "innerText":_4a0.innerHTML="";_4a0.appendChild(win.doc.createTextNode(_49d));break;case "innerHTML":_4a0.innerHTML=_49d;break;case "class":_47f.replace(_4a0,_49d,this[attr]);break;}},this);},get:function(name){var _4a2=this._getAttrNames(name);return this[_4a2.g]?this[_4a2.g]():this[name];},set:function(name,_4a3){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _4a4=this._getAttrNames(name),_4a5=this[_4a4.s];if(lang.isFunction(_4a5)){var _4a6=_4a5.apply(this,Array.prototype.slice.call(arguments,1));}else{var _4a7=this.focusNode&&!lang.isFunction(this.focusNode)?"focusNode":"domNode",tag=this[_4a7].tagName,_4a8=_489[tag]||(_489[tag]=_48a(this[_4a7])),map=name in this.attributeMap?this.attributeMap[name]:_4a4.s in this?this[_4a4.s]:((_4a4.l in _4a8&&typeof _4a3!="function")||/^aria-|^data-|^role$/.test(name))?_4a7:null;if(map!=null){this._attrToDom(name,_4a3,map);}this._set(name,_4a3);}return _4a6||this;},_attrPairNames:{},_getAttrNames:function(name){var apn=this._attrPairNames;if(apn[name]){return apn[name];}var uc=name.replace(/^[a-z]|-[a-zA-Z]/g,function(c){return c.charAt(c.length-1).toUpperCase();});return (apn[name]={n:name+"Node",s:"_set"+uc+"Attr",g:"_get"+uc+"Attr",l:uc.toLowerCase()});},_set:function(name,_4a9){var _4aa=this[name];this[name]=_4a9;if(this._watchCallbacks&&this._created&&_4a9!==_4aa){this._watchCallbacks(name,_4aa,_4a9);}},on:function(type,func){return _47a.after(this,this._onMap(type),func,true);},_onMap:function(type){var ctor=this.constructor,map=ctor._onMap;if(!map){map=(ctor._onMap={});for(var attr in ctor.prototype){if(/^on/.test(attr)){map[attr.replace(/^on/,"").toLowerCase()]=attr;}}}return map[type.toLowerCase()];},toString:function(){return "[Widget "+this.declaredClass+", "+(this.id||"NO ID")+"]";},getChildren:function(){return this.containerNode?_487.findWidgets(this.containerNode):[];},getParent:function(){return _487.getEnclosingWidget(this.domNode.parentNode);},connect:function(obj,_4ab,_4ac){var _4ad=_47c.connect(obj,_4ab,this,_4ac);this._connects.push(_4ad);return _4ad;},disconnect:function(_4ae){var i=_479.indexOf(this._connects,_4ae);if(i!=-1){_4ae.remove();this._connects.splice(i,1);}},subscribe:function(t,_4af){var _4b0=_486.subscribe(t,lang.hitch(this,_4af));this._connects.push(_4b0);return _4b0;},unsubscribe:function(_4b1){this.disconnect(_4b1);},isLeftToRight:function(){return this.dir?(this.dir=="ltr"):_481.isBodyLtr();},isFocusable:function(){return this.focus&&(_482.get(this.domNode,"display")!="none");},placeAt:function(_4b2,_4b3){if(_4b2.declaredClass&&_4b2.addChild){_4b2.addChild(this,_4b3);}else{_480.place(this.domNode,_4b2,_4b3);}return this;},getTextDir:function(text,_4b4){return _4b4;},applyTextDir:function(){}});});},"dojo/dnd/Moveable":function(){define(["../main","../Evented","../touch","./Mover"],function(dojo,_4b5,_4b6){dojo.declare("dojo.dnd.Moveable",[_4b5],{handle:"",delay:0,skip:false,constructor:function(node,_4b7){this.node=dojo.byId(node);if(!_4b7){_4b7={};}this.handle=_4b7.handle?dojo.byId(_4b7.handle):null;if(!this.handle){this.handle=this.node;}this.delay=_4b7.delay>0?_4b7.delay:0;this.skip=_4b7.skip;this.mover=_4b7.mover?_4b7.mover:dojo.dnd.Mover;this.events=[dojo.connect(this.handle,_4b6.press,this,"onMouseDown"),dojo.connect(this.handle,"ondragstart",this,"onSelectStart"),dojo.connect(this.handle,"onselectstart",this,"onSelectStart")];},markupFactory:function(_4b8,node,ctor){return new ctor(node,_4b8);},destroy:function(){dojo.forEach(this.events,dojo.disconnect);this.events=this.node=this.handle=null;},onMouseDown:function(e){if(this.skip&&dojo.dnd.isFormElement(e)){return;}if(this.delay){this.events.push(dojo.connect(this.handle,_4b6.move,this,"onMouseMove"),dojo.connect(this.handle,_4b6.release,this,"onMouseUp"));this._lastX=e.pageX;this._lastY=e.pageY;}else{this.onDragDetected(e);}dojo.stopEvent(e);},onMouseMove:function(e){if(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay){this.onMouseUp(e);this.onDragDetected(e);}dojo.stopEvent(e);},onMouseUp:function(e){for(var i=0;i<2;++i){dojo.disconnect(this.events.pop());}dojo.stopEvent(e);},onSelectStart:function(e){if(!this.skip||!dojo.dnd.isFormElement(e)){dojo.stopEvent(e);}},onDragDetected:function(e){new this.mover(this.node,e,this);},onMoveStart:function(_4b9){dojo.publish("/dnd/move/start",[_4b9]);dojo.addClass(dojo.body(),"dojoMove");dojo.addClass(this.node,"dojoMoveItem");},onMoveStop:function(_4ba){dojo.publish("/dnd/move/stop",[_4ba]);dojo.removeClass(dojo.body(),"dojoMove");dojo.removeClass(this.node,"dojoMoveItem");},onFirstMove:function(_4bb,e){},onMove:function(_4bc,_4bd,e){this.onMoving(_4bc,_4bd);var s=_4bc.node.style;s.left=_4bd.l+"px";s.top=_4bd.t+"px";this.onMoved(_4bc,_4bd);},onMoving:function(_4be,_4bf){},onMoved:function(_4c0,_4c1){}});return dojo.dnd.Moveable;});}}});require(["dojo/i18n"],function(i18n){i18n._preloadLocalizations("dojox/grid/nls/DataGrid",["nl-nl","en-us","da","fi-fi","pt-pt","hu","sk","sl","pl","ca","sv","zh-tw","ar","en-gb","he-il","de-de","ko-kr","ja-jp","nb","ru","es-es","th","cs","it-it","pt-br","fr-fr","el","tr","zh-cn"]);});define("dojox/grid/DataGrid",["../main","dojo/_base/array","dojo/_base/lang","dojo/_base/json","dojo/_base/sniff","dojo/_base/declare","./_Grid","./DataSelection","dojo/_base/html"],function(_4c2,_4c3,lang,json,has,_4c4,_4c5,_4c6,html){var _4c7=_4c4("dojox.grid.DataGrid",_4c5,{store:null,query:null,queryOptions:null,fetchText:"...",sortFields:null,updateDelay:1,items:null,_store_connects:null,_by_idty:null,_by_idx:null,_cache:null,_pages:null,_pending_requests:null,_bop:-1,_eop:-1,_requests:0,rowCount:0,_isLoaded:false,_isLoading:false,keepSelection:false,postCreate:function(){this._pages=[];this._store_connects=[];this._by_idty={};this._by_idx=[];this._cache=[];this._pending_requests={};this._setStore(this.store);this.inherited(arguments);},destroy:function(){this.selection.destroy();this.inherited(arguments);},createSelection:function(){this.selection=new _4c6(this);},get:function(_4c8,_4c9){if(_4c9&&this.field=="_item"&&!this.fields){return _4c9;}else{if(_4c9&&this.fields){var ret=[];var s=this.grid.store;_4c3.forEach(this.fields,function(f){ret=ret.concat(s.getValues(_4c9,f));});return ret;}else{if(!_4c9&&typeof _4c8==="string"){return this.inherited(arguments);}}}return (!_4c9?this.defaultValue:(!this.field?this.value:(this.field=="_item"?_4c9:this.grid.store.getValue(_4c9,this.field))));},_checkUpdateStatus:function(){if(this.updateDelay>0){var _4ca=false;if(this._endUpdateDelay){clearTimeout(this._endUpdateDelay);delete this._endUpdateDelay;_4ca=true;}if(!this.updating){this.beginUpdate();_4ca=true;}if(_4ca){var _4cb=this;this._endUpdateDelay=setTimeout(function(){delete _4cb._endUpdateDelay;_4cb.endUpdate();},this.updateDelay);}}},_onSet:function(item,_4cc,_4cd,_4ce){this._checkUpdateStatus();var idx=this.getItemIndex(item);if(idx>-1){this.updateRow(idx);}},_createItem:function(item,_4cf){var idty=this._hasIdentity?this.store.getIdentity(item):json.toJson(this.query)+":idx:"+_4cf+":sort:"+json.toJson(this.getSortProps());var o=this._by_idty[idty]={idty:idty,item:item};return o;},_addItem:function(item,_4d0,_4d1){this._by_idx[_4d0]=this._createItem(item,_4d0);if(!_4d1){this.updateRow(_4d0);}},_onNew:function(item,_4d2){this._checkUpdateStatus();var _4d3=this.get("rowCount");this._addingItem=true;this.updateRowCount(_4d3+1);this._addingItem=false;this._addItem(item,_4d3);this.showMessage();},_onDelete:function(item){this._checkUpdateStatus();var idx=this._getItemIndex(item,true);if(idx>=0){this._pages=[];this._bop=-1;this._eop=-1;var o=this._by_idx[idx];this._by_idx.splice(idx,1);delete this._by_idty[o.idty];this.updateRowCount(this.get("rowCount")-1);if(this.get("rowCount")===0){this.showMessage(this.noDataMessage);}}if(this.selection.isSelected(idx)){this.selection.deselect(idx);this.selection.selected.splice(idx,1);}},_onRevert:function(){this._refresh();},setStore:function(_4d4,_4d5,_4d6){if(this._requestsPending(0)){return;}this._setQuery(_4d5,_4d6);this._setStore(_4d4);this._refresh(true);},setQuery:function(_4d7,_4d8){if(this._requestsPending(0)){return;}this._setQuery(_4d7,_4d8);this._refresh(true);},setItems:function(_4d9){this.items=_4d9;this._setStore(this.store);this._refresh(true);},_setQuery:function(_4da,_4db){this.query=_4da;this.queryOptions=_4db||this.queryOptions;},_setStore:function(_4dc){if(this.store&&this._store_connects){_4c3.forEach(this._store_connects,this.disconnect,this);}this.store=_4dc;if(this.store){var f=this.store.getFeatures();var h=[];this._canEdit=!!f["dojo.data.api.Write"]&&!!f["dojo.data.api.Identity"];this._hasIdentity=!!f["dojo.data.api.Identity"];if(!!f["dojo.data.api.Notification"]&&!this.items){h.push(this.connect(this.store,"onSet","_onSet"));h.push(this.connect(this.store,"onNew","_onNew"));h.push(this.connect(this.store,"onDelete","_onDelete"));}if(this._canEdit){h.push(this.connect(this.store,"revert","_onRevert"));}this._store_connects=h;}},_onFetchBegin:function(size,req){if(!this.scroller){return;}if(this.rowCount!=size){if(req.isRender){this.scroller.init(size,this.keepRows,this.rowsPerPage);this.rowCount=size;this._setAutoHeightAttr(this.autoHeight,true);this._skipRowRenormalize=true;this.prerender();this._skipRowRenormalize=false;}else{this.updateRowCount(size);}}if(!size){this.views.render();this._resize();this.showMessage(this.noDataMessage);this.focus.initFocusView();}else{this.showMessage();}},_onFetchComplete:function(_4dd,req){if(!this.scroller){return;}if(_4dd&&_4dd.length>0){_4c3.forEach(_4dd,function(item,idx){this._addItem(item,req.start+idx,true);},this);this.updateRows(req.start,_4dd.length);if(req.isRender){this.setScrollTop(0);this.postrender();}else{if(this._lastScrollTop){this.setScrollTop(this._lastScrollTop);}}if(has("ie")){html.setSelectable(this.domNode,this.selectable);}}delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;}this._pending_requests[req.start]=false;},_onFetchError:function(err,req){delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;this.showMessage(this.errorMessage);}this._pending_requests[req.start]=false;this.onFetchError(err,req);},onFetchError:function(err,req){},_fetch:function(_4de,_4df){_4de=_4de||0;if(this.store&&!this._pending_requests[_4de]){if(!this._isLoaded&&!this._isLoading){this._isLoading=true;this.showMessage(this.loadingMessage);}this._pending_requests[_4de]=true;try{if(this.items){var _4e0=this.items;var _4e1=this.store;this.rowsPerPage=_4e0.length;var req={start:_4de,count:this.rowsPerPage,isRender:_4df};this._onFetchBegin(_4e0.length,req);var _4e2=0;_4c3.forEach(_4e0,function(i){if(!_4e1.isItemLoaded(i)){_4e2++;}});if(_4e2===0){this._onFetchComplete(_4e0,req);}else{var _4e3=function(item){_4e2--;if(_4e2===0){this._onFetchComplete(_4e0,req);}};_4c3.forEach(_4e0,function(i){if(!_4e1.isItemLoaded(i)){_4e1.loadItem({item:i,onItem:_4e3,scope:this});}},this);}}else{this.store.fetch({start:_4de,count:this.rowsPerPage,query:this.query,sort:this.getSortProps(),queryOptions:this.queryOptions,isRender:_4df,onBegin:lang.hitch(this,"_onFetchBegin"),onComplete:lang.hitch(this,"_onFetchComplete"),onError:lang.hitch(this,"_onFetchError")});}}catch(e){this._onFetchError(e,{start:_4de,count:this.rowsPerPage});}}},_clearData:function(){this.updateRowCount(0);this._by_idty={};this._by_idx=[];this._pages=[];this._bop=this._eop=-1;this._isLoaded=false;this._isLoading=false;},getItem:function(idx){var data=this._by_idx[idx];if(!data||(data&&!data.item)){this._preparePage(idx);return null;}return data.item;},getItemIndex:function(item){return this._getItemIndex(item,false);},_getItemIndex:function(item,_4e4){if(!_4e4&&!this.store.isItem(item)){return -1;}var idty=this._hasIdentity?this.store.getIdentity(item):null;for(var i=0,l=this._by_idx.length;i<l;i++){var d=this._by_idx[i];if(d&&((idty&&d.idty==idty)||(d.item===item))){return i;}}return -1;},filter:function(_4e5,_4e6){this.query=_4e5;if(_4e6){this._clearData();}this._fetch();},_getItemAttr:function(idx,attr){var item=this.getItem(idx);return (!item?this.fetchText:this.store.getValue(item,attr));},_render:function(){if(this.domNode.parentNode){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this._fetch(0,true);}},_requestsPending:function(_4e7){return this._pending_requests[_4e7];},_rowToPage:function(_4e8){return (this.rowsPerPage?Math.floor(_4e8/this.rowsPerPage):_4e8);},_pageToRow:function(_4e9){return (this.rowsPerPage?this.rowsPerPage*_4e9:_4e9);},_preparePage:function(_4ea){if((_4ea<this._bop||_4ea>=this._eop)&&!this._addingItem){var _4eb=this._rowToPage(_4ea);this._needPage(_4eb);this._bop=_4eb*this.rowsPerPage;this._eop=this._bop+(this.rowsPerPage||this.get("rowCount"));}},_needPage:function(_4ec){if(!this._pages[_4ec]){this._pages[_4ec]=true;this._requestPage(_4ec);}},_requestPage:function(_4ed){var row=this._pageToRow(_4ed);var _4ee=Math.min(this.rowsPerPage,this.get("rowCount")-row);if(_4ee>0){this._requests++;if(!this._requestsPending(row)){setTimeout(lang.hitch(this,"_fetch",row,false),1);}}},getCellName:function(_4ef){return _4ef.field;},_refresh:function(_4f0){this._clearData();this._fetch(0,_4f0);},sort:function(){this.edit.apply();this._lastScrollTop=this.scrollTop;this._refresh();},canSort:function(){return (!this._isLoading);},getSortProps:function(){var c=this.getCell(this.getSortIndex());if(!c){if(this.sortFields){return this.sortFields;}return null;}else{var desc=c["sortDesc"];var si=!(this.sortInfo>0);if(typeof desc=="undefined"){desc=si;}else{desc=si?!desc:desc;}return [{attribute:c.field,descending:desc}];}},styleRowState:function(_4f1){if(this.store&&this.store.getState){var _4f2=this.store.getState(_4f1.index),c="";for(var i=0,ss=["inflight","error","inserting"],s;s=ss[i];i++){if(_4f2[s]){c=" dojoxGridRow-"+s;break;}}_4f1.customClasses+=c;}},onStyleRow:function(_4f3){this.styleRowState(_4f3);this.inherited(arguments);},canEdit:function(_4f4,_4f5){return this._canEdit;},_copyAttr:function(idx,attr){var row={};var _4f6={};var src=this.getItem(idx);return this.store.getValue(src,attr);},doStartEdit:function(_4f7,_4f8){if(!this._cache[_4f8]){this._cache[_4f8]=this._copyAttr(_4f8,_4f7.field);}this.onStartEdit(_4f7,_4f8);},doApplyCellEdit:function(_4f9,_4fa,_4fb){this.store.fetchItemByIdentity({identity:this._by_idx[_4fa].idty,onItem:lang.hitch(this,function(item){var _4fc=this.store.getValue(item,_4fb);if(typeof _4fc=="number"){_4f9=isNaN(_4f9)?_4f9:parseFloat(_4f9);}else{if(typeof _4fc=="boolean"){_4f9=_4f9=="true"?true:_4f9=="false"?false:_4f9;}else{if(_4fc instanceof Date){var _4fd=new Date(_4f9);_4f9=isNaN(_4fd.getTime())?_4f9:_4fd;}}}this.store.setValue(item,_4fb,_4f9);this.onApplyCellEdit(_4f9,_4fa,_4fb);})});},doCancelEdit:function(_4fe){var _4ff=this._cache[_4fe];if(_4ff){this.updateRow(_4fe);delete this._cache[_4fe];}this.onCancelEdit.apply(this,arguments);},doApplyEdit:function(_500,_501){var _502=this._cache[_500];this.onApplyEdit(_500);},removeSelectedRows:function(){if(this._canEdit){this.edit.apply();var fx=lang.hitch(this,function(_503){if(_503.length){_4c3.forEach(_503,this.store.deleteItem,this.store);this.selection.clear();}});if(this.allItemsSelected){this.store.fetch({query:this.query,queryOptions:this.queryOptions,onComplete:fx});}else{fx(this.selection.getSelected());}}}});_4c7.cell_markupFactory=function(_504,node,_505){var _506=lang.trim(html.attr(node,"field")||"");if(_506){_505.field=_506;}_505.field=_505.field||_505.name;var _507=lang.trim(html.attr(node,"fields")||"");if(_507){_505.fields=_507.split(",");}if(_504){_504(node,_505);}};_4c7.markupFactory=function(_508,node,ctor,_509){return _4c5.markupFactory(_508,node,ctor,lang.partial(_4c7.cell_markupFactory,_509));};return _4c7;});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js b/js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js new file mode 100644 index 0000000..de77929 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js @@ -0,0 +1,14486 @@ +/* + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +/* + This is an optimized version of Dojo, built for deployment and not for + development. To get sources and documentation, please visit: + + http://dojotoolkit.org +*/ + +//>>built +require({cache:{ +'dojo/uacss':function(){ +define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/window"], + function(geometry, lang, ready, has, baseWindow){ + // module: + // dojo/uacss + // summary: + // Applies pre-set CSS classes to the top-level HTML node, based on: + // - browser (ex: dj_ie) + // - browser version (ex: dj_ie6) + // - box model (ex: dj_contentBox) + // - text direction (ex: dijitRtl) + // + // In addition, browser, browser version, and box model are + // combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl. + + var + html = baseWindow.doc.documentElement, + ie = has("ie"), + opera = has("opera"), + maj = Math.floor, + ff = has("ff"), + boxModel = geometry.boxModel.replace(/-/,''), + + classes = { + "dj_ie": ie, + "dj_ie6": maj(ie) == 6, + "dj_ie7": maj(ie) == 7, + "dj_ie8": maj(ie) == 8, + "dj_ie9": maj(ie) == 9, + "dj_quirks": has("quirks"), + "dj_iequirks": ie && has("quirks"), + + // NOTE: Opera not supported by dijit + "dj_opera": opera, + + "dj_khtml": has("khtml"), + + "dj_webkit": has("webkit"), + "dj_safari": has("safari"), + "dj_chrome": has("chrome"), + + "dj_gecko": has("mozilla"), + "dj_ff3": maj(ff) == 3 + }; // no dojo unsupported browsers + + classes["dj_" + boxModel] = true; + + // apply browser, browser version, and box model class names + var classStr = ""; + for(var clz in classes){ + if(classes[clz]){ + classStr += clz + " "; + } + } + html.className = lang.trim(html.className + " " + classStr); + + // If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension. + // We can't run the code below until the <body> tag has loaded (so we can check for dir=rtl). + // priority is 90 to run ahead of parser priority of 100 + ready(90, function(){ + if(!geometry.isBodyLtr()){ + var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl "); + html.className = lang.trim(html.className + " " + rtlClassStr + "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ")); + } + }); + return has; +}); + +}, +'dijit/hccss':function(){ +define("dijit/hccss", [ + "require", // require.toUrl + "dojo/_base/config", // config.blankGif + "dojo/dom-class", // domClass.add domConstruct.create domStyle.getComputedStyle + "dojo/dom-construct", // domClass.add domConstruct.create domStyle.getComputedStyle + "dojo/dom-style", // domClass.add domConstruct.create domStyle.getComputedStyle + "dojo/ready", // ready + "dojo/_base/sniff", // has("ie") has("mozilla") + "dojo/_base/window" // win.body +], function(require, config, domClass, domConstruct, domStyle, ready, has, win){ + + // module: + // dijit/hccss + // summary: + // Test if computer is in high contrast mode, and sets dijit_a11y flag on <body> if it is. + + if(has("ie") || has("mozilla")){ // NOTE: checking in Safari messes things up + // priority is 90 to run ahead of parser priority of 100 + ready(90, function(){ + // summary: + // Detects if we are in high-contrast mode or not + + // create div for testing if high contrast mode is on or images are turned off + var div = domConstruct.create("div",{ + id: "a11yTestNode", + style:{ + cssText:'border: 1px solid;' + + 'border-color:red green;' + + 'position: absolute;' + + 'height: 5px;' + + 'top: -999px;' + + 'background-image: url("' + (config.blankGif || require.toUrl("dojo/resources/blank.gif")) + '");' + } + }, win.body()); + + // test it + var cs = domStyle.getComputedStyle(div); + if(cs){ + var bkImg = cs.backgroundImage; + var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" )); + if(needsA11y){ + domClass.add(win.body(), "dijit_a11y"); + } + if(has("ie")){ + div.outerHTML = ""; // prevent mixed-content warning, see http://support.microsoft.com/kb/925014 + }else{ + win.body().removeChild(div); + } + } + }); + } +}); + +}, +'dojox/grid/_View':function(){ +require({cache:{ +'url:dojox/grid/resources/View.html':"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n"}}); +define("dojox/grid/_View", [ + "dojo", + "dijit/registry", + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/connect", + "dojo/_base/sniff", + "dojo/query", + "dojo/_base/window", + "dojo/text!./resources/View.html", + "dojo/dnd/Source", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dojox/html/metrics", + "./util", + "dojo/_base/html", + "./_Builder", + "dojo/dnd/Avatar", + "dojo/dnd/Manager" +], function(dojo, dijit, dojox, declare, array, lang, connect, has, query, + win, template, Source, _Widget, _TemplatedMixin, metrics, util, html, _Builder, Avatar){ + + // a private function + var getStyleText = function(inNode, inStyleText){ + return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText; + }; + + // some public functions + var _View = declare('dojox.grid._View', [_Widget, _TemplatedMixin], { + // summary: + // A collection of grid columns. A grid is comprised of a set of views that stack horizontally. + // Grid creates views automatically based on grid's layout structure. + // Users should typically not need to access individual views directly. + // + // defaultWidth: String + // Default width of the view + defaultWidth: "18em", + + // viewWidth: String + // Width for the view, in valid css unit + viewWidth: "", + + templateString: template, + + themeable: false, + classTag: 'dojoxGrid', + marginBottom: 0, + rowPad: 2, + + // _togglingColumn: int + // Width of the column being toggled (-1 for none) + _togglingColumn: -1, + + // _headerBuilderClass: Object + // The class to use for our header builder + _headerBuilderClass: _Builder._HeaderBuilder, + + // _contentBuilderClass: Object + // The class to use for our content builder + _contentBuilderClass: _Builder._ContentBuilder, + + postMixInProperties: function(){ + this.rowNodes = {}; + }, + + postCreate: function(){ + this.connect(this.scrollboxNode,"onscroll","doscroll"); + util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]); + util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]); + this.content = new this._contentBuilderClass(this); + this.header = new this._headerBuilderClass(this); + //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node + if(!this.grid.isLeftToRight()){ + this.headerNodeContainer.style.width = ""; + } + }, + + destroy: function(){ + html.destroy(this.headerNode); + delete this.headerNode; + for(var i in this.rowNodes){ + this._cleanupRowWidgets(this.rowNodes[i]); + html.destroy(this.rowNodes[i]); + } + this.rowNodes = {}; + if(this.source){ + this.source.destroy(); + } + this.inherited(arguments); + }, + + // focus + focus: function(){ + if(has("ie") || has("webkit") || has("opera")){ + this.hiddenFocusNode.focus(); + }else{ + this.scrollboxNode.focus(); + } + }, + + setStructure: function(inStructure){ + var vs = (this.structure = inStructure); + // FIXME: similar logic is duplicated in layout + if(vs.width && !isNaN(vs.width)){ + this.viewWidth = vs.width + 'em'; + }else{ + this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth; + } + this._onBeforeRow = vs.onBeforeRow||function(){}; + this._onAfterRow = vs.onAfterRow||function(){}; + this.noscroll = vs.noscroll; + if(this.noscroll){ + this.scrollboxNode.style.overflow = "hidden"; + } + this.simpleStructure = Boolean(vs.cells.length == 1); + // bookkeeping + this.testFlexCells(); + // accomodate new structure + this.updateStructure(); + }, + + _cleanupRowWidgets: function(inRowNode){ + // Summary: + // Cleans up the widgets for the given row node so that + // we can reattach them if needed + if(inRowNode){ + array.forEach(query("[widgetId]", inRowNode).map(dijit.byNode), function(w){ + if(w._destroyOnRemove){ + w.destroy(); + delete w; + }else if(w.domNode && w.domNode.parentNode){ + w.domNode.parentNode.removeChild(w.domNode); + } + }); + } + }, + + onBeforeRow: function(inRowIndex, cells){ + this._onBeforeRow(inRowIndex, cells); + if(inRowIndex >= 0){ + this._cleanupRowWidgets(this.getRowNode(inRowIndex)); + } + }, + + onAfterRow: function(inRowIndex, cells, inRowNode){ + this._onAfterRow(inRowIndex, cells, inRowNode); + var g = this.grid; + array.forEach(query(".dojoxGridStubNode", inRowNode), function(n){ + if(n && n.parentNode){ + var lw = n.getAttribute("linkWidget"); + var cellIdx = window.parseInt(html.attr(n, "cellIdx"), 10); + var cellDef = g.getCell(cellIdx); + var w = dijit.byId(lw); + if(w){ + n.parentNode.replaceChild(w.domNode, n); + if(!w._started){ + w.startup(); + } + dojo.destroy(n); + }else{ + n.innerHTML = ""; + } + } + }, this); + }, + + testFlexCells: function(){ + // FIXME: cheater, this function does double duty as initializer and tester + this.flexCells = false; + for(var j=0, row; (row=this.structure.cells[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + cell.view = this; + this.flexCells = this.flexCells || cell.isFlex(); + } + } + return this.flexCells; + }, + + updateStructure: function(){ + // header builder needs to update table map + this.header.update(); + // content builder needs to update markup cache + this.content.update(); + }, + + getScrollbarWidth: function(){ + var hasScrollSpace = this.hasVScrollbar(); + var overflow = html.style(this.scrollboxNode, "overflow"); + if(this.noscroll || !overflow || overflow == "hidden"){ + hasScrollSpace = false; + }else if(overflow == "scroll"){ + hasScrollSpace = true; + } + return (hasScrollSpace ? metrics.getScrollbar().w : 0); // Integer + }, + + getColumnsWidth: function(){ + var h = this.headerContentNode; + return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer + }, + + setColumnsWidth: function(width){ + this.headerContentNode.firstChild.style.width = width + 'px'; + if(this.viewWidth){ + this.viewWidth = width + 'px'; + } + }, + + getWidth: function(){ + return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String + }, + + getContentWidth: function(){ + return Math.max(0, html._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String + }, + + render: function(){ + this.scrollboxNode.style.height = ''; + this.renderHeader(); + if(this._togglingColumn >= 0){ + this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn); + this._togglingColumn = -1; + } + var cells = this.grid.layout.cells; + var getSibling = lang.hitch(this, function(node, before){ + !this.grid.isLeftToRight() && (before = !before); + var inc = before?-1:1; + var idx = this.header.getCellNodeIndex(node) + inc; + var cell = cells[idx]; + while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){ + idx += inc; + cell = cells[idx]; + } + if(cell){ + return cell.getHeaderNode(); + } + return null; + }); + if(this.grid.columnReordering && this.simpleStructure){ + if(this.source){ + this.source.destroy(); + } + + // Create the top and bottom markers + var bottomMarkerId = "dojoxGrid_bottomMarker"; + var topMarkerId = "dojoxGrid_topMarker"; + if(this.bottomMarker){ + html.destroy(this.bottomMarker); + } + this.bottomMarker = html.byId(bottomMarkerId); + if(this.topMarker){ + html.destroy(this.topMarker); + } + this.topMarker = html.byId(topMarkerId); + if (!this.bottomMarker) { + this.bottomMarker = html.create("div", { + "id": bottomMarkerId, + "class": "dojoxGridColPlaceBottom" + }, win.body()); + this._hide(this.bottomMarker); + + + this.topMarker = html.create("div", { + "id": topMarkerId, + "class": "dojoxGridColPlaceTop" + }, win.body()); + this._hide(this.topMarker); + } + this.arrowDim = html.contentBox(this.bottomMarker); + + var headerHeight = html.contentBox(this.headerContentNode.firstChild.rows[0]).h; + + this.source = new Source(this.headerContentNode.firstChild.rows[0], { + horizontal: true, + accept: [ "gridColumn_" + this.grid.id ], + viewIndex: this.index, + generateText: false, + onMouseDown: lang.hitch(this, function(e){ + this.header.decorateEvent(e); + if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) && + this.header.canResize(e) && !this.header.moveable){ + this.header.beginColumnResize(e); + }else{ + if(this.grid.headerMenu){ + this.grid.headerMenu.onCancel(true); + } + // IE reports a left click as 1, where everything else reports 0 + if(e.button === (has("ie") < 9 ? 1 : 0)){ + Source.prototype.onMouseDown.call(this.source, e); + } + } + }), + onMouseOver: lang.hitch(this, function(e){ + var src = this.source; + if(src._getChildByEvent(e)){ + Source.prototype.onMouseOver.apply(src, arguments); + } + }), + _markTargetAnchor: lang.hitch(this, function(before){ + var src = this.source; + if(src.current == src.targetAnchor && src.before == before){ return; } + if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){ + src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before"); + } + Source.prototype._markTargetAnchor.call(src, before); + + var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before); + var endAdd = 0; + + if (!target) { + target = src.targetAnchor; + endAdd = html.contentBox(target).w + this.arrowDim.w/2 + 2; + } + + var pos = html.position(target, true); + var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd); + + html.style(this.bottomMarker, "visibility", "visible"); + html.style(this.topMarker, "visibility", "visible"); + html.style(this.bottomMarker, { + "left": left + "px", + "top" : (headerHeight + pos.y) + "px" + }); + + html.style(this.topMarker, { + "left": left + "px", + "top" : (pos.y - this.arrowDim.h) + "px" + }); + + if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){ + src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before"); + } + }), + _unmarkTargetAnchor: lang.hitch(this, function(){ + var src = this.source; + if(!src.targetAnchor){ return; } + if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){ + src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before"); + } + this._hide(this.bottomMarker); + this._hide(this.topMarker); + Source.prototype._unmarkTargetAnchor.call(src); + }), + destroy: lang.hitch(this, function(){ + connect.disconnect(this._source_conn); + connect.unsubscribe(this._source_sub); + Source.prototype.destroy.call(this.source); + if(this.bottomMarker){ + html.destroy(this.bottomMarker); + delete this.bottomMarker; + } + if(this.topMarker){ + html.destroy(this.topMarker); + delete this.topMarker; + } + }), + onDndCancel: lang.hitch(this, function(){ + Source.prototype.onDndCancel.call(this.source); + this._hide(this.bottomMarker); + this._hide(this.topMarker); + }) + }); + + this._source_conn = connect.connect(this.source, "onDndDrop", this, "_onDndDrop"); + this._source_sub = connect.subscribe("/dnd/drop/before", this, "_onDndDropBefore"); + this.source.startup(); + } + }, + + _hide: function(node){ + html.style(node, { + top: "-10000px", + "visibility": "hidden" + }); + }, + + _onDndDropBefore: function(source, nodes, copy){ + if(dojo.dnd.manager().target !== this.source){ + return; + } + this.source._targetNode = this.source.targetAnchor; + this.source._beforeTarget = this.source.before; + var views = this.grid.views.views; + var srcView = views[source.viewIndex]; + var tgtView = views[this.index]; + if(tgtView != srcView){ + srcView.convertColPctToFixed(); + tgtView.convertColPctToFixed(); + } + }, + + _onDndDrop: function(source, nodes, copy){ + if(dojo.dnd.manager().target !== this.source){ + if(dojo.dnd.manager().source === this.source){ + this._removingColumn = true; + } + return; + } + this._hide(this.bottomMarker); + this._hide(this.topMarker); + + var getIdx = function(n){ + return n ? html.attr(n, "idx") : null; + }; + var w = html.marginBox(nodes[0]).w; + if(source.viewIndex !== this.index){ + var views = this.grid.views.views; + var srcView = views[source.viewIndex]; + var tgtView = views[this.index]; + if(srcView.viewWidth && srcView.viewWidth != "auto"){ + srcView.setColumnsWidth(srcView.getColumnsWidth() - w); + } + if(tgtView.viewWidth && tgtView.viewWidth != "auto"){ + tgtView.setColumnsWidth(tgtView.getColumnsWidth()); + } + } + var stn = this.source._targetNode; + var stb = this.source._beforeTarget; + !this.grid.isLeftToRight() && (stb = !stb); + var layout = this.grid.layout; + var idx = this.index; + delete this.source._targetNode; + delete this.source._beforeTarget; + + layout.moveColumn( + source.viewIndex, + idx, + getIdx(nodes[0]), + getIdx(stn), + stb); + }, + + renderHeader: function(){ + this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent); + if(this.flexCells){ + this.contentWidth = this.getContentWidth(); + this.headerContentNode.firstChild.style.width = this.contentWidth; + } + util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]); + }, + + // note: not called in 'view' context + _getHeaderContent: function(inCell){ + var n = inCell.name || inCell.grid.getCellName(inCell); + if(/^\s+$/.test(n)){ + n = ' '//otherwise arrow styles will be messed up + } + var ret = [ '<div class="dojoxGridSortNode' ]; + + if(inCell.index != inCell.grid.getSortIndex()){ + ret.push('">'); + }else{ + ret = ret.concat([ ' ', + inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown', + '"><div class="dojoxGridArrowButtonChar">', + inCell.grid.sortInfo > 0 ? '▲' : '▼', + '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>', + '<div class="dojoxGridColCaption">']); + } + ret = ret.concat([n, '</div></div>']); + return ret.join(''); + }, + + resize: function(){ + this.adaptHeight(); + this.adaptWidth(); + }, + + hasHScrollbar: function(reset){ + var hadScroll = this._hasHScroll||false; + if(this._hasHScroll == undefined || reset){ + if(this.noscroll){ + this._hasHScroll = false; + }else{ + var style = html.style(this.scrollboxNode, "overflow"); + if(style == "hidden"){ + this._hasHScroll = false; + }else if(style == "scroll"){ + this._hasHScroll = true; + }else{ + this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth ); + } + } + } + if(hadScroll !== this._hasHScroll){ + this.grid.update(); + } + return this._hasHScroll; // Boolean + }, + + hasVScrollbar: function(reset){ + var hadScroll = this._hasVScroll||false; + if(this._hasVScroll == undefined || reset){ + if(this.noscroll){ + this._hasVScroll = false; + }else{ + var style = html.style(this.scrollboxNode, "overflow"); + if(style == "hidden"){ + this._hasVScroll = false; + }else if(style == "scroll"){ + this._hasVScroll = true; + }else{ + this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight); + } + } + } + if(hadScroll !== this._hasVScroll){ + this.grid.update(); + } + return this._hasVScroll; // Boolean + }, + + convertColPctToFixed: function(){ + // Fix any percentage widths to be pixel values + var hasPct = false; + this.grid.initialWidth = ""; + var cellNodes = query("th", this.headerContentNode); + var fixedWidths = array.map(cellNodes, function(c, vIdx){ + var w = c.style.width; + html.attr(c, "vIdx", vIdx); + if(w && w.slice(-1) == "%"){ + hasPct = true; + }else if(w && w.slice(-2) == "px"){ + return window.parseInt(w, 10); + } + return html.contentBox(c).w; + }); + if(hasPct){ + array.forEach(this.grid.layout.cells, function(cell, idx){ + if(cell.view == this){ + var cellNode = cell.view.getHeaderCellNode(cell.index); + if(cellNode && html.hasAttr(cellNode, "vIdx")){ + var vIdx = window.parseInt(html.attr(cellNode, "vIdx")); + this.setColWidth(idx, fixedWidths[vIdx]); + html.removeAttr(cellNode, "vIdx"); + } + } + }, this); + return true; + } + return false; + }, + + adaptHeight: function(minusScroll){ + if(!this.grid._autoHeight){ + var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight; + var self = this; + var checkOtherViewScrollers = function(){ + var v; + for(var i in self.grid.views.views){ + v = self.grid.views.views[i]; + if(v !== self && v.hasHScrollbar()){ + return true; + } + } + return false; + }; + if(minusScroll || (this.noscroll && checkOtherViewScrollers())){ + h -= metrics.getScrollbar().h; + } + util.setStyleHeightPx(this.scrollboxNode, h); + } + this.hasVScrollbar(true); + }, + + adaptWidth: function(){ + if(this.flexCells){ + // the view content width + this.contentWidth = this.getContentWidth(); + this.headerContentNode.firstChild.style.width = this.contentWidth; + } + // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth, + // but clientWidth seemingly does not include scrollbar width in some cases + var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth(); + if(!this._removingColumn){ + w = Math.max(w, this.getColumnsWidth()) + 'px'; + }else{ + w = Math.min(w, this.getColumnsWidth()) + 'px'; + this._removingColumn = false; + } + var cn = this.contentNode; + cn.style.width = w; + this.hasHScrollbar(true); + }, + + setSize: function(w, h){ + var ds = this.domNode.style; + var hs = this.headerNode.style; + + if(w){ + ds.width = w; + hs.width = w; + } + ds.height = (h >= 0 ? h + 'px' : ''); + }, + + renderRow: function(inRowIndex){ + var rowNode = this.createRowNode(inRowIndex); + this.buildRow(inRowIndex, rowNode); + //this.grid.edit.restore(this, inRowIndex); + return rowNode; + }, + + createRowNode: function(inRowIndex){ + var node = document.createElement("div"); + node.className = this.classTag + 'Row'; + if (this instanceof dojox.grid._RowSelector){ + html.attr(node,"role","presentation"); + }else{ + html.attr(node,"role","row"); + if (this.grid.selectionMode != "none") { + node.setAttribute("aria-selected", "false"); //rows can be selected so add aria-selected prop + } + } + node[util.gridViewTag] = this.id; + node[util.rowIndexTag] = inRowIndex; + this.rowNodes[inRowIndex] = node; + return node; + }, + + buildRow: function(inRowIndex, inRowNode){ + + this.buildRowContent(inRowIndex, inRowNode); + + this.styleRow(inRowIndex, inRowNode); + + + }, + + buildRowContent: function(inRowIndex, inRowNode){ + inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex); + if(this.flexCells && this.contentWidth){ + // FIXME: accessing firstChild here breaks encapsulation + inRowNode.firstChild.style.width = this.contentWidth; + } + util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]); + }, + + rowRemoved:function(inRowIndex){ + if(inRowIndex >= 0){ + this._cleanupRowWidgets(this.getRowNode(inRowIndex)); + } + this.grid.edit.save(this, inRowIndex); + delete this.rowNodes[inRowIndex]; + }, + + getRowNode: function(inRowIndex){ + return this.rowNodes[inRowIndex]; + }, + + getCellNode: function(inRowIndex, inCellIndex){ + var row = this.getRowNode(inRowIndex); + if(row){ + return this.content.getCellNode(row, inCellIndex); + } + }, + + getHeaderCellNode: function(inCellIndex){ + if(this.headerContentNode){ + return this.header.getCellNode(this.headerContentNode, inCellIndex); + } + }, + + // styling + styleRow: function(inRowIndex, inRowNode){ + inRowNode._style = getStyleText(inRowNode); + this.styleRowNode(inRowIndex, inRowNode); + }, + + styleRowNode: function(inRowIndex, inRowNode){ + if(inRowNode){ + this.doStyleRowNode(inRowIndex, inRowNode); + } + }, + + doStyleRowNode: function(inRowIndex, inRowNode){ + this.grid.styleRowNode(inRowIndex, inRowNode); + }, + + // updating + updateRow: function(inRowIndex){ + var rowNode = this.getRowNode(inRowIndex); + if(rowNode){ + rowNode.style.height = ''; + this.buildRow(inRowIndex, rowNode); + } + return rowNode; + }, + + updateRowStyles: function(inRowIndex){ + this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex)); + }, + + // scrolling + lastTop: 0, + firstScroll:0, + + doscroll: function(inEvent){ + //var s = dojo.marginBox(this.headerContentNode.firstChild); + var isLtr = this.grid.isLeftToRight(); + if(this.firstScroll < 2){ + if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){ + var s = html.marginBox(this.headerNodeContainer); + if(has("ie")){ + this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px'; + }else if(has("mozilla")){ + //TODO currently only for FF, not sure for safari and opera + this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px'; + //this.headerNodeContainer.style.width = s.w + 'px'; + //set scroll to right in FF + this.scrollboxNode.scrollLeft = isLtr ? + this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth : + this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth; + } + } + this.firstScroll++; + } + this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft; + // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below + var top = this.scrollboxNode.scrollTop; + if(top !== this.lastTop){ + this.grid.scrollTo(top); + } + }, + + setScrollTop: function(inTop){ + // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above + this.lastTop = inTop; + this.scrollboxNode.scrollTop = inTop; + return this.scrollboxNode.scrollTop; + }, + + // event handlers (direct from DOM) + doContentEvent: function(e){ + if(this.content.decorateEvent(e)){ + this.grid.onContentEvent(e); + } + }, + + doHeaderEvent: function(e){ + if(this.header.decorateEvent(e)){ + this.grid.onHeaderEvent(e); + } + }, + + // event dispatch(from Grid) + dispatchContentEvent: function(e){ + return this.content.dispatchEvent(e); + }, + + dispatchHeaderEvent: function(e){ + return this.header.dispatchEvent(e); + }, + + // column resizing + setColWidth: function(inIndex, inWidth){ + this.grid.setCellWidth(inIndex, inWidth + 'px'); + }, + + update: function(){ + if(!this.domNode){ + return; + } + this.content.update(); + this.grid.update(); + //get scroll after update or scroll left setting goes wrong on IE. + //See trac: #8040 + var left = this.scrollboxNode.scrollLeft; + this.scrollboxNode.scrollLeft = left; + this.headerNode.scrollLeft = left; + } + }); + + var _GridAvatar = declare("dojox.grid._GridAvatar", Avatar, { + construct: function(){ + var dd = win.doc; + + var a = dd.createElement("table"); + a.cellPadding = a.cellSpacing = "0"; + a.className = "dojoxGridDndAvatar"; + a.style.position = "absolute"; + a.style.zIndex = 1999; + a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins + var b = dd.createElement("tbody"); + var tr = dd.createElement("tr"); + var td = dd.createElement("td"); + var img = dd.createElement("td"); + tr.className = "dojoxGridDndAvatarItem"; + img.className = "dojoxGridDndAvatarItemImage"; + img.style.width = "16px"; + var source = this.manager.source, node; + if(source.creator){ + // create an avatar representation of the node + node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node; + }else{ + // or just clone the node and hope it works + node = this.manager.nodes[0].cloneNode(true); + var table, tbody; + if(node.tagName.toLowerCase() == "tr"){ + // insert extra table nodes + table = dd.createElement("table"); + tbody = dd.createElement("tbody"); + tbody.appendChild(node); + table.appendChild(tbody); + node = table; + }else if(node.tagName.toLowerCase() == "th"){ + // insert extra table nodes + table = dd.createElement("table"); + tbody = dd.createElement("tbody"); + var r = dd.createElement("tr"); + table.cellPadding = table.cellSpacing = "0"; + r.appendChild(node); + tbody.appendChild(r); + table.appendChild(tbody); + node = table; + } + } + node.id = ""; + td.appendChild(node); + tr.appendChild(img); + tr.appendChild(td); + html.style(tr, "opacity", 0.9); + b.appendChild(tr); + + a.appendChild(b); + this.node = a; + + var m = dojo.dnd.manager(); + this.oldOffsetY = m.OFFSET_Y; + m.OFFSET_Y = 1; + }, + destroy: function(){ + dojo.dnd.manager().OFFSET_Y = this.oldOffsetY; + this.inherited(arguments); + } + }); + + var oldMakeAvatar = dojo.dnd.manager().makeAvatar; + dojo.dnd.manager().makeAvatar = function(){ + var src = this.source; + if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){ + return new _GridAvatar(this); + } + return oldMakeAvatar.call(dojo.dnd.manager()); + }; + + return _View; + +}); +}, +'dijit/_Contained':function(){ +define("dijit/_Contained", [ + "dojo/_base/declare", // declare + "./registry" // registry.getEnclosingWidget(), registry.byNode() +], function(declare, registry){ + + // module: + // dijit/_Contained + // summary: + // Mixin for widgets that are children of a container widget + + return declare("dijit._Contained", null, { + // summary: + // Mixin for widgets that are children of a container widget + // + // example: + // | // make a basic custom widget that knows about it's parents + // | declare("my.customClass",[dijit._Widget,dijit._Contained],{}); + + _getSibling: function(/*String*/ which){ + // summary: + // Returns next or previous sibling + // which: + // Either "next" or "previous" + // tags: + // private + var node = this.domNode; + do{ + node = node[which+"Sibling"]; + }while(node && node.nodeType != 1); + return node && registry.byNode(node); // dijit._Widget + }, + + getPreviousSibling: function(){ + // summary: + // Returns null if this is the first child of the parent, + // otherwise returns the next element sibling to the "left". + + return this._getSibling("previous"); // dijit._Widget + }, + + getNextSibling: function(){ + // summary: + // Returns null if this is the last child of the parent, + // otherwise returns the next element sibling to the "right". + + return this._getSibling("next"); // dijit._Widget + }, + + getIndexInParent: function(){ + // summary: + // Returns the index of this widget within its container parent. + // It returns -1 if the parent does not exist, or if the parent + // is not a dijit._Container + + var p = this.getParent(); + if(!p || !p.getIndexOfChild){ + return -1; // int + } + return p.getIndexOfChild(this); // int + } + }); +}); + +}, +'dojo/dnd/Selector':function(){ +define(["../main", "./common", "./Container"], function(dojo) { + // module: + // dojo/dnd/Selector + // summary: + // TODOC + + +/* + Container item states: + "" - an item is not selected + "Selected" - an item is selected + "Anchor" - an item is selected, and is an anchor for a "shift" selection +*/ + +/*===== +dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], { + // singular: Boolean + // allows selection of only one element, if true + singular: false, + + // autoSync: Boolean + // autosynchronizes the source with its list of DnD nodes, + autoSync: false +}); +=====*/ + +dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, { + // summary: + // a Selector object, which knows how to select its children + + /*===== + // selection: Set<String> + // The set of id's that are currently selected, such that this.selection[id] == 1 + // if the node w/that id is selected. Can iterate over selected node's id's like: + // | for(var id in this.selection) + selection: {}, + =====*/ + + constructor: function(node, params){ + // summary: + // constructor of the Selector + // node: Node||String + // node or node's id to build the selector on + // params: dojo.dnd.__SelectorArgs? + // a dictionary of parameters + if(!params){ params = {}; } + this.singular = params.singular; + this.autoSync = params.autoSync; + // class-specific variables + this.selection = {}; + this.anchor = null; + this.simpleSelection = false; + // set up events + this.events.push( + dojo.connect(this.node, "onmousedown", this, "onMouseDown"), + dojo.connect(this.node, "onmouseup", this, "onMouseUp")); + }, + + // object attributes (for markup) + singular: false, // is singular property + + // methods + getSelectedNodes: function(){ + // summary: + // returns a list (an array) of selected nodes + var t = new dojo.NodeList(); + var e = dojo.dnd._empty; + for(var i in this.selection){ + if(i in e){ continue; } + t.push(dojo.byId(i)); + } + return t; // NodeList + }, + selectNone: function(){ + // summary: + // unselects all items + return this._removeSelection()._removeAnchor(); // self + }, + selectAll: function(){ + // summary: + // selects all items + this.forInItems(function(data, id){ + this._addItemClass(dojo.byId(id), "Selected"); + this.selection[id] = 1; + }, this); + return this._removeAnchor(); // self + }, + deleteSelectedNodes: function(){ + // summary: + // deletes all selected items + var e = dojo.dnd._empty; + for(var i in this.selection){ + if(i in e){ continue; } + var n = dojo.byId(i); + this.delItem(i); + dojo.destroy(n); + } + this.anchor = null; + this.selection = {}; + return this; // self + }, + forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){ + // summary: + // iterates over selected items; + // see `dojo.dnd.Container.forInItems()` for details + o = o || dojo.global; + var s = this.selection, e = dojo.dnd._empty; + for(var i in s){ + if(i in e){ continue; } + f.call(o, this.getItem(i), i, this); + } + }, + sync: function(){ + // summary: + // sync up the node list with the data map + + dojo.dnd.Selector.superclass.sync.call(this); + + // fix the anchor + if(this.anchor){ + if(!this.getItem(this.anchor.id)){ + this.anchor = null; + } + } + + // fix the selection + var t = [], e = dojo.dnd._empty; + for(var i in this.selection){ + if(i in e){ continue; } + if(!this.getItem(i)){ + t.push(i); + } + } + dojo.forEach(t, function(i){ + delete this.selection[i]; + }, this); + + return this; // self + }, + insertNodes: function(addSelected, data, before, anchor){ + // summary: + // inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details) + // addSelected: Boolean + // all new nodes will be added to selected items, if true, no selection change otherwise + // data: Array + // a list of data items, which should be processed by the creator function + // before: Boolean + // insert before the anchor, if true, and after the anchor otherwise + // anchor: Node + // the anchor node to be used as a point of insertion + var oldCreator = this._normalizedCreator; + this._normalizedCreator = function(item, hint){ + var t = oldCreator.call(this, item, hint); + if(addSelected){ + if(!this.anchor){ + this.anchor = t.node; + this._removeItemClass(t.node, "Selected"); + this._addItemClass(this.anchor, "Anchor"); + }else if(this.anchor != t.node){ + this._removeItemClass(t.node, "Anchor"); + this._addItemClass(t.node, "Selected"); + } + this.selection[t.node.id] = 1; + }else{ + this._removeItemClass(t.node, "Selected"); + this._removeItemClass(t.node, "Anchor"); + } + return t; + }; + dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor); + this._normalizedCreator = oldCreator; + return this; // self + }, + destroy: function(){ + // summary: + // prepares the object to be garbage-collected + dojo.dnd.Selector.superclass.destroy.call(this); + this.selection = this.anchor = null; + }, + + // mouse events + onMouseDown: function(e){ + // summary: + // event processor for onmousedown + // e: Event + // mouse event + if(this.autoSync){ this.sync(); } + if(!this.current){ return; } + if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){ + this.simpleSelection = true; + if(e.button === dojo.mouseButtons.LEFT){ + // accept the left button and stop the event + // for IE we don't stop event when multiple buttons are pressed + dojo.stopEvent(e); + } + return; + } + if(!this.singular && e.shiftKey){ + if(!dojo.isCopyKey(e)){ + this._removeSelection(); + } + var c = this.getAllNodes(); + if(c.length){ + if(!this.anchor){ + this.anchor = c[0]; + this._addItemClass(this.anchor, "Anchor"); + } + this.selection[this.anchor.id] = 1; + if(this.anchor != this.current){ + var i = 0; + for(; i < c.length; ++i){ + var node = c[i]; + if(node == this.anchor || node == this.current){ break; } + } + for(++i; i < c.length; ++i){ + var node = c[i]; + if(node == this.anchor || node == this.current){ break; } + this._addItemClass(node, "Selected"); + this.selection[node.id] = 1; + } + this._addItemClass(this.current, "Selected"); + this.selection[this.current.id] = 1; + } + } + }else{ + if(this.singular){ + if(this.anchor == this.current){ + if(dojo.isCopyKey(e)){ + this.selectNone(); + } + }else{ + this.selectNone(); + this.anchor = this.current; + this._addItemClass(this.anchor, "Anchor"); + this.selection[this.current.id] = 1; + } + }else{ + if(dojo.isCopyKey(e)){ + if(this.anchor == this.current){ + delete this.selection[this.anchor.id]; + this._removeAnchor(); + }else{ + if(this.current.id in this.selection){ + this._removeItemClass(this.current, "Selected"); + delete this.selection[this.current.id]; + }else{ + if(this.anchor){ + this._removeItemClass(this.anchor, "Anchor"); + this._addItemClass(this.anchor, "Selected"); + } + this.anchor = this.current; + this._addItemClass(this.current, "Anchor"); + this.selection[this.current.id] = 1; + } + } + }else{ + if(!(this.current.id in this.selection)){ + this.selectNone(); + this.anchor = this.current; + this._addItemClass(this.current, "Anchor"); + this.selection[this.current.id] = 1; + } + } + } + } + dojo.stopEvent(e); + }, + onMouseUp: function(e){ + // summary: + // event processor for onmouseup + // e: Event + // mouse event + if(!this.simpleSelection){ return; } + this.simpleSelection = false; + this.selectNone(); + if(this.current){ + this.anchor = this.current; + this._addItemClass(this.anchor, "Anchor"); + this.selection[this.current.id] = 1; + } + }, + onMouseMove: function(e){ + // summary: + // event processor for onmousemove + // e: Event + // mouse event + this.simpleSelection = false; + }, + + // utilities + onOverEvent: function(){ + // summary: + // this function is called once, when mouse is over our container + this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove"); + }, + onOutEvent: function(){ + // summary: + // this function is called once, when mouse is out of our container + dojo.disconnect(this.onmousemoveEvent); + delete this.onmousemoveEvent; + }, + _removeSelection: function(){ + // summary: + // unselects all items + var e = dojo.dnd._empty; + for(var i in this.selection){ + if(i in e){ continue; } + var node = dojo.byId(i); + if(node){ this._removeItemClass(node, "Selected"); } + } + this.selection = {}; + return this; // self + }, + _removeAnchor: function(){ + if(this.anchor){ + this._removeItemClass(this.anchor, "Anchor"); + this.anchor = null; + } + return this; // self + } +}); + +return dojo.dnd.Selector; +}); + +}, +'dojo/parser':function(){ +define( + ["./_base/kernel", "./_base/lang", "./_base/array", "./_base/html", "./_base/window", "./_base/url", + "./_base/json", "./aspect", "./date/stamp", "./query", "./on", "./ready"], + function(dojo, dlang, darray, dhtml, dwindow, _Url, djson, aspect, dates, query, don){ + +// module: +// dojo/parser +// summary: +// The Dom/Widget parsing package + +new Date("X"); // workaround for #11279, new Date("") == NaN + +var features = { + // Feature detection for when node.attributes only lists the attributes specified in the markup + // rather than old IE/quirks behavior where it lists every default value too + "dom-attributes-explicit": document.createElement("div").attributes.length < 40 +}; +function has(feature){ + return features[feature]; +} + + +dojo.parser = new function(){ + // summary: + // The Dom/Widget parsing package + + var _nameMap = { + // Map from widget name (ex: "dijit.form.Button") to structure mapping + // lowercase version of attribute names to the version in the widget ex: + // { + // label: "label", + // onclick: "onClick" + // } + }; + function getNameMap(proto){ + // summary: + // Returns map from lowercase name to attribute name in class, ex: {onclick: "onClick"} + var map = {}; + for(var name in proto){ + if(name.charAt(0)=="_"){ continue; } // skip internal properties + map[name.toLowerCase()] = name; + } + return map; + } + // Widgets like BorderContainer add properties to _Widget via dojo.extend(). + // If BorderContainer is loaded after _Widget's parameter list has been cached, + // we need to refresh that parameter list (for _Widget and all widgets that extend _Widget). + aspect.after(dlang, "extend", function(){ + _nameMap = {}; + }, true); + + // Map from widget name (ex: "dijit.form.Button") to constructor + var _ctorMap = {}; + + this._functionFromScript = function(script, attrData){ + // summary: + // Convert a <script type="dojo/method" args="a, b, c"> ... </script> + // into a function + // script: DOMNode + // The <script> DOMNode + // attrData: String + // For HTML5 compliance, searches for attrData + "args" (typically + // "data-dojo-args") instead of "args" + var preamble = ""; + var suffix = ""; + var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args")); + if(argsStr){ + darray.forEach(argsStr.split(/\s*,\s*/), function(part, idx){ + preamble += "var "+part+" = arguments["+idx+"]; "; + }); + } + var withStr = script.getAttribute("with"); + if(withStr && withStr.length){ + darray.forEach(withStr.split(/\s*,\s*/), function(part){ + preamble += "with("+part+"){"; + suffix += "}"; + }); + } + return new Function(preamble+script.innerHTML+suffix); + }; + + this.instantiate = /*====== dojo.parser.instantiate= ======*/function(nodes, mixin, args){ + // summary: + // Takes array of nodes, and turns them into class instances and + // potentially calls a startup method to allow them to connect with + // any children. + // nodes: Array + // Array of nodes or objects like + // | { + // | type: "dijit.form.Button", + // | node: DOMNode, + // | scripts: [ ... ], // array of <script type="dojo/..."> children of node + // | inherited: { ... } // settings inherited from ancestors like dir, theme, etc. + // | } + // mixin: Object? + // An object that will be mixed in with each node in the array. + // Values in the mixin will override values in the node, if they + // exist. + // args: Object? + // An object used to hold kwArgs for instantiation. + // See parse.args argument for details. + + var thelist = [], + mixin = mixin||{}; + args = args||{}; + + // Precompute names of special attributes we are looking for + // TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0) + var dojoType = (args.scope || dojo._scopeName) + "Type", // typically "dojoType" + attrData = "data-" + (args.scope || dojo._scopeName) + "-",// typically "data-dojo-" + dataDojoType = attrData + "type", // typically "data-dojo-type" + dataDojoProps = attrData + "props", // typically "data-dojo-props" + dataDojoAttachPoint = attrData + "attach-point", + dataDojoAttachEvent = attrData + "attach-event", + dataDojoId = attrData + "id"; + + // And make hash to quickly check if a given attribute is special, and to map the name to something friendly + var specialAttrs = {}; + darray.forEach([dataDojoProps, dataDojoType, dojoType, dataDojoId, "jsId", dataDojoAttachPoint, + dataDojoAttachEvent, "dojoAttachPoint", "dojoAttachEvent", "class", "style"], function(name){ + specialAttrs[name.toLowerCase()] = name.replace(args.scope, "dojo"); + }); + + darray.forEach(nodes, function(obj){ + if(!obj){ return; } + + var node = obj.node || obj, + type = dojoType in mixin ? mixin[dojoType] : obj.node ? obj.type : (node.getAttribute(dataDojoType) || node.getAttribute(dojoType)), + ctor = _ctorMap[type] || (_ctorMap[type] = dlang.getObject(type)), + proto = ctor && ctor.prototype; + if(!ctor){ + throw new Error("Could not load class '" + type); + } + + // Setup hash to hold parameter settings for this widget. Start with the parameter + // settings inherited from ancestors ("dir" and "lang"). + // Inherited setting may later be overridden by explicit settings on node itself. + var params = {}; + + if(args.defaults){ + // settings for the document itself (or whatever subtree is being parsed) + dlang.mixin(params, args.defaults); + } + if(obj.inherited){ + // settings from dir=rtl or lang=... on a node above this node + dlang.mixin(params, obj.inherited); + } + + // Get list of attributes explicitly listed in the markup + var attributes; + if(has("dom-attributes-explicit")){ + // Standard path to get list of user specified attributes + attributes = node.attributes; + }else{ + // Special path for IE, avoid (sometimes >100) bogus entries in node.attributes + var clone = /^input$|^img$/i.test(node.nodeName) ? node : node.cloneNode(false), + attrs = clone.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g, "").replace(/^\s*<[a-zA-Z0-9]*/, "").replace(/>.*$/, ""); + + attributes = darray.map(attrs.split(/\s+/), function(name){ + var lcName = name.toLowerCase(); + return { + name: name, + // getAttribute() doesn't work for button.value, returns innerHTML of button. + // but getAttributeNode().value doesn't work for the form.encType or li.value + value: (node.nodeName == "LI" && name == "value") || lcName == "enctype" ? + node.getAttribute(lcName) : node.getAttributeNode(lcName).value, + specified: true + }; + }); + } + + // Read in attributes and process them, including data-dojo-props, data-dojo-type, + // dojoAttachPoint, etc., as well as normal foo=bar attributes. + var i=0, item; + while(item = attributes[i++]){ + if(!item || !item.specified){ + continue; + } + + var name = item.name, + lcName = name.toLowerCase(), + value = item.value; + + if(lcName in specialAttrs){ + switch(specialAttrs[lcName]){ + + // Data-dojo-props. Save for later to make sure it overrides direct foo=bar settings + case "data-dojo-props": + var extra = value; + break; + + // data-dojo-id or jsId. TODO: drop jsId in 2.0 + case "data-dojo-id": + case "jsId": + var jsname = value; + break; + + // For the benefit of _Templated + case "data-dojo-attach-point": + case "dojoAttachPoint": + params.dojoAttachPoint = value; + break; + case "data-dojo-attach-event": + case "dojoAttachEvent": + params.dojoAttachEvent = value; + break; + + // Special parameter handling needed for IE + case "class": + params["class"] = node.className; + break; + case "style": + params["style"] = node.style && node.style.cssText; + break; + } + }else{ + // Normal attribute, ex: value="123" + + // Find attribute in widget corresponding to specified name. + // May involve case conversion, ex: onclick --> onClick + if(!(name in proto)){ + var map = (_nameMap[type] || (_nameMap[type] = getNameMap(proto))); + name = map[lcName] || name; + } + + // Set params[name] to value, doing type conversion + if(name in proto){ + switch(typeof proto[name]){ + case "string": + params[name] = value; + break; + case "number": + params[name] = value.length ? Number(value) : NaN; + break; + case "boolean": + // for checked/disabled value might be "" or "checked". interpret as true. + params[name] = value.toLowerCase() != "false"; + break; + case "function": + if(value === "" || value.search(/[^\w\.]+/i) != -1){ + // The user has specified some text for a function like "return x+5" + params[name] = new Function(value); + }else{ + // The user has specified the name of a function like "myOnClick" + // or a single word function "return" + params[name] = dlang.getObject(value, false) || new Function(value); + } + break; + default: + var pVal = proto[name]; + params[name] = + (pVal && "length" in pVal) ? (value ? value.split(/\s*,\s*/) : []) : // array + (pVal instanceof Date) ? + (value == "" ? new Date("") : // the NaN of dates + value == "now" ? new Date() : // current date + dates.fromISOString(value)) : + (pVal instanceof dojo._Url) ? (dojo.baseUrl + value) : + djson.fromJson(value); + } + }else{ + params[name] = value; + } + } + } + + // Mix things found in data-dojo-props into the params, overriding any direct settings + if(extra){ + try{ + extra = djson.fromJson.call(args.propsThis, "{" + extra + "}"); + dlang.mixin(params, extra); + }catch(e){ + // give the user a pointer to their invalid parameters. FIXME: can we kill this in production? + throw new Error(e.toString() + " in data-dojo-props='" + extra + "'"); + } + } + + // Any parameters specified in "mixin" override everything else. + dlang.mixin(params, mixin); + + var scripts = obj.node ? obj.scripts : (ctor && (ctor._noScript || proto._noScript) ? [] : + query("> script[type^='dojo/']", node)); + + // Process <script type="dojo/*"> script tags + // <script type="dojo/method" event="foo"> tags are added to params, and passed to + // the widget on instantiation. + // <script type="dojo/method"> tags (with no event) are executed after instantiation + // <script type="dojo/connect" data-dojo-event="foo"> tags are dojo.connected after instantiation + // <script type="dojo/watch" data-dojo-prop="foo"> tags are dojo.watch after instantiation + // <script type="dojo/on" data-dojo-event="foo"> tags are dojo.on after instantiation + // note: dojo/* script tags cannot exist in self closing widgets, like <input /> + var connects = [], // functions to connect after instantiation + calls = [], // functions to call after instantiation + watch = [], //functions to watch after instantiation + on = []; //functions to on after instantiation + + if(scripts){ + for(i=0; i<scripts.length; i++){ + var script = scripts[i]; + node.removeChild(script); + // FIXME: drop event="" support in 2.0. use data-dojo-event="" instead + var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")), + prop = script.getAttribute(attrData + "prop"), + type = script.getAttribute("type"), + nf = this._functionFromScript(script, attrData); + if(event){ + if(type == "dojo/connect"){ + connects.push({event: event, func: nf}); + }else if(type == "dojo/on"){ + on.push({event: event, func: nf}); + }else{ + params[event] = nf; + } + }else if(type == "dojo/watch"){ + watch.push({prop: prop, func: nf}); + }else{ + calls.push(nf); + } + } + } + + // create the instance + var markupFactory = ctor.markupFactory || proto.markupFactory; + var instance = markupFactory ? markupFactory(params, node, ctor) : new ctor(params, node); + thelist.push(instance); + + // map it to the JS namespace if that makes sense + if(jsname){ + dlang.setObject(jsname, instance); + } + + // process connections and startup functions + for(i=0; i<connects.length; i++){ + aspect.after(instance, connects[i].event, dojo.hitch(instance, connects[i].func), true); + } + for(i=0; i<calls.length; i++){ + calls[i].call(instance); + } + for(i=0; i<watch.length; i++){ + instance.watch(watch[i].prop, watch[i].func); + } + for(i=0; i<on.length; i++){ + don(instance, on[i].event, on[i].func); + } + }, this); + + // Call startup on each top level instance if it makes sense (as for + // widgets). Parent widgets will recursively call startup on their + // (non-top level) children + if(!mixin._started){ + darray.forEach(thelist, function(instance){ + if( !args.noStart && instance && + dlang.isFunction(instance.startup) && + !instance._started + ){ + instance.startup(); + } + }); + } + return thelist; + }; + + this.parse = /*====== dojo.parser.parse= ======*/ function(rootNode, args){ + // summary: + // Scan the DOM for class instances, and instantiate them. + // + // description: + // Search specified node (or root node) recursively for class instances, + // and instantiate them. Searches for either data-dojo-type="Class" or + // dojoType="Class" where "Class" is a a fully qualified class name, + // like `dijit.form.Button` + // + // Using `data-dojo-type`: + // Attributes using can be mixed into the parameters used to instantiate the + // Class by using a `data-dojo-props` attribute on the node being converted. + // `data-dojo-props` should be a string attribute to be converted from JSON. + // + // Using `dojoType`: + // Attributes are read from the original domNode and converted to appropriate + // types by looking up the Class prototype values. This is the default behavior + // from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will + // go away in Dojo 2.0. + // + // rootNode: DomNode? + // A default starting root node from which to start the parsing. Can be + // omitted, defaulting to the entire document. If omitted, the `args` + // object can be passed in this place. If the `args` object has a + // `rootNode` member, that is used. + // + // args: Object + // a kwArgs object passed along to instantiate() + // + // * noStart: Boolean? + // when set will prevent the parser from calling .startup() + // when locating the nodes. + // * rootNode: DomNode? + // identical to the function's `rootNode` argument, though + // allowed to be passed in via this `args object. + // * template: Boolean + // If true, ignores ContentPane's stopParser flag and parses contents inside of + // a ContentPane inside of a template. This allows dojoAttachPoint on widgets/nodes + // nested inside the ContentPane to work. + // * inherited: Object + // Hash possibly containing dir and lang settings to be applied to + // parsed widgets, unless there's another setting on a sub-node that overrides + // * scope: String + // Root for attribute names to search for. If scopeName is dojo, + // will search for data-dojo-type (or dojoType). For backwards compatibility + // reasons defaults to dojo._scopeName (which is "dojo" except when + // multi-version support is used, when it will be something like dojo16, dojo20, etc.) + // * propsThis: Object + // If specified, "this" referenced from data-dojo-props will refer to propsThis. + // Intended for use from the widgets-in-template feature of `dijit._WidgetsInTemplateMixin` + // + // example: + // Parse all widgets on a page: + // | dojo.parser.parse(); + // + // example: + // Parse all classes within the node with id="foo" + // | dojo.parser.parse(dojo.byId('foo')); + // + // example: + // Parse all classes in a page, but do not call .startup() on any + // child + // | dojo.parser.parse({ noStart: true }) + // + // example: + // Parse all classes in a node, but do not call .startup() + // | dojo.parser.parse(someNode, { noStart:true }); + // | // or + // | dojo.parser.parse({ noStart:true, rootNode: someNode }); + + // determine the root node based on the passed arguments. + var root; + if(!args && rootNode && rootNode.rootNode){ + args = rootNode; + root = args.rootNode; + }else{ + root = rootNode; + } + root = root ? dhtml.byId(root) : dwindow.body(); + args = args || {}; + + var dojoType = (args.scope || dojo._scopeName) + "Type", // typically "dojoType" + attrData = "data-" + (args.scope || dojo._scopeName) + "-", // typically "data-dojo-" + dataDojoType = attrData + "type", // typically "data-dojo-type" + dataDojoTextDir = attrData + "textdir"; // typically "data-dojo-textdir" + + // List of all nodes on page w/dojoType specified + var list = []; + + // Info on DOMNode currently being processed + var node = root.firstChild; + + // Info on parent of DOMNode currently being processed + // - inherited: dir, lang, and textDir setting of parent, or inherited by parent + // - parent: pointer to identical structure for my parent (or null if no parent) + // - scripts: if specified, collects <script type="dojo/..."> type nodes from children + var inherited = args && args.inherited; + if(!inherited){ + function findAncestorAttr(node, attr){ + return (node.getAttribute && node.getAttribute(attr)) || + (node !== dwindow.doc && node !== dwindow.doc.documentElement && node.parentNode ? findAncestorAttr(node.parentNode, attr) : null); + } + inherited = { + dir: findAncestorAttr(root, "dir"), + lang: findAncestorAttr(root, "lang"), + textDir: findAncestorAttr(root, dataDojoTextDir) + }; + for(var key in inherited){ + if(!inherited[key]){ delete inherited[key]; } + } + } + var parent = { + inherited: inherited + }; + + // For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect) + var scripts; + + // when true, only look for <script type="dojo/..."> tags, and don't recurse to children + var scriptsOnly; + + function getEffective(parent){ + // summary: + // Get effective dir, lang, textDir settings for specified obj + // (matching "parent" object structure above), and do caching. + // Take care not to return null entries. + if(!parent.inherited){ + parent.inherited = {}; + var node = parent.node, + grandparent = getEffective(parent.parent); + var inherited = { + dir: node.getAttribute("dir") || grandparent.dir, + lang: node.getAttribute("lang") || grandparent.lang, + textDir: node.getAttribute(dataDojoTextDir) || grandparent.textDir + }; + for(var key in inherited){ + if(inherited[key]){ + parent.inherited[key] = inherited[key]; + } + } + } + return parent.inherited; + } + + // DFS on DOM tree, collecting nodes with data-dojo-type specified. + while(true){ + if(!node){ + // Finished this level, continue to parent's next sibling + if(!parent || !parent.node){ + break; + } + node = parent.node.nextSibling; + scripts = parent.scripts; + scriptsOnly = false; + parent = parent.parent; + continue; + } + + if(node.nodeType != 1){ + // Text or comment node, skip to next sibling + node = node.nextSibling; + continue; + } + + if(scripts && node.nodeName.toLowerCase() == "script"){ + // Save <script type="dojo/..."> for parent, then continue to next sibling + type = node.getAttribute("type"); + if(type && /^dojo\/\w/i.test(type)){ + scripts.push(node); + } + node = node.nextSibling; + continue; + } + if(scriptsOnly){ + node = node.nextSibling; + continue; + } + + // Check for data-dojo-type attribute, fallback to backward compatible dojoType + var type = node.getAttribute(dataDojoType) || node.getAttribute(dojoType); + + // Short circuit for leaf nodes containing nothing [but text] + var firstChild = node.firstChild; + if(!type && (!firstChild || (firstChild.nodeType == 3 && !firstChild.nextSibling))){ + node = node.nextSibling; + continue; + } + + // Setup data structure to save info on current node for when we return from processing descendant nodes + var current = { + node: node, + scripts: scripts, + parent: parent + }; + + // If dojoType/data-dojo-type specified, add to output array of nodes to instantiate + var ctor = type && (_ctorMap[type] || (_ctorMap[type] = dlang.getObject(type))), // note: won't find classes declared via dojo.Declaration + childScripts = ctor && !ctor.prototype._noScript ? [] : null; // <script> nodes that are parent's children + if(type){ + list.push({ + "type": type, + node: node, + scripts: childScripts, + inherited: getEffective(current) // dir & lang settings for current node, explicit or inherited + }); + } + + // Recurse, collecting <script type="dojo/..."> children, and also looking for + // descendant nodes with dojoType specified (unless the widget has the stopParser flag). + // When finished with children, go to my next sibling. + node = firstChild; + scripts = childScripts; + scriptsOnly = ctor && ctor.prototype.stopParser && !(args && args.template); + parent = current; + + } + + // go build the object instances + var mixin = args && args.template ? {template: true} : null; + return this.instantiate(list, mixin, args); // Array + }; +}(); + + +//Register the parser callback. It should be the first callback +//after the a11y test. +if(dojo.config.parseOnLoad){ + dojo.ready(100, dojo.parser, "parse"); +} + +return dojo.parser; +}); + +}, +'dojox/grid/DataSelection':function(){ +define("dojox/grid/DataSelection", [ + "dojo/_base/declare", + "./_SelectionPreserver", + "./Selection" +], function(declare, _SelectionPreserver, Selection){ + +return declare("dojox.grid.DataSelection", Selection, { + constructor: function(grid){ + if(grid.keepSelection){ + this.preserver = new _SelectionPreserver(this); + } + }, + + destroy: function(){ + if(this.preserver){ + this.preserver.destroy(); + } + }, + + getFirstSelected: function(){ + var idx = Selection.prototype.getFirstSelected.call(this); + + if(idx == -1){ return null; } + return this.grid.getItem(idx); + }, + + getNextSelected: function(inPrev){ + var old_idx = this.grid.getItemIndex(inPrev); + var idx = Selection.prototype.getNextSelected.call(this, old_idx); + + if(idx == -1){ return null; } + return this.grid.getItem(idx); + }, + + getSelected: function(){ + var result = []; + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + result.push(this.grid.getItem(i)); + } + } + return result; + }, + + addToSelection: function(inItemOrIndex){ + if(this.mode == 'none'){ return; } + var idx = null; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + Selection.prototype.addToSelection.call(this, idx); + }, + + deselect: function(inItemOrIndex){ + if(this.mode == 'none'){ return; } + var idx = null; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + Selection.prototype.deselect.call(this, idx); + }, + + deselectAll: function(inItemOrIndex){ + var idx = null; + if(inItemOrIndex || typeof inItemOrIndex == "number"){ + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + Selection.prototype.deselectAll.call(this, idx); + }else{ + this.inherited(arguments); + } + } +}); +}); +}, +'url:dijit/templates/CheckedMenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\"> </td>\n</tr>\n", +'dojo/dnd/Manager':function(){ +define(["../main", "../Evented", "./common", "./autoscroll", "./Avatar"], function(dojo, Evented) { + // module: + // dojo/dnd/Manager + // summary: + // TODOC + + +var Manager = dojo.declare("dojo.dnd.Manager", [Evented], { + // summary: + // the manager of DnD operations (usually a singleton) + constructor: function(){ + this.avatar = null; + this.source = null; + this.nodes = []; + this.copy = true; + this.target = null; + this.canDropFlag = false; + this.events = []; + }, + + // avatar's offset from the mouse + OFFSET_X: 16, + OFFSET_Y: 16, + + // methods + overSource: function(source){ + // summary: + // called when a source detected a mouse-over condition + // source: Object + // the reporter + if(this.avatar){ + this.target = (source && source.targetState != "Disabled") ? source : null; + this.canDropFlag = Boolean(this.target); + this.avatar.update(); + } + dojo.publish("/dnd/source/over", [source]); + }, + outSource: function(source){ + // summary: + // called when a source detected a mouse-out condition + // source: Object + // the reporter + if(this.avatar){ + if(this.target == source){ + this.target = null; + this.canDropFlag = false; + this.avatar.update(); + dojo.publish("/dnd/source/over", [null]); + } + }else{ + dojo.publish("/dnd/source/over", [null]); + } + }, + startDrag: function(source, nodes, copy){ + // summary: + // called to initiate the DnD operation + // source: Object + // the source which provides items + // nodes: Array + // the list of transferred items + // copy: Boolean + // copy items, if true, move items otherwise + this.source = source; + this.nodes = nodes; + this.copy = Boolean(copy); // normalizing to true boolean + this.avatar = this.makeAvatar(); + dojo.body().appendChild(this.avatar.node); + dojo.publish("/dnd/start", [source, nodes, this.copy]); + this.events = [ + dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"), + dojo.connect(dojo.doc, "onmouseup", this, "onMouseUp"), + dojo.connect(dojo.doc, "onkeydown", this, "onKeyDown"), + dojo.connect(dojo.doc, "onkeyup", this, "onKeyUp"), + // cancel text selection and text dragging + dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent), + dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent) + ]; + var c = "dojoDnd" + (copy ? "Copy" : "Move"); + dojo.addClass(dojo.body(), c); + }, + canDrop: function(flag){ + // summary: + // called to notify if the current target can accept items + var canDropFlag = Boolean(this.target && flag); + if(this.canDropFlag != canDropFlag){ + this.canDropFlag = canDropFlag; + this.avatar.update(); + } + }, + stopDrag: function(){ + // summary: + // stop the DnD in progress + dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]); + dojo.forEach(this.events, dojo.disconnect); + this.events = []; + this.avatar.destroy(); + this.avatar = null; + this.source = this.target = null; + this.nodes = []; + }, + makeAvatar: function(){ + // summary: + // makes the avatar; it is separate to be overwritten dynamically, if needed + return new dojo.dnd.Avatar(this); + }, + updateAvatar: function(){ + // summary: + // updates the avatar; it is separate to be overwritten dynamically, if needed + this.avatar.update(); + }, + + // mouse event processors + onMouseMove: function(e){ + // summary: + // event processor for onmousemove + // e: Event + // mouse event + var a = this.avatar; + if(a){ + dojo.dnd.autoScrollNodes(e); + //dojo.dnd.autoScroll(e); + var s = a.node.style; + s.left = (e.pageX + this.OFFSET_X) + "px"; + s.top = (e.pageY + this.OFFSET_Y) + "px"; + var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))); + if(this.copy != copy){ + this._setCopyStatus(copy); + } + } + }, + onMouseUp: function(e){ + // summary: + // event processor for onmouseup + // e: Event + // mouse event + if(this.avatar){ + if(this.target && this.canDropFlag){ + var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))), + params = [this.source, this.nodes, copy, this.target, e]; + dojo.publish("/dnd/drop/before", params); + dojo.publish("/dnd/drop", params); + }else{ + dojo.publish("/dnd/cancel"); + } + this.stopDrag(); + } + }, + + // keyboard event processors + onKeyDown: function(e){ + // summary: + // event processor for onkeydown: + // watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag + // e: Event + // keyboard event + if(this.avatar){ + switch(e.keyCode){ + case dojo.keys.CTRL: + var copy = Boolean(this.source.copyState(true)); + if(this.copy != copy){ + this._setCopyStatus(copy); + } + break; + case dojo.keys.ESCAPE: + dojo.publish("/dnd/cancel"); + this.stopDrag(); + break; + } + } + }, + onKeyUp: function(e){ + // summary: + // event processor for onkeyup, watching for CTRL for copy/move status + // e: Event + // keyboard event + if(this.avatar && e.keyCode == dojo.keys.CTRL){ + var copy = Boolean(this.source.copyState(false)); + if(this.copy != copy){ + this._setCopyStatus(copy); + } + } + }, + + // utilities + _setCopyStatus: function(copy){ + // summary: + // changes the copy status + // copy: Boolean + // the copy status + this.copy = copy; + this.source._markDndStatus(this.copy); + this.updateAvatar(); + dojo.replaceClass(dojo.body(), + "dojoDnd" + (this.copy ? "Copy" : "Move"), + "dojoDnd" + (this.copy ? "Move" : "Copy")); + } +}); + +// dojo.dnd._manager: +// The manager singleton variable. Can be overwritten if needed. +dojo.dnd._manager = null; + +Manager.manager = dojo.dnd.manager = function(){ + // summary: + // Returns the current DnD manager. Creates one if it is not created yet. + if(!dojo.dnd._manager){ + dojo.dnd._manager = new dojo.dnd.Manager(); + } + return dojo.dnd._manager; // Object +}; + +return Manager; +}); + +}, +'dojox/grid/_RowSelector':function(){ +define("dojox/grid/_RowSelector", [ + "dojo/_base/declare", + "./_View" +], function(declare, _View){ + +return declare('dojox.grid._RowSelector', _View, { + // summary: + // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows. + defaultWidth: "2em", + noscroll: true, + padBorderWidth: 2, + buildRendering: function(){ + this.inherited('buildRendering', arguments); + this.scrollboxNode.style.overflow = "hidden"; + this.headerNode.style.visibility = "hidden"; + }, + getWidth: function(){ + return this.viewWidth || this.defaultWidth; + }, + buildRowContent: function(inRowIndex, inRowNode){ + var w = this.contentWidth || 0; + inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner"> </td></tr></table>'; + }, + renderHeader: function(){ + }, + updateRow: function(){ + }, + resize: function(){ + this.adaptHeight(); + }, + adaptWidth: function(){ + // Only calculate this here - rather than every call to buildRowContent + if(!("contentWidth" in this) && this.contentNode){ + this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth; + } + }, + // styling + doStyleRowNode: function(inRowIndex, inRowNode){ + var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ]; + if(this.grid.rows.isOver(inRowIndex)){ + n.push("dojoxGridRowbarOver"); + } + if(this.grid.selection.isSelected(inRowIndex)){ + n.push("dojoxGridRowbarSelected"); + } + inRowNode.className = n.join(" "); + }, + // event handlers + domouseover: function(e){ + this.grid.onMouseOverRow(e); + }, + domouseout: function(e){ + if(!this.isIntraRowEvent(e)){ + this.grid.onMouseOutRow(e); + } + } +}); +}); +}, +'dojox/grid/_Layout':function(){ +define("dojox/grid/_Layout", [ + "dojo/_base/kernel", + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/dom-geometry", + "./cells", + "./_RowSelector" +], function(dojo, dojox, declare, array, lang, domGeometry){ + +return declare("dojox.grid._Layout", null, { + // summary: + // Controls grid cell layout. Owned by grid and used internally. + constructor: function(inGrid){ + this.grid = inGrid; + }, + // flat array of grid cells + cells: [], + // structured array of grid cells + structure: null, + // default cell width + defaultWidth: '6em', + + // methods + moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){ + var source_cells = this.structure[sourceViewIndex].cells[0]; + var dest_cells = this.structure[destViewIndex].cells[0]; + + var cell = null; + var cell_ri = 0; + var target_ri = 0; + + for(var i=0, c; c=source_cells[i]; i++){ + if(c.index == cellIndex){ + cell_ri = i; + break; + } + } + cell = source_cells.splice(cell_ri, 1)[0]; + cell.view = this.grid.views.views[destViewIndex]; + + for(i=0, c=null; c=dest_cells[i]; i++){ + if(c.index == targetIndex){ + target_ri = i; + break; + } + } + if(!before){ + target_ri += 1; + } + dest_cells.splice(target_ri, 0, cell); + + var sortedCell = this.grid.getCell(this.grid.getSortIndex()); + if(sortedCell){ + sortedCell._currentlySorted = this.grid.getSortAsc(); + } + + this.cells = []; + cellIndex = 0; + var v; + for(i=0; v=this.structure[i]; i++){ + for(var j=0, cs; cs=v.cells[j]; j++){ + for(var k=0; c=cs[k]; k++){ + c.index = cellIndex; + this.cells.push(c); + if("_currentlySorted" in c){ + var si = cellIndex + 1; + si *= c._currentlySorted ? 1 : -1; + this.grid.sortInfo = si; + delete c._currentlySorted; + } + cellIndex++; + } + } + } + + //Fix #9481 - reset idx in cell markup + array.forEach(this.cells, function(c){ + var marks = c.markup[2].split(" "); + var oldIdx = parseInt(marks[1].substring(5));//get old "idx" + if(oldIdx != c.index){ + marks[1] = "idx=\"" + c.index + "\""; + c.markup[2] = marks.join(" "); + } + }); + + this.grid.setupHeaderMenu(); + //this.grid.renderOnIdle(); + }, + + setColumnVisibility: function(columnIndex, visible){ + var cell = this.cells[columnIndex]; + if(cell.hidden == visible){ + cell.hidden = !visible; + var v = cell.view, w = v.viewWidth; + if(w && w != "auto"){ + v._togglingColumn = domGeometry.getMarginBox(cell.getHeaderNode()).w || 0; + } + v.update(); + return true; + }else{ + return false; + } + }, + + addCellDef: function(inRowIndex, inCellIndex, inDef){ + var self = this; + var getCellWidth = function(inDef){ + var w = 0; + if(inDef.colSpan > 1){ + w = 0; + }else{ + w = inDef.width || self._defaultCellProps.width || self.defaultWidth; + + if(!isNaN(w)){ + w = w + "em"; + } + } + return w; + }; + + var props = { + grid: this.grid, + subrow: inRowIndex, + layoutIndex: inCellIndex, + index: this.cells.length + }; + + if(inDef && inDef instanceof dojox.grid.cells._Base){ + var new_cell = lang.clone(inDef); + props.unitWidth = getCellWidth(new_cell._props); + new_cell = lang.mixin(new_cell, this._defaultCellProps, inDef._props, props); + return new_cell; + } + + var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell; + if(lang.isString(cell_type)){ + cell_type = lang.getObject(cell_type); + } + + props.unitWidth = getCellWidth(inDef); + return new cell_type(lang.mixin({}, this._defaultCellProps, inDef, props)); + }, + + addRowDef: function(inRowIndex, inDef){ + var result = []; + var relSum = 0, pctSum = 0, doRel = true; + for(var i=0, def, cell; (def=inDef[i]); i++){ + cell = this.addCellDef(inRowIndex, i, def); + result.push(cell); + this.cells.push(cell); + // Check and calculate the sum of all relative widths + if(doRel && cell.relWidth){ + relSum += cell.relWidth; + }else if(cell.width){ + var w = cell.width; + if(typeof w == "string" && w.slice(-1) == "%"){ + pctSum += window.parseInt(w, 10); + }else if(w == "auto"){ + // relative widths doesn't play nice with auto - since we + // don't have a way of knowing how much space the auto is + // supposed to take up. + doRel = false; + } + } + } + if(relSum && doRel){ + // We have some kind of relWidths specified - so change them to % + array.forEach(result, function(cell){ + if(cell.relWidth){ + cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%"; + } + }); + } + return result; + + }, + + addRowsDef: function(inDef){ + var result = []; + if(lang.isArray(inDef)){ + if(lang.isArray(inDef[0])){ + for(var i=0, row; inDef && (row=inDef[i]); i++){ + result.push(this.addRowDef(i, row)); + } + }else{ + result.push(this.addRowDef(0, inDef)); + } + } + return result; + }, + + addViewDef: function(inDef){ + this._defaultCellProps = inDef.defaultCell || {}; + if(inDef.width && inDef.width == "auto"){ + delete inDef.width; + } + return lang.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)}); + }, + + setStructure: function(inStructure){ + this.fieldIndex = 0; + this.cells = []; + var s = this.structure = []; + + if(this.grid.rowSelector){ + var sel = { type: dojox._scopeName + ".grid._RowSelector" }; + + if(lang.isString(this.grid.rowSelector)){ + var width = this.grid.rowSelector; + + if(width == "false"){ + sel = null; + }else if(width != "true"){ + sel['width'] = width; + } + }else{ + if(!this.grid.rowSelector){ + sel = null; + } + } + + if(sel){ + s.push(this.addViewDef(sel)); + } + } + + var isCell = function(def){ + return ("name" in def || "field" in def || "get" in def); + }; + + var isRowDef = function(def){ + if(lang.isArray(def)){ + if(lang.isArray(def[0]) || isCell(def[0])){ + return true; + } + } + return false; + }; + + var isView = function(def){ + return (def !== null && lang.isObject(def) && + ("cells" in def || "rows" in def || ("type" in def && !isCell(def)))); + }; + + if(lang.isArray(inStructure)){ + var hasViews = false; + for(var i=0, st; (st=inStructure[i]); i++){ + if(isView(st)){ + hasViews = true; + break; + } + } + if(!hasViews){ + s.push(this.addViewDef({ cells: inStructure })); + }else{ + for(i=0; (st=inStructure[i]); i++){ + if(isRowDef(st)){ + s.push(this.addViewDef({ cells: st })); + }else if(isView(st)){ + s.push(this.addViewDef(st)); + } + } + } + }else if(isView(inStructure)){ + // it's a view object + s.push(this.addViewDef(inStructure)); + } + + this.cellCount = this.cells.length; + this.grid.setupHeaderMenu(); + } +}); +}); +}, +'dojox/grid/_Grid':function(){ +require({cache:{ +'url:dojox/grid/resources/_Grid.html':"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n"}}); +define("dojox/grid/_Grid", [ + "dojo/_base/kernel", + "../main", + "dojo/_base/declare", + "./_Events", + "./_Scroller", + "./_Layout", + "./_View", + "./_ViewManager", + "./_RowManager", + "./_FocusManager", + "./_EditManager", + "./Selection", + "./_RowSelector", + "./util", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/CheckedMenuItem", + "dojo/text!./resources/_Grid.html", + "dojo/string", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/sniff", + "dojox/html/metrics", + "dojo/_base/html", + "dojo/query", + "dojo/dnd/common", + "dojo/i18n!dijit/nls/loading" +], function(dojo, dojox, declare, _Events, _Scroller, _Layout, _View, _ViewManager, + _RowManager, _FocusManager, _EditManager, Selection, _RowSelector, util, _Widget, + _TemplatedMixin, CheckedMenuItem, template, string, array, lang, has, metrics, html, query){ + + // NOTE: this is for backwards compatibility with Dojo 1.3 + if(!dojo.isCopyKey){ + dojo.isCopyKey = dojo.dnd.getCopyKeyState; + } + /*===== + dojox.grid.__CellDef = function(){ + // name: String? + // The text to use in the header of the grid for this cell. + // get: Function? + // function(rowIndex){} rowIndex is of type Integer. This + // function will be called when a cell requests data. Returns the + // unformatted data for the cell. + // value: String? + // If "get" is not specified, this is used as the data for the cell. + // defaultValue: String? + // If "get" and "value" aren't specified or if "get" returns an undefined + // value, this is used as the data for the cell. "formatter" is not run + // on this if "get" returns an undefined value. + // formatter: Function? + // function(data, rowIndex){} data is of type anything, rowIndex + // is of type Integer. This function will be called after the cell + // has its data but before it passes it back to the grid to render. + // Returns the formatted version of the cell's data. + // type: dojox.grid.cells._Base|Function? + // TODO + // editable: Boolean? + // Whether this cell should be editable or not. + // hidden: Boolean? + // If true, the cell will not be displayed. + // noresize: Boolean? + // If true, the cell will not be able to be resized. + // width: Integer|String? + // A CSS size. If it's an Integer, the width will be in em's. + // colSpan: Integer? + // How many columns to span this cell. Will not work in the first + // sub-row of cells. + // rowSpan: Integer? + // How many sub-rows to span this cell. + // styles: String? + // A string of styles to apply to both the header cell and main + // grid cells. Must end in a ';'. + // headerStyles: String? + // A string of styles to apply to just the header cell. Must end + // in a ';' + // cellStyles: String? + // A string of styles to apply to just the main grid cells. Must + // end in a ';' + // classes: String? + // A space separated list of classes to apply to both the header + // cell and the main grid cells. + // headerClasses: String? + // A space separated list of classes to apply to just the header + // cell. + // cellClasses: String? + // A space separated list of classes to apply to just the main + // grid cells. + // attrs: String? + // A space separated string of attribute='value' pairs to add to + // the header cell element and main grid cell elements. + this.name = name; + this.value = value; + this.get = get; + this.formatter = formatter; + this.type = type; + this.editable = editable; + this.hidden = hidden; + this.width = width; + this.colSpan = colSpan; + this.rowSpan = rowSpan; + this.styles = styles; + this.headerStyles = headerStyles; + this.cellStyles = cellStyles; + this.classes = classes; + this.headerClasses = headerClasses; + this.cellClasses = cellClasses; + this.attrs = attrs; + } + =====*/ + + /*===== + dojox.grid.__ViewDef = function(){ + // noscroll: Boolean? + // If true, no scrollbars will be rendered without scrollbars. + // width: Integer|String? + // A CSS size. If it's an Integer, the width will be in em's. If + // "noscroll" is true, this value is ignored. + // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]? + // The structure of the cells within this grid. + // type: String? + // A string containing the constructor of a subclass of + // dojox.grid._View. If this is not specified, dojox.grid._View + // is used. + // defaultCell: dojox.grid.__CellDef? + // A cell definition with default values for all cells in this view. If + // a property is defined in a cell definition in the "cells" array and + // this property, the cell definition's property will override this + // property's property. + // onBeforeRow: Function? + // function(rowIndex, cells){} rowIndex is of type Integer, cells + // is of type Array[dojox.grid.__CellDef[]]. This function is called + // before each row of data is rendered. Before the header is + // rendered, rowIndex will be -1. "cells" is a reference to the + // internal structure of this view's cells so any changes you make to + // it will persist between calls. + // onAfterRow: Function? + // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells + // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode. + // This function is called after each row of data is rendered. After the + // header is rendered, rowIndex will be -1. "cells" is a reference to the + // internal structure of this view's cells so any changes you make to + // it will persist between calls. + this.noscroll = noscroll; + this.width = width; + this.cells = cells; + this.type = type; + this.defaultCell = defaultCell; + this.onBeforeRow = onBeforeRow; + this.onAfterRow = onAfterRow; + } + =====*/ + + var _Grid = declare('dojox.grid._Grid', + [ _Widget, _TemplatedMixin, _Events ], + { + // summary: + // A grid widget with virtual scrolling, cell editing, complex rows, + // sorting, fixed columns, sizeable columns, etc. + // + // description: + // _Grid provides the full set of grid features without any + // direct connection to a data store. + // + // The grid exposes a get function for the grid, or optionally + // individual columns, to populate cell contents. + // + // The grid is rendered based on its structure, an object describing + // column and cell layout. + // + // example: + // A quick sample: + // + // define a get function + // | function get(inRowIndex){ // called in cell context + // | return [this.index, inRowIndex].join(', '); + // | } + // + // define the grid structure: + // | var structure = [ // array of view objects + // | { cells: [// array of rows, a row is an array of cells + // | [ + // | { name: "Alpha", width: 6 }, + // | { name: "Beta" }, + // | { name: "Gamma", get: get }] + // | ]} + // | ]; + // + // | <div id="grid" + // | rowCount="100" get="get" + // | structure="structure" + // | dojoType="dojox.grid._Grid"></div> + + templateString: template, + + // classTag: String + // CSS class applied to the grid's domNode + classTag: 'dojoxGrid', + + // settings + // rowCount: Integer + // Number of rows to display. + rowCount: 5, + + // keepRows: Integer + // Number of rows to keep in the rendering cache. + keepRows: 75, + + // rowsPerPage: Integer + // Number of rows to render at a time. + rowsPerPage: 25, + + // autoWidth: Boolean + // If autoWidth is true, grid width is automatically set to fit the data. + autoWidth: false, + + // initialWidth: String + // A css string to use to set our initial width (only used if autoWidth + // is true). The first rendering of the grid will be this width, any + // resizing of columns, etc will result in the grid switching to + // autoWidth mode. Note, this width will override any styling in a + // stylesheet or directly on the node. + initialWidth: "", + + // autoHeight: Boolean|Integer + // If autoHeight is true, grid height is automatically set to fit the data. + // If it is an integer, the height will be automatically set to fit the data + // if there are fewer than that many rows - and the height will be set to show + // that many rows if there are more + autoHeight: '', + + // rowHeight: Integer + // If rowHeight is set to a positive number, it will define the height of the rows + // in pixels. This can provide a significant performance advantage, since it + // eliminates the need to measure row sizes during rendering, which is one + // the primary bottlenecks in the DataGrid's performance. + rowHeight: 0, + + // autoRender: Boolean + // If autoRender is true, grid will render itself after initialization. + autoRender: true, + + // defaultHeight: String + // default height of the grid, measured in any valid css unit. + defaultHeight: '15em', + + // height: String + // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden) + // if the height: css attribute exists on the source node. + height: '', + + // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] + // View layout defintion. + structure: null, + + // elasticView: Integer + // Override defaults and make the indexed grid view elastic, thus filling available horizontal space. + elasticView: -1, + + // singleClickEdit: boolean + // Single-click starts editing. Default is double-click + singleClickEdit: false, + + // selectionMode: String + // Set the selection mode of grid's Selection. Value must be 'single', 'multiple', + // or 'extended'. Default is 'extended'. + selectionMode: 'extended', + + // rowSelector: Boolean|String + // If set to true, will add a row selector view to this grid. If set to a CSS width, will add + // a row selector of that width to this grid. + rowSelector: '', + + // columnReordering: Boolean + // If set to true, will add drag and drop reordering to views with one row of columns. + columnReordering: false, + + // headerMenu: dijit.Menu + // If set to a dijit.Menu, will use this as a context menu for the grid headers. + headerMenu: null, + + // placeholderLabel: String + // Label of placeholders to search for in the header menu to replace with column toggling + // menu items. + placeholderLabel: "GridColumns", + + // selectable: Boolean + // Set to true if you want to be able to select the text within the grid. + selectable: false, + + // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row + _click: null, + + // loadingMessage: String + // Message that shows while the grid is loading + loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>", + + // errorMessage: String + // Message that shows when the grid encounters an error loading + errorMessage: "<span class='dojoxGridError'>${errorState}</span>", + + // noDataMessage: String + // Message that shows if the grid has no data - wrap it in a + // span with class 'dojoxGridNoData' if you want it to be + // styled similar to the loading and error messages + noDataMessage: "", + + // escapeHTMLInData: Boolean + // This will escape HTML brackets from the data to prevent HTML from + // user-inputted data being rendered with may contain JavaScript and result in + // XSS attacks. This is true by default, and it is recommended that it remain + // true. Setting this to false will allow data to be displayed in the grid without + // filtering, and should be only used if it is known that the data won't contain + // malicious scripts. If HTML is needed in grid cells, it is recommended that + // you use the formatter function to generate the HTML (the output of + // formatter functions is not filtered, even with escapeHTMLInData set to true). + escapeHTMLInData: true, + + // formatterScope: Object + // An object to execute format functions within. If not set, the + // format functions will execute within the scope of the cell that + // has a format function. + formatterScope: null, + + // editable: boolean + // indicates if the grid contains editable cells, default is false + // set to true if editable cell encountered during rendering + editable: false, + + // private + sortInfo: 0, + themeable: true, + _placeholders: null, + + // _layoutClass: Object + // The class to use for our layout - can be overridden by grid subclasses + _layoutClass: _Layout, + + // initialization + buildRendering: function(){ + this.inherited(arguments); + if(!this.domNode.getAttribute('tabIndex')){ + this.domNode.tabIndex = "0"; + } + this.createScroller(); + this.createLayout(); + this.createViews(); + this.createManagers(); + + this.createSelection(); + + this.connect(this.selection, "onSelected", "onSelected"); + this.connect(this.selection, "onDeselected", "onDeselected"); + this.connect(this.selection, "onChanged", "onSelectionChanged"); + + metrics.initOnFontResize(); + this.connect(metrics, "onFontResize", "textSizeChanged"); + util.funnelEvents(this.domNode, this, 'doKeyEvent', util.keyEvents); + if (this.selectionMode != "none") { + this.domNode.setAttribute("aria-multiselectable", this.selectionMode == "single" ? "false" : "true"); + } + + html.addClass(this.domNode, this.classTag); + if(!this.isLeftToRight()){ + html.addClass(this.domNode, this.classTag+"Rtl"); + } + }, + + postMixInProperties: function(){ + this.inherited(arguments); + var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang); + this.loadingMessage = string.substitute(this.loadingMessage, messages); + this.errorMessage = string.substitute(this.errorMessage, messages); + if(this.srcNodeRef && this.srcNodeRef.style.height){ + this.height = this.srcNodeRef.style.height; + } + // Call this to update our autoheight to start out + this._setAutoHeightAttr(this.autoHeight, true); + this.lastScrollTop = this.scrollTop = 0; + }, + + postCreate: function(){ + this._placeholders = []; + this._setHeaderMenuAttr(this.headerMenu); + this._setStructureAttr(this.structure); + this._click = []; + this.inherited(arguments); + if(this.domNode && this.autoWidth && this.initialWidth){ + this.domNode.style.width = this.initialWidth; + } + if (this.domNode && !this.editable){ + // default value for aria-readonly is false, set to true if grid is not editable + html.attr(this.domNode,"aria-readonly", "true"); + } + }, + + destroy: function(){ + this.domNode.onReveal = null; + this.domNode.onSizeChange = null; + + // Fixes IE domNode leak + delete this._click; + + if(this.scroller){ + this.scroller.destroy(); + delete this.scroller; + } + this.edit.destroy(); + delete this.edit; + this.views.destroyViews(); + if(this.focus){ + this.focus.destroy(); + delete this.focus; + } + if(this.headerMenu&&this._placeholders.length){ + array.forEach(this._placeholders, function(p){ p.unReplace(true); }); + this.headerMenu.unBindDomNode(this.viewsHeaderNode); + } + this.inherited(arguments); + }, + + _setAutoHeightAttr: function(ah, skipRender){ + // Calculate our autoheight - turn it into a boolean or an integer + if(typeof ah == "string"){ + if(!ah || ah == "false"){ + ah = false; + }else if (ah == "true"){ + ah = true; + }else{ + ah = window.parseInt(ah, 10); + } + } + if(typeof ah == "number"){ + if(isNaN(ah)){ + ah = false; + } + // Autoheight must be at least 1, if it's a number. If it's + // less than 0, we'll take that to mean "all" rows (same as + // autoHeight=true - if it is equal to zero, we'll take that + // to mean autoHeight=false + if(ah < 0){ + ah = true; + }else if (ah === 0){ + ah = false; + } + } + this.autoHeight = ah; + if(typeof ah == "boolean"){ + this._autoHeight = ah; + }else if(typeof ah == "number"){ + this._autoHeight = (ah >= this.get('rowCount')); + }else{ + this._autoHeight = false; + } + if(this._started && !skipRender){ + this.render(); + } + }, + + _getRowCountAttr: function(){ + return this.updating && this.invalidated && this.invalidated.rowCount != undefined ? + this.invalidated.rowCount : this.rowCount; + }, + + textSizeChanged: function(){ + this.render(); + }, + + sizeChange: function(){ + this.update(); + }, + + createManagers: function(){ + // summary: + // create grid managers for various tasks including rows, focus, selection, editing + + // row manager + this.rows = new _RowManager(this); + // focus manager + this.focus = new _FocusManager(this); + // edit manager + this.edit = new _EditManager(this); + }, + + createSelection: function(){ + // summary: Creates a new Grid selection manager. + + // selection manager + this.selection = new Selection(this); + }, + + createScroller: function(){ + // summary: Creates a new virtual scroller + this.scroller = new _Scroller(); + this.scroller.grid = this; + this.scroller.renderRow = lang.hitch(this, "renderRow"); + this.scroller.removeRow = lang.hitch(this, "rowRemoved"); + }, + + createLayout: function(){ + // summary: Creates a new Grid layout + this.layout = new this._layoutClass(this); + this.connect(this.layout, "moveColumn", "onMoveColumn"); + }, + + onMoveColumn: function(){ + this.render(); + }, + + onResizeColumn: function(/*int*/ cellIdx){ + // Called when a column is resized. + }, + + // views + createViews: function(){ + this.views = new _ViewManager(this); + this.views.createView = lang.hitch(this, "createView"); + }, + + createView: function(inClass, idx){ + var c = lang.getObject(inClass); + var view = new c({ grid: this, index: idx }); + this.viewsNode.appendChild(view.domNode); + this.viewsHeaderNode.appendChild(view.headerNode); + this.views.addView(view); + html.attr(this.domNode, "align", this.isLeftToRight() ? 'left' : 'right'); + return view; + }, + + buildViews: function(){ + for(var i=0, vs; (vs=this.layout.structure[i]); i++){ + this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs); + } + this.scroller.setContentNodes(this.views.getContentNodes()); + }, + + _setStructureAttr: function(structure){ + var s = structure; + if(s && lang.isString(s)){ + dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0"); + s=lang.getObject(s); + } + this.structure = s; + if(!s){ + if(this.layout.structure){ + s = this.layout.structure; + }else{ + return; + } + } + this.views.destroyViews(); + this.focus.focusView = null; + if(s !== this.layout.structure){ + this.layout.setStructure(s); + } + this._structureChanged(); + }, + + setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){ + // summary: + // Install a new structure and rebuild the grid. + dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0"); + this._setStructureAttr(inStructure); + }, + + getColumnTogglingItems: function(){ + // Summary: returns an array of dijit.CheckedMenuItem widgets that can be + // added to a menu for toggling columns on and off. + var items, checkedItems = []; + items = array.map(this.layout.cells, function(cell){ + if(!cell.menuItems){ cell.menuItems = []; } + + var self = this; + var item = new CheckedMenuItem({ + label: cell.name, + checked: !cell.hidden, + _gridCell: cell, + onChange: function(checked){ + if(self.layout.setColumnVisibility(this._gridCell.index, checked)){ + var items = this._gridCell.menuItems; + if(items.length > 1){ + array.forEach(items, function(item){ + if(item !== this){ + item.setAttribute("checked", checked); + } + }, this); + } + checked = array.filter(self.layout.cells, function(c){ + if(c.menuItems.length > 1){ + array.forEach(c.menuItems, "item.set('disabled', false);"); + }else{ + c.menuItems[0].set('disabled', false); + } + return !c.hidden; + }); + if(checked.length == 1){ + array.forEach(checked[0].menuItems, "item.set('disabled', true);"); + } + } + }, + destroy: function(){ + var index = array.indexOf(this._gridCell.menuItems, this); + this._gridCell.menuItems.splice(index, 1); + delete this._gridCell; + CheckedMenuItem.prototype.destroy.apply(this, arguments); + } + }); + cell.menuItems.push(item); + if(!cell.hidden) { + checkedItems.push(item); + } + return item; + }, this); // dijit.CheckedMenuItem[] + if(checkedItems.length == 1) { + checkedItems[0].set('disabled', true); + } + return items; + }, + + _setHeaderMenuAttr: function(menu){ + if(this._placeholders && this._placeholders.length){ + array.forEach(this._placeholders, function(p){ + p.unReplace(true); + }); + this._placeholders = []; + } + if(this.headerMenu){ + this.headerMenu.unBindDomNode(this.viewsHeaderNode); + } + this.headerMenu = menu; + if(!menu){ return; } + + this.headerMenu.bindDomNode(this.viewsHeaderNode); + if(this.headerMenu.getPlaceholders){ + this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel); + } + }, + + setHeaderMenu: function(/* dijit.Menu */ menu){ + dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0"); + this._setHeaderMenuAttr(menu); + }, + + setupHeaderMenu: function(){ + if(this._placeholders && this._placeholders.length){ + array.forEach(this._placeholders, function(p){ + if(p._replaced){ + p.unReplace(true); + } + p.replace(this.getColumnTogglingItems()); + }, this); + } + }, + + _fetch: function(start){ + this.setScrollTop(0); + }, + + getItem: function(inRowIndex){ + return null; + }, + + showMessage: function(message){ + if(message){ + this.messagesNode.innerHTML = message; + this.messagesNode.style.display = ""; + }else{ + this.messagesNode.innerHTML = ""; + this.messagesNode.style.display = "none"; + } + }, + + _structureChanged: function() { + this.buildViews(); + if(this.autoRender && this._started){ + this.render(); + } + }, + + hasLayout: function() { + return this.layout.cells.length; + }, + + // sizing + resize: function(changeSize, resultSize){ + // summary: + // Update the grid's rendering dimensions and resize it + + // Calling sizeChange calls update() which calls _resize...so let's + // save our input values, if any, and use them there when it gets + // called. This saves us an extra call to _resize(), which can + // get kind of heavy. + + // fixes #11101, should ignore resize when in autoheight mode(IE) to avoid a deadlock + // e.g when an autoheight editable grid put in dijit.form.Form or other similar containers, + // grid switch to editing mode --> grid height change --> From height change + // ---> Form call grid.resize() ---> grid height change --> deaklock + if(dojo.isIE && !changeSize && !resultSize && this._autoHeight){ + return; + } + this._pendingChangeSize = changeSize; + this._pendingResultSize = resultSize; + this.sizeChange(); + }, + + _getPadBorder: function() { + this._padBorder = this._padBorder || html._getPadBorderExtents(this.domNode); + return this._padBorder; + }, + + _getHeaderHeight: function(){ + var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader(); + vns.height = t + 'px'; + // header heights are reset during measuring so must be normalized after measuring. + this.views.normalizeHeaderNodeHeight(); + return t; + }, + + _resize: function(changeSize, resultSize){ + // Restore our pending values, if any + changeSize = changeSize || this._pendingChangeSize; + resultSize = resultSize || this._pendingResultSize; + delete this._pendingChangeSize; + delete this._pendingResultSize; + // if we have set up everything except the DOM, we cannot resize + if(!this.domNode){ return; } + var pn = this.domNode.parentNode; + if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){ + return; + } + // useful measurement + var padBorder = this._getPadBorder(); + var hh = undefined; + var h; + // grid height + if(this._autoHeight){ + this.domNode.style.height = 'auto'; + }else if(typeof this.autoHeight == "number"){ + h = hh = this._getHeaderHeight(); + h += (this.scroller.averageRowHeight * this.autoHeight); + this.domNode.style.height = h + "px"; + }else if(this.domNode.clientHeight <= padBorder.h){ + if(pn == document.body){ + this.domNode.style.height = this.defaultHeight; + }else if(this.height){ + this.domNode.style.height = this.height; + }else{ + this.fitTo = "parent"; + } + } + // if we are given dimensions, size the grid's domNode to those dimensions + if(resultSize){ + changeSize = resultSize; + } + if(!this._autoHeight && changeSize){ + html.marginBox(this.domNode, changeSize); + this.height = this.domNode.style.height; + delete this.fitTo; + }else if(this.fitTo == "parent"){ + h = this._parentContentBoxHeight = this._parentContentBoxHeight || html._getContentBox(pn).h; + this.domNode.style.height = Math.max(0, h) + "px"; + } + + var hasFlex = array.some(this.views.views, function(v){ return v.flexCells; }); + + if(!this._autoHeight && (h || html._getContentBox(this.domNode).h) === 0){ + // We need to hide the header, since the Grid is essentially hidden. + this.viewsHeaderNode.style.display = "none"; + }else{ + // Otherwise, show the header and give it an appropriate height. + this.viewsHeaderNode.style.display = "block"; + if(!hasFlex && hh === undefined){ + hh = this._getHeaderHeight(); + } + } + if(hasFlex){ + hh = undefined; + } + + // NOTE: it is essential that width be applied before height + // Header height can only be calculated properly after view widths have been set. + // This is because flex column width is naturally 0 in Firefox. + // Therefore prior to width sizing flex columns with spaces are maximally wrapped + // and calculated to be too tall. + this.adaptWidth(); + this.adaptHeight(hh); + + this.postresize(); + }, + + adaptWidth: function() { + // private: sets width and position for views and update grid width if necessary + var doAutoWidth = (!this.initialWidth && this.autoWidth); + var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w), + vw = this.views.arrange(1, w); + this.views.onEach("adaptWidth"); + if(doAutoWidth){ + this.domNode.style.width = vw + "px"; + } + }, + + adaptHeight: function(inHeaderHeight){ + // private: measures and normalizes header height, then sets view heights, and then updates scroller + // content extent + var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight; + var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0); + this.views.onEach('setSize', [0, h]); + this.views.onEach('adaptHeight'); + if(!this._autoHeight){ + var numScroll = 0, numNoScroll = 0; + var noScrolls = array.filter(this.views.views, function(v){ + var has = v.hasHScrollbar(); + if(has){ numScroll++; }else{ numNoScroll++; } + return (!has); + }); + if(numScroll > 0 && numNoScroll > 0){ + array.forEach(noScrolls, function(v){ + v.adaptHeight(true); + }); + } + } + if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){ + this.scroller.windowHeight = h; + }else{ + this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0); + } + }, + + // startup + startup: function(){ + if(this._started){return;} + this.inherited(arguments); + if(this.autoRender){ + this.render(); + } + }, + + // render + render: function(){ + // summary: + // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and + // scrolling states, see Update. + + if(!this.domNode){return;} + if(!this._started){return;} + + if(!this.hasLayout()) { + this.scroller.init(0, this.keepRows, this.rowsPerPage); + return; + } + // + this.update = this.defaultUpdate; + this._render(); + }, + + _render: function(){ + this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage); + this.prerender(); + this.setScrollTop(0); + this.postrender(); + }, + + prerender: function(){ + // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered. + this.keepRows = this._autoHeight ? 0 : this.keepRows; + this.scroller.setKeepInfo(this.keepRows); + this.views.render(); + this._resize(); + }, + + postrender: function(){ + this.postresize(); + this.focus.initFocusView(); + // make rows unselectable + html.setSelectable(this.domNode, this.selectable); + }, + + postresize: function(){ + // views are position absolute, so they do not inflate the parent + if(this._autoHeight){ + var size = Math.max(this.views.measureContent()) + 'px'; + + this.viewsNode.style.height = size; + } + }, + + renderRow: function(inRowIndex, inNodes){ + // summary: private, used internally to render rows + this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize); + }, + + rowRemoved: function(inRowIndex){ + // summary: private, used internally to remove rows + this.views.rowRemoved(inRowIndex); + }, + + invalidated: null, + + updating: false, + + beginUpdate: function(){ + // summary: + // Use to make multiple changes to rows while queueing row updating. + // NOTE: not currently supporting nested begin/endUpdate calls + this.invalidated = []; + this.updating = true; + }, + + endUpdate: function(){ + // summary: + // Use after calling beginUpdate to render any changes made to rows. + this.updating = false; + var i = this.invalidated, r; + if(i.all){ + this.update(); + }else if(i.rowCount != undefined){ + this.updateRowCount(i.rowCount); + }else{ + for(r in i){ + this.updateRow(Number(r)); + } + } + this.invalidated = []; + }, + + // update + defaultUpdate: function(){ + // note: initial update calls render and subsequently this function. + if(!this.domNode){return;} + if(this.updating){ + this.invalidated.all = true; + return; + } + //this.edit.saveState(inRowIndex); + this.lastScrollTop = this.scrollTop; + this.prerender(); + this.scroller.invalidateNodes(); + this.setScrollTop(this.lastScrollTop); + this.postrender(); + //this.edit.restoreState(inRowIndex); + }, + + update: function(){ + // summary: + // Update the grid, retaining edit and scrolling states. + this.render(); + }, + + updateRow: function(inRowIndex){ + // summary: + // Render a single row. + // inRowIndex: Integer + // Index of the row to render + inRowIndex = Number(inRowIndex); + if(this.updating){ + this.invalidated[inRowIndex]=true; + }else{ + this.views.updateRow(inRowIndex); + this.scroller.rowHeightChanged(inRowIndex); + } + }, + + updateRows: function(startIndex, howMany){ + // summary: + // Render consecutive rows at once. + // startIndex: Integer + // Index of the starting row to render + // howMany: Integer + // How many rows to update. + startIndex = Number(startIndex); + howMany = Number(howMany); + var i; + if(this.updating){ + for(i=0; i<howMany; i++){ + this.invalidated[i+startIndex]=true; + } + }else{ + for(i=0; i<howMany; i++){ + this.views.updateRow(i+startIndex, this._skipRowRenormalize); + } + this.scroller.rowHeightChanged(startIndex); + } + }, + + updateRowCount: function(inRowCount){ + //summary: + // Change the number of rows. + // inRowCount: int + // Number of rows in the grid. + if(this.updating){ + this.invalidated.rowCount = inRowCount; + }else{ + this.rowCount = inRowCount; + this._setAutoHeightAttr(this.autoHeight, true); + if(this.layout.cells.length){ + this.scroller.updateRowCount(inRowCount); + } + this._resize(); + if(this.layout.cells.length){ + this.setScrollTop(this.scrollTop); + } + } + }, + + updateRowStyles: function(inRowIndex){ + // summary: + // Update the styles for a row after it's state has changed. + this.views.updateRowStyles(inRowIndex); + }, + getRowNode: function(inRowIndex){ + // summary: + // find the rowNode that is not a rowSelector + if (this.focus.focusView && !(this.focus.focusView instanceof _RowSelector)){ + return this.focus.focusView.rowNodes[inRowIndex]; + }else{ // search through views + for (var i = 0, cView; (cView = this.views.views[i]); i++) { + if (!(cView instanceof _RowSelector)) { + return cView.rowNodes[inRowIndex]; + } + } + } + return null; + }, + rowHeightChanged: function(inRowIndex){ + // summary: + // Update grid when the height of a row has changed. Row height is handled automatically as rows + // are rendered. Use this function only to update a row's height outside the normal rendering process. + // inRowIndex: Integer + // index of the row that has changed height + + this.views.renormalizeRow(inRowIndex); + this.scroller.rowHeightChanged(inRowIndex); + }, + + // fastScroll: Boolean + // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower + // scroll performance but more immediate scrolling feedback + fastScroll: true, + + delayScroll: false, + + // scrollRedrawThreshold: int + // pixel distance a user must scroll vertically to trigger grid scrolling. + scrollRedrawThreshold: (has("ie") ? 100 : 50), + + // scroll methods + scrollTo: function(inTop){ + // summary: + // Vertically scroll the grid to a given pixel position + // inTop: Integer + // vertical position of the grid in pixels + if(!this.fastScroll){ + this.setScrollTop(inTop); + return; + } + var delta = Math.abs(this.lastScrollTop - inTop); + this.lastScrollTop = inTop; + if(delta > this.scrollRedrawThreshold || this.delayScroll){ + this.delayScroll = true; + this.scrollTop = inTop; + this.views.setScrollTop(inTop); + if(this._pendingScroll){ + window.clearTimeout(this._pendingScroll); + } + var _this = this; + this._pendingScroll = window.setTimeout(function(){ + delete _this._pendingScroll; + _this.finishScrollJob(); + }, 200); + }else{ + this.setScrollTop(inTop); + } + }, + + finishScrollJob: function(){ + this.delayScroll = false; + this.setScrollTop(this.scrollTop); + }, + + setScrollTop: function(inTop){ + this.scroller.scroll(this.views.setScrollTop(inTop)); + }, + + scrollToRow: function(inRowIndex){ + // summary: + // Scroll the grid to a specific row. + // inRowIndex: Integer + // grid row index + this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1); + }, + + // styling (private, used internally to style individual parts of a row) + styleRowNode: function(inRowIndex, inRowNode){ + if(inRowNode){ + this.rows.styleRowNode(inRowIndex, inRowNode); + } + }, + + // called when the mouse leaves the grid so we can deselect all hover rows + _mouseOut: function(e){ + this.rows.setOverRow(-2); + }, + + // cells + getCell: function(inIndex){ + // summary: + // Retrieves the cell object for a given grid column. + // inIndex: Integer + // Grid column index of cell to retrieve + // returns: + // a grid cell + return this.layout.cells[inIndex]; + }, + + setCellWidth: function(inIndex, inUnitWidth){ + this.getCell(inIndex).unitWidth = inUnitWidth; + }, + + getCellName: function(inCell){ + // summary: Returns the cell name of a passed cell + return "Cell " + inCell.index; // String + }, + + // sorting + canSort: function(inSortInfo){ + // summary: + // Determines if the grid can be sorted + // inSortInfo: Integer + // Sort information, 1-based index of column on which to sort, positive for an ascending sort + // and negative for a descending sort + // returns: Boolean + // True if grid can be sorted on the given column in the given direction + }, + + sort: function(){ + }, + + getSortAsc: function(inSortInfo){ + // summary: + // Returns true if grid is sorted in an ascending direction. + inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo; + return Boolean(inSortInfo > 0); // Boolean + }, + + getSortIndex: function(inSortInfo){ + // summary: + // Returns the index of the column on which the grid is sorted + inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo; + return Math.abs(inSortInfo) - 1; // Integer + }, + + setSortIndex: function(inIndex, inAsc){ + // summary: + // Sort the grid on a column in a specified direction + // inIndex: Integer + // Column index on which to sort. + // inAsc: Boolean + // If true, sort the grid in ascending order, otherwise in descending order + var si = inIndex +1; + if(inAsc != undefined){ + si *= (inAsc ? 1 : -1); + } else if(this.getSortIndex() == inIndex){ + si = -this.sortInfo; + } + this.setSortInfo(si); + }, + + setSortInfo: function(inSortInfo){ + if(this.canSort(inSortInfo)){ + this.sortInfo = inSortInfo; + this.sort(); + this.update(); + } + }, + + // DOM event handler + doKeyEvent: function(e){ + e.dispatch = 'do' + e.type; + this.onKeyEvent(e); + }, + + // event dispatch + //: protected + _dispatch: function(m, e){ + if(m in this){ + return this[m](e); + } + return false; + }, + + dispatchKeyEvent: function(e){ + this._dispatch(e.dispatch, e); + }, + + dispatchContentEvent: function(e){ + this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e); + }, + + dispatchHeaderEvent: function(e){ + e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e); + }, + + dokeydown: function(e){ + this.onKeyDown(e); + }, + + doclick: function(e){ + if(e.cellNode){ + this.onCellClick(e); + }else{ + this.onRowClick(e); + } + }, + + dodblclick: function(e){ + if(e.cellNode){ + this.onCellDblClick(e); + }else{ + this.onRowDblClick(e); + } + }, + + docontextmenu: function(e){ + if(e.cellNode){ + this.onCellContextMenu(e); + }else{ + this.onRowContextMenu(e); + } + }, + + doheaderclick: function(e){ + if(e.cellNode){ + this.onHeaderCellClick(e); + }else{ + this.onHeaderClick(e); + } + }, + + doheaderdblclick: function(e){ + if(e.cellNode){ + this.onHeaderCellDblClick(e); + }else{ + this.onHeaderDblClick(e); + } + }, + + doheadercontextmenu: function(e){ + if(e.cellNode){ + this.onHeaderCellContextMenu(e); + }else{ + this.onHeaderContextMenu(e); + } + }, + + // override to modify editing process + doStartEdit: function(inCell, inRowIndex){ + this.onStartEdit(inCell, inRowIndex); + }, + + doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){ + this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex); + }, + + doCancelEdit: function(inRowIndex){ + this.onCancelEdit(inRowIndex); + }, + + doApplyEdit: function(inRowIndex){ + this.onApplyEdit(inRowIndex); + }, + + // row editing + addRow: function(){ + // summary: + // Add a row to the grid. + this.updateRowCount(this.get('rowCount')+1); + }, + + removeSelectedRows: function(){ + // summary: + // Remove the selected rows from the grid. + if(this.allItemsSelected){ + this.updateRowCount(0); + }else{ + this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length)); + } + this.selection.clear(); + } + + }); + + _Grid.markupFactory = function(props, node, ctor, cellFunc){ + var widthFromAttr = function(n){ + var w = html.attr(n, "width")||"auto"; + if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){ + w = parseInt(w, 10)+"px"; + } + return w; + }; + // if(!props.store){ console.debug("no store!"); } + // if a structure isn't referenced, do we have enough + // data to try to build one automatically? + if( !props.structure && + node.nodeName.toLowerCase() == "table"){ + + // try to discover a structure + props.structure = query("> colgroup", node).map(function(cg){ + var sv = html.attr(cg, "span"); + var v = { + noscroll: (html.attr(cg, "noscroll") == "true") ? true : false, + __span: (!!sv ? parseInt(sv, 10) : 1), + cells: [] + }; + if(html.hasAttr(cg, "width")){ + v.width = widthFromAttr(cg); + } + return v; // for vendetta + }); + if(!props.structure.length){ + props.structure.push({ + __span: Infinity, + cells: [] // catch-all view + }); + } + // check to see if we're gonna have more than one view + + // for each tr in our th, create a row of cells + query("thead > tr", node).forEach(function(tr, tr_idx){ + var cellCount = 0; + var viewIdx = 0; + var lastViewIdx; + var cView = null; + query("> th", tr).map(function(th){ + // what view will this cell go into? + + // NOTE: + // to prevent extraneous iteration, we start counters over + // for each row, incrementing over the surface area of the + // structure that colgroup processing generates and + // creating cell objects for each <th> to place into those + // cell groups. There's a lot of state-keepking logic + // here, but it is what it has to be. + if(!cView){ // current view book keeping + lastViewIdx = 0; + cView = props.structure[0]; + }else if(cellCount >= (lastViewIdx+cView.__span)){ + viewIdx++; + // move to allocating things into the next view + lastViewIdx += cView.__span; + var lastView = cView; + cView = props.structure[viewIdx]; + } + + // actually define the cell from what markup hands us + var cell = { + name: lang.trim(html.attr(th, "name")||th.innerHTML), + colSpan: parseInt(html.attr(th, "colspan")||1, 10), + type: lang.trim(html.attr(th, "cellType")||""), + id: lang.trim(html.attr(th,"id")||"") + }; + cellCount += cell.colSpan; + var rowSpan = html.attr(th, "rowspan"); + if(rowSpan){ + cell.rowSpan = rowSpan; + } + if(html.hasAttr(th, "width")){ + cell.width = widthFromAttr(th); + } + if(html.hasAttr(th, "relWidth")){ + cell.relWidth = window.parseInt(html.attr(th, "relWidth"), 10); + } + if(html.hasAttr(th, "hidden")){ + cell.hidden = (html.attr(th, "hidden") == "true" || html.attr(th, "hidden") === true/*always boolean true in Chrome*/); + } + + if(cellFunc){ + cellFunc(th, cell); + } + + cell.type = cell.type ? lang.getObject(cell.type) : dojox.grid.cells.Cell; + + if(cell.type && cell.type.markupFactory){ + cell.type.markupFactory(th, cell); + } + + if(!cView.cells[tr_idx]){ + cView.cells[tr_idx] = []; + } + cView.cells[tr_idx].push(cell); + }); + }); + } + + return new ctor(props, node); + }; + + return _Grid; + +}); +}, +'dijit/nls/loading':function(){ +define("dijit/nls/loading", { root: +//begin v1.x content +({ + loadingState: "Loading...", + errorState: "Sorry, an error occurred" +}) +//end v1.x content +, +"zh": true, +"zh-tw": true, +"tr": true, +"th": true, +"sv": true, +"sl": true, +"sk": true, +"ru": true, +"ro": true, +"pt": true, +"pt-pt": true, +"pl": true, +"nl": true, +"nb": true, +"ko": true, +"kk": true, +"ja": true, +"it": true, +"hu": true, +"hr": true, +"he": true, +"fr": true, +"fi": true, +"es": true, +"el": true, +"de": true, +"da": true, +"cs": true, +"ca": true, +"az": true, +"ar": true +}); + +}, +'dojox/main':function(){ +define("dojox/main", ["dojo/_base/kernel"], function(dojo) { + // module: + // dojox/main + // summary: + // The dojox package main module; dojox package is somewhat unusual in that the main module currently just provides an empty object. + + return dojo.dojox; +}); +}, +'dojo/dnd/Mover':function(){ +define(["../main", "../Evented", "../touch", "./common", "./autoscroll"], function(dojo, Evented, touch) { + // module: + // dojo/dnd/Mover + // summary: + // TODOC + + +dojo.declare("dojo.dnd.Mover", [Evented], { + constructor: function(node, e, host){ + // summary: + // an object which makes a node follow the mouse, or touch-drag on touch devices. + // Used as a default mover, and as a base class for custom movers. + // node: Node + // a node (or node's id) to be moved + // e: Event + // a mouse event, which started the move; + // only pageX and pageY properties are used + // host: Object? + // object which implements the functionality of the move, + // and defines proper events (onMoveStart and onMoveStop) + this.node = dojo.byId(node); + this.marginBox = {l: e.pageX, t: e.pageY}; + this.mouseButton = e.button; + var h = (this.host = host), d = node.ownerDocument; + this.events = [ + // At the start of a drag, onFirstMove is called, and then the following two + // connects are disconnected + dojo.connect(d, touch.move, this, "onFirstMove"), + + // These are called continually during the drag + dojo.connect(d, touch.move, this, "onMouseMove"), + + // And these are called at the end of the drag + dojo.connect(d, touch.release, this, "onMouseUp"), + + // cancel text selection and text dragging + dojo.connect(d, "ondragstart", dojo.stopEvent), + dojo.connect(d.body, "onselectstart", dojo.stopEvent) + ]; + // notify that the move has started + if(h && h.onMoveStart){ + h.onMoveStart(this); + } + }, + // mouse event processors + onMouseMove: function(e){ + // summary: + // event processor for onmousemove/ontouchmove + // e: Event + // mouse/touch event + dojo.dnd.autoScroll(e); + var m = this.marginBox; + this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e); + dojo.stopEvent(e); + }, + onMouseUp: function(e){ + if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ? + e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too? + this.destroy(); + } + dojo.stopEvent(e); + }, + // utilities + onFirstMove: function(e){ + // summary: + // makes the node absolute; it is meant to be called only once. + // relative and absolutely positioned nodes are assumed to use pixel units + var s = this.node.style, l, t, h = this.host; + switch(s.position){ + case "relative": + case "absolute": + // assume that left and top values are in pixels already + l = Math.round(parseFloat(s.left)) || 0; + t = Math.round(parseFloat(s.top)) || 0; + break; + default: + s.position = "absolute"; // enforcing the absolute mode + var m = dojo.marginBox(this.node); + // event.pageX/pageY (which we used to generate the initial + // margin box) includes padding and margin set on the body. + // However, setting the node's position to absolute and then + // doing dojo.marginBox on it *doesn't* take that additional + // space into account - so we need to subtract the combined + // padding and margin. We use getComputedStyle and + // _getMarginBox/_getContentBox to avoid the extra lookup of + // the computed style. + var b = dojo.doc.body; + var bs = dojo.getComputedStyle(b); + var bm = dojo._getMarginBox(b, bs); + var bc = dojo._getContentBox(b, bs); + l = m.l - (bc.l - bm.l); + t = m.t - (bc.t - bm.t); + break; + } + this.marginBox.l = l - this.marginBox.l; + this.marginBox.t = t - this.marginBox.t; + if(h && h.onFirstMove){ + h.onFirstMove(this, e); + } + + // Disconnect onmousemove and ontouchmove events that call this function + dojo.disconnect(this.events.shift()); + }, + destroy: function(){ + // summary: + // stops the move, deletes all references, so the object can be garbage-collected + dojo.forEach(this.events, dojo.disconnect); + // undo global settings + var h = this.host; + if(h && h.onMoveStop){ + h.onMoveStop(this); + } + // destroy objects + this.events = this.node = this.host = null; + } +}); + +return dojo.dnd.Mover; +}); + +}, +'dojo/Stateful':function(){ +define(["./_base/kernel", "./_base/declare", "./_base/lang", "./_base/array"], function(dojo, declare, lang, array) { + // module: + // dojo/Stateful + // summary: + // TODOC + +return dojo.declare("dojo.Stateful", null, { + // summary: + // Base class for objects that provide named properties with optional getter/setter + // control and the ability to watch for property changes + // example: + // | var obj = new dojo.Stateful(); + // | obj.watch("foo", function(){ + // | console.log("foo changed to " + this.get("foo")); + // | }); + // | obj.set("foo","bar"); + postscript: function(mixin){ + if(mixin){ + lang.mixin(this, mixin); + } + }, + + get: function(/*String*/name){ + // summary: + // Get a property on a Stateful instance. + // name: + // The property to get. + // returns: + // The property value on this Stateful instance. + // description: + // Get a named property on a Stateful object. The property may + // potentially be retrieved via a getter method in subclasses. In the base class + // this just retrieves the object's property. + // For example: + // | stateful = new dojo.Stateful({foo: 3}); + // | stateful.get("foo") // returns 3 + // | stateful.foo // returns 3 + + return this[name]; //Any + }, + set: function(/*String*/name, /*Object*/value){ + // summary: + // Set a property on a Stateful instance + // name: + // The property to set. + // value: + // The value to set in the property. + // returns: + // The function returns this dojo.Stateful instance. + // description: + // Sets named properties on a stateful object and notifies any watchers of + // the property. A programmatic setter may be defined in subclasses. + // For example: + // | stateful = new dojo.Stateful(); + // | stateful.watch(function(name, oldValue, value){ + // | // this will be called on the set below + // | } + // | stateful.set(foo, 5); + // + // set() may also be called with a hash of name/value pairs, ex: + // | myObj.set({ + // | foo: "Howdy", + // | bar: 3 + // | }) + // This is equivalent to calling set(foo, "Howdy") and set(bar, 3) + if(typeof name === "object"){ + for(var x in name){ + this.set(x, name[x]); + } + return this; + } + var oldValue = this[name]; + this[name] = value; + if(this._watchCallbacks){ + this._watchCallbacks(name, oldValue, value); + } + return this; //dojo.Stateful + }, + watch: function(/*String?*/name, /*Function*/callback){ + // summary: + // Watches a property for changes + // name: + // Indicates the property to watch. This is optional (the callback may be the + // only parameter), and if omitted, all the properties will be watched + // returns: + // An object handle for the watch. The unwatch method of this object + // can be used to discontinue watching this property: + // | var watchHandle = obj.watch("foo", callback); + // | watchHandle.unwatch(); // callback won't be called now + // callback: + // The function to execute when the property changes. This will be called after + // the property has been changed. The callback will be called with the |this| + // set to the instance, the first argument as the name of the property, the + // second argument as the old value and the third argument as the new value. + + var callbacks = this._watchCallbacks; + if(!callbacks){ + var self = this; + callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){ + var notify = function(propertyCallbacks){ + if(propertyCallbacks){ + propertyCallbacks = propertyCallbacks.slice(); + for(var i = 0, l = propertyCallbacks.length; i < l; i++){ + try{ + propertyCallbacks[i].call(self, name, oldValue, value); + }catch(e){ + console.error(e); + } + } + } + }; + notify(callbacks['_' + name]); + if(!ignoreCatchall){ + notify(callbacks["*"]); // the catch-all + } + }; // we use a function instead of an object so it will be ignored by JSON conversion + } + if(!callback && typeof name === "function"){ + callback = name; + name = "*"; + }else{ + // prepend with dash to prevent name conflicts with function (like "name" property) + name = '_' + name; + } + var propertyCallbacks = callbacks[name]; + if(typeof propertyCallbacks !== "object"){ + propertyCallbacks = callbacks[name] = []; + } + propertyCallbacks.push(callback); + return { + unwatch: function(){ + propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1); + } + }; //Object + } + +}); + +}); + +}, +'dojo/touch':function(){ +define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, mouse){ +// module: +// dojo/touch + +/*===== + dojo.touch = { + // summary: + // This module provides unified touch event handlers by exporting + // press, move, release and cancel which can also run well on desktop. + // Based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html + // + // example: + // 1. Used with dojo.connect() + // | dojo.connect(node, dojo.touch.press, function(e){}); + // | dojo.connect(node, dojo.touch.move, function(e){}); + // | dojo.connect(node, dojo.touch.release, function(e){}); + // | dojo.connect(node, dojo.touch.cancel, function(e){}); + // + // 2. Used with dojo.on + // | define(["dojo/on", "dojo/touch"], function(on, touch){ + // | on(node, touch.press, function(e){}); + // | on(node, touch.move, function(e){}); + // | on(node, touch.release, function(e){}); + // | on(node, touch.cancel, function(e){}); + // + // 3. Used with dojo.touch.* directly + // | dojo.touch.press(node, function(e){}); + // | dojo.touch.move(node, function(e){}); + // | dojo.touch.release(node, function(e){}); + // | dojo.touch.cancel(node, function(e){}); + + press: function(node, listener){ + // summary: + // Register a listener to 'touchstart'|'mousedown' for the given node + // node: Dom + // Target node to listen to + // listener: Function + // Callback function + // returns: + // A handle which will be used to remove the listener by handle.remove() + }, + move: function(node, listener){ + // summary: + // Register a listener to 'touchmove'|'mousemove' for the given node + // node: Dom + // Target node to listen to + // listener: Function + // Callback function + // returns: + // A handle which will be used to remove the listener by handle.remove() + }, + release: function(node, listener){ + // summary: + // Register a listener to 'touchend'|'mouseup' for the given node + // node: Dom + // Target node to listen to + // listener: Function + // Callback function + // returns: + // A handle which will be used to remove the listener by handle.remove() + }, + cancel: function(node, listener){ + // summary: + // Register a listener to 'touchcancel'|'mouseleave' for the given node + // node: Dom + // Target node to listen to + // listener: Function + // Callback function + // returns: + // A handle which will be used to remove the listener by handle.remove() + } + }; +=====*/ + + function _handle(/*String - press | move | release | cancel*/type){ + return function(node, listener){//called by on(), see dojo.on + return on(node, type, listener); + }; + } + var touch = has("touch"); + //device neutral events - dojo.touch.press|move|release|cancel + dojo.touch = { + press: _handle(touch ? "touchstart": "mousedown"), + move: _handle(touch ? "touchmove": "mousemove"), + release: _handle(touch ? "touchend": "mouseup"), + cancel: touch ? _handle("touchcancel") : mouse.leave + }; + return dojo.touch; +}); +}, +'dojox/grid/Selection':function(){ +define("dojox/grid/Selection", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/dom-attr" +], function(declare, array, lang, domAttr){ + +return declare("dojox.grid.Selection", null, { + // summary: + // Manages row selection for grid. Owned by grid and used internally + // for selection. Override to implement custom selection. + + constructor: function(inGrid){ + this.grid = inGrid; + this.selected = []; + + this.setMode(inGrid.selectionMode); + }, + + mode: 'extended', + + selected: null, + updating: 0, + selectedIndex: -1, + + setMode: function(mode){ + if(this.selected.length){ + this.deselectAll(); + } + if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){ + this.mode = 'extended'; + }else{ + this.mode = mode; + } + }, + + onCanSelect: function(inIndex){ + return this.grid.onCanSelect(inIndex); + }, + + onCanDeselect: function(inIndex){ + return this.grid.onCanDeselect(inIndex); + }, + + onSelected: function(inIndex){ + }, + + onDeselected: function(inIndex){ + }, + + //onSetSelected: function(inIndex, inSelect) { }; + onChanging: function(){ + }, + + onChanged: function(){ + }, + + isSelected: function(inIndex){ + if(this.mode == 'none'){ + return false; + } + return this.selected[inIndex]; + }, + + getFirstSelected: function(){ + if(!this.selected.length||this.mode == 'none'){ return -1; } + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + return i; + } + } + return -1; + }, + + getNextSelected: function(inPrev){ + if(this.mode == 'none'){ return -1; } + for(var i=inPrev+1, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + return i; + } + } + return -1; + }, + + getSelected: function(){ + var result = []; + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + result.push(i); + } + } + return result; + }, + + getSelectedCount: function(){ + var c = 0; + for(var i=0; i<this.selected.length; i++){ + if(this.selected[i]){ + c++; + } + } + return c; + }, + + _beginUpdate: function(){ + if(this.updating === 0){ + this.onChanging(); + } + this.updating++; + }, + + _endUpdate: function(){ + this.updating--; + if(this.updating === 0){ + this.onChanged(); + } + }, + + select: function(inIndex){ + if(this.mode == 'none'){ return; } + if(this.mode != 'multiple'){ + this.deselectAll(inIndex); + this.addToSelection(inIndex); + }else{ + this.toggleSelect(inIndex); + } + }, + + addToSelection: function(inIndex){ + if(this.mode == 'none'){ return; } + if(lang.isArray(inIndex)){ + array.forEach(inIndex, this.addToSelection, this); + return; + } + inIndex = Number(inIndex); + if(this.selected[inIndex]){ + this.selectedIndex = inIndex; + }else{ + if(this.onCanSelect(inIndex) !== false){ + this.selectedIndex = inIndex; + var rowNode = this.grid.getRowNode(inIndex); + if(rowNode){ + domAttr.set(rowNode, "aria-selected", "true"); + } + this._beginUpdate(); + this.selected[inIndex] = true; + //this.grid.onSelected(inIndex); + this.onSelected(inIndex); + //this.onSetSelected(inIndex, true); + this._endUpdate(); + } + } + }, + + deselect: function(inIndex){ + if(this.mode == 'none'){ return; } + if(lang.isArray(inIndex)){ + array.forEach(inIndex, this.deselect, this); + return; + } + inIndex = Number(inIndex); + if(this.selectedIndex == inIndex){ + this.selectedIndex = -1; + } + if(this.selected[inIndex]){ + if(this.onCanDeselect(inIndex) === false){ + return; + } + var rowNode = this.grid.getRowNode(inIndex); + if(rowNode){ + domAttr.set(rowNode, "aria-selected", "false"); + } + this._beginUpdate(); + delete this.selected[inIndex]; + //this.grid.onDeselected(inIndex); + this.onDeselected(inIndex); + //this.onSetSelected(inIndex, false); + this._endUpdate(); + } + }, + + setSelected: function(inIndex, inSelect){ + this[(inSelect ? 'addToSelection' : 'deselect')](inIndex); + }, + + toggleSelect: function(inIndex){ + if(lang.isArray(inIndex)){ + array.forEach(inIndex, this.toggleSelect, this); + return; + } + this.setSelected(inIndex, !this.selected[inIndex]); + }, + + _range: function(inFrom, inTo, func){ + var s = (inFrom >= 0 ? inFrom : inTo), e = inTo; + if(s > e){ + e = s; + s = inTo; + } + for(var i=s; i<=e; i++){ + func(i); + } + }, + + selectRange: function(inFrom, inTo){ + this._range(inFrom, inTo, lang.hitch(this, "addToSelection")); + }, + + deselectRange: function(inFrom, inTo){ + this._range(inFrom, inTo, lang.hitch(this, "deselect")); + }, + + insert: function(inIndex){ + this.selected.splice(inIndex, 0, false); + if(this.selectedIndex >= inIndex){ + this.selectedIndex++; + } + }, + + remove: function(inIndex){ + this.selected.splice(inIndex, 1); + if(this.selectedIndex >= inIndex){ + this.selectedIndex--; + } + }, + + deselectAll: function(inExcept){ + for(var i in this.selected){ + if((i!=inExcept)&&(this.selected[i]===true)){ + this.deselect(i); + } + } + }, + + clickSelect: function(inIndex, inCtrlKey, inShiftKey){ + if(this.mode == 'none'){ return; } + this._beginUpdate(); + if(this.mode != 'extended'){ + this.select(inIndex); + }else{ + var lastSelected = this.selectedIndex; + if(!inCtrlKey){ + this.deselectAll(inIndex); + } + if(inShiftKey){ + this.selectRange(lastSelected, inIndex); + }else if(inCtrlKey){ + this.toggleSelect(inIndex); + }else{ + this.addToSelection(inIndex); + } + } + this._endUpdate(); + }, + + clickSelectEvent: function(e){ + this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey); + }, + + clear: function(){ + this._beginUpdate(); + this.deselectAll(); + this._endUpdate(); + } +}); +}); +}, +'dijit/_CssStateMixin':function(){ +define("dijit/_CssStateMixin", [ + "dojo/touch", + "dojo/_base/array", // array.forEach array.map + "dojo/_base/declare", // declare + "dojo/dom-class", // domClass.toggle + "dojo/_base/lang", // lang.hitch + "dojo/_base/window" // win.body +], function(touch, array, declare, domClass, lang, win){ + +// module: +// dijit/_CssStateMixin +// summary: +// Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus +// state changes, and also higher-level state changes such becoming disabled or selected. + +return declare("dijit._CssStateMixin", [], { + // summary: + // Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus + // state changes, and also higher-level state changes such becoming disabled or selected. + // + // description: + // By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically + // maintain CSS classes on the widget root node (this.domNode) depending on hover, + // active, focus, etc. state. Ex: with a baseClass of dijitButton, it will apply the classes + // dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it. + // + // It also sets CSS like dijitButtonDisabled based on widget semantic state. + // + // By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons + // within the widget). + + // cssStateNodes: [protected] Object + // List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus + //. + // Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names + // (like "dijitUpArrowButton"). Example: + // | { + // | "upArrowButton": "dijitUpArrowButton", + // | "downArrowButton": "dijitDownArrowButton" + // | } + // The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it + // is hovered, etc. + cssStateNodes: {}, + + // hovering: [readonly] Boolean + // True if cursor is over this widget + hovering: false, + + // active: [readonly] Boolean + // True if mouse was pressed while over this widget, and hasn't been released yet + active: false, + + _applyAttributes: function(){ + // This code would typically be in postCreate(), but putting in _applyAttributes() for + // performance: so the class changes happen before DOM is inserted into the document. + // Change back to postCreate() in 2.0. See #11635. + + this.inherited(arguments); + + // Automatically monitor mouse events (essentially :hover and :active) on this.domNode + array.forEach(["onmouseenter", "onmouseleave", touch.press], function(e){ + this.connect(this.domNode, e, "_cssMouseEvent"); + }, this); + + // Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node + array.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){ + this.watch(attr, lang.hitch(this, "_setStateClass")); + }, this); + + // Events on sub nodes within the widget + for(var ap in this.cssStateNodes){ + this._trackMouseState(this[ap], this.cssStateNodes[ap]); + } + // Set state initially; there's probably no hover/active/focus state but widget might be + // disabled/readonly/checked/selected so we want to set CSS classes for those conditions. + this._setStateClass(); + }, + + _cssMouseEvent: function(/*Event*/ event){ + // summary: + // Sets hovering and active properties depending on mouse state, + // which triggers _setStateClass() to set appropriate CSS classes for this.domNode. + + if(!this.disabled){ + switch(event.type){ + case "mouseenter": + case "mouseover": // generated on non-IE browsers even though we connected to mouseenter + this._set("hovering", true); + this._set("active", this._mouseDown); + break; + + case "mouseleave": + case "mouseout": // generated on non-IE browsers even though we connected to mouseleave + this._set("hovering", false); + this._set("active", false); + break; + + case "mousedown": + case "touchpress": + this._set("active", true); + this._mouseDown = true; + // Set a global event to handle mouseup, so it fires properly + // even if the cursor leaves this.domNode before the mouse up event. + // Alternately could set active=false on mouseout. + var mouseUpConnector = this.connect(win.body(), touch.release, function(){ + this._mouseDown = false; + this._set("active", false); + this.disconnect(mouseUpConnector); + }); + break; + } + } + }, + + _setStateClass: function(){ + // summary: + // Update the visual state of the widget by setting the css classes on this.domNode + // (or this.stateNode if defined) by combining this.baseClass with + // various suffixes that represent the current widget state(s). + // + // description: + // In the case where a widget has multiple + // states, it sets the class based on all possible + // combinations. For example, an invalid form widget that is being hovered + // will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover". + // + // The widget may have one or more of the following states, determined + // by this.state, this.checked, this.valid, and this.selected: + // - Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid + // - Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet + // - Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true + // - Selected - ex: currently selected tab will have this.selected==true + // + // In addition, it may have one or more of the following states, + // based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused): + // - Disabled - if the widget is disabled + // - Active - if the mouse (or space/enter key?) is being pressed down + // - Focused - if the widget has focus + // - Hover - if the mouse is over the widget + + // Compute new set of classes + var newStateClasses = this.baseClass.split(" "); + + function multiply(modifier){ + newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier); + } + + if(!this.isLeftToRight()){ + // For RTL mode we need to set an addition class like dijitTextBoxRtl. + multiply("Rtl"); + } + + var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : ""); + if(this.checked){ + multiply(checkedState); + } + if(this.state){ + multiply(this.state); + } + if(this.selected){ + multiply("Selected"); + } + + if(this.disabled){ + multiply("Disabled"); + }else if(this.readOnly){ + multiply("ReadOnly"); + }else{ + if(this.active){ + multiply("Active"); + }else if(this.hovering){ + multiply("Hover"); + } + } + + if(this.focused){ + multiply("Focused"); + } + + // Remove old state classes and add new ones. + // For performance concerns we only write into domNode.className once. + var tn = this.stateNode || this.domNode, + classHash = {}; // set of all classes (state and otherwise) for node + + array.forEach(tn.className.split(" "), function(c){ classHash[c] = true; }); + + if("_stateClasses" in this){ + array.forEach(this._stateClasses, function(c){ delete classHash[c]; }); + } + + array.forEach(newStateClasses, function(c){ classHash[c] = true; }); + + var newClasses = []; + for(var c in classHash){ + newClasses.push(c); + } + tn.className = newClasses.join(" "); + + this._stateClasses = newStateClasses; + }, + + _trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){ + // summary: + // Track mouse/focus events on specified node and set CSS class on that node to indicate + // current state. Usually not called directly, but via cssStateNodes attribute. + // description: + // Given class=foo, will set the following CSS class on the node + // - fooActive: if the user is currently pressing down the mouse button while over the node + // - fooHover: if the user is hovering the mouse over the node, but not pressing down a button + // - fooFocus: if the node is focused + // + // Note that it won't set any classes if the widget is disabled. + // node: DomNode + // Should be a sub-node of the widget, not the top node (this.domNode), since the top node + // is handled specially and automatically just by mixing in this class. + // clazz: String + // CSS class name (ex: dijitSliderUpArrow). + + // Current state of node (initially false) + // NB: setting specifically to false because domClass.toggle() needs true boolean as third arg + var hovering=false, active=false, focused=false; + + var self = this, + cn = lang.hitch(this, "connect", node); + + function setClass(){ + var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly); + domClass.toggle(node, clazz+"Hover", hovering && !active && !disabled); + domClass.toggle(node, clazz+"Active", active && !disabled); + domClass.toggle(node, clazz+"Focused", focused && !disabled); + } + + // Mouse + cn("onmouseenter", function(){ + hovering = true; + setClass(); + }); + cn("onmouseleave", function(){ + hovering = false; + active = false; + setClass(); + }); + cn(touch.press, function(){ + active = true; + setClass(); + }); + cn(touch.release, function(){ + active = false; + setClass(); + }); + + // Focus + cn("onfocus", function(){ + focused = true; + setClass(); + }); + cn("onblur", function(){ + focused = false; + setClass(); + }); + + // Just in case widget is enabled/disabled while it has focus/hover/active state. + // Maybe this is overkill. + this.watch("disabled", setClass); + this.watch("readOnly", setClass); + } +}); +}); + +}, +'url:dojox/grid/resources/_Grid.html':"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n", +'dojox/grid/_RowManager':function(){ +define("dojox/grid/_RowManager", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/dom-class" +], function(declare, lang, domClass){ + + var setStyleText = function(inNode, inStyleText){ + if(inNode.style.cssText == undefined){ + inNode.setAttribute("style", inStyleText); + }else{ + inNode.style.cssText = inStyleText; + } + }; + + return declare("dojox.grid._RowManager", null, { + // Stores information about grid rows. Owned by grid and used internally. + constructor: function(inGrid){ + this.grid = inGrid; + }, + linesToEms: 2, + overRow: -2, + // styles + prepareStylingRow: function(inRowIndex, inRowNode){ + return { + index: inRowIndex, + node: inRowNode, + odd: Boolean(inRowIndex&1), + selected: !!this.grid.selection.isSelected(inRowIndex), + over: this.isOver(inRowIndex), + customStyles: "", + customClasses: "dojoxGridRow" + }; + }, + styleRowNode: function(inRowIndex, inRowNode){ + var row = this.prepareStylingRow(inRowIndex, inRowNode); + this.grid.onStyleRow(row); + this.applyStyles(row); + }, + applyStyles: function(inRow){ + var i = inRow; + + i.node.className = i.customClasses; + var h = i.node.style.height; + setStyleText(i.node, i.customStyles + ';' + (i.node._style||'')); + i.node.style.height = h; + }, + updateStyles: function(inRowIndex){ + this.grid.updateRowStyles(inRowIndex); + }, + // states and events + setOverRow: function(inRowIndex){ + var last = this.overRow; + this.overRow = inRowIndex; + if((last!=this.overRow)&&(lang.isString(last) || last >= 0)){ + this.updateStyles(last); + } + this.updateStyles(this.overRow); + }, + isOver: function(inRowIndex){ + return (this.overRow == inRowIndex && !domClass.contains(this.grid.domNode, "dojoxGridColumnResizing")); + } + }); +}); +}, +'dojo/_base/url':function(){ +define(["./kernel"], function(dojo) { + // module: + // dojo/url + // summary: + // This module contains dojo._Url + + var + ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"), + ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"), + _Url = function(){ + var n = null, + _a = arguments, + uri = [_a[0]]; + // resolve uri components relative to each other + for(var i = 1; i<_a.length; i++){ + if(!_a[i]){ continue; } + + // Safari doesn't support this.constructor so we have to be explicit + // FIXME: Tracked (and fixed) in Webkit bug 3537. + // http://bugs.webkit.org/show_bug.cgi?id=3537 + var relobj = new _Url(_a[i]+""), + uriobj = new _Url(uri[0]+""); + + if( + relobj.path == "" && + !relobj.scheme && + !relobj.authority && + !relobj.query + ){ + if(relobj.fragment != n){ + uriobj.fragment = relobj.fragment; + } + relobj = uriobj; + }else if(!relobj.scheme){ + relobj.scheme = uriobj.scheme; + + if(!relobj.authority){ + relobj.authority = uriobj.authority; + + if(relobj.path.charAt(0) != "/"){ + var path = uriobj.path.substring(0, + uriobj.path.lastIndexOf("/") + 1) + relobj.path; + + var segs = path.split("/"); + for(var j = 0; j < segs.length; j++){ + if(segs[j] == "."){ + // flatten "./" references + if(j == segs.length - 1){ + segs[j] = ""; + }else{ + segs.splice(j, 1); + j--; + } + }else if(j > 0 && !(j == 1 && segs[0] == "") && + segs[j] == ".." && segs[j-1] != ".."){ + // flatten "../" references + if(j == (segs.length - 1)){ + segs.splice(j, 1); + segs[j - 1] = ""; + }else{ + segs.splice(j - 1, 2); + j -= 2; + } + } + } + relobj.path = segs.join("/"); + } + } + } + + uri = []; + if(relobj.scheme){ + uri.push(relobj.scheme, ":"); + } + if(relobj.authority){ + uri.push("//", relobj.authority); + } + uri.push(relobj.path); + if(relobj.query){ + uri.push("?", relobj.query); + } + if(relobj.fragment){ + uri.push("#", relobj.fragment); + } + } + + this.uri = uri.join(""); + + // break the uri into its main components + var r = this.uri.match(ore); + + this.scheme = r[2] || (r[1] ? "" : n); + this.authority = r[4] || (r[3] ? "" : n); + this.path = r[5]; // can never be undefined + this.query = r[7] || (r[6] ? "" : n); + this.fragment = r[9] || (r[8] ? "" : n); + + if(this.authority != n){ + // server based naming authority + r = this.authority.match(ire); + + this.user = r[3] || n; + this.password = r[4] || n; + this.host = r[6] || r[7]; // ipv6 || ipv4 + this.port = r[9] || n; + } + }; + _Url.prototype.toString = function(){ return this.uri; }; + + return dojo._Url = _Url; +}); + +}, +'dojo/string':function(){ +define(["./_base/kernel", "./_base/lang"], function(dojo, lang) { + // module: + // dojo/string + // summary: + // TODOC + +lang.getObject("string", true, dojo); + +/*===== +dojo.string = { + // summary: String utilities for Dojo +}; +=====*/ + +dojo.string.rep = function(/*String*/str, /*Integer*/num){ + // summary: + // Efficiently replicate a string `n` times. + // str: + // the string to replicate + // num: + // number of times to replicate the string + + if(num <= 0 || !str){ return ""; } + + var buf = []; + for(;;){ + if(num & 1){ + buf.push(str); + } + if(!(num >>= 1)){ break; } + str += str; + } + return buf.join(""); // String +}; + +dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){ + // summary: + // Pad a string to guarantee that it is at least `size` length by + // filling with the character `ch` at either the start or end of the + // string. Pads at the start, by default. + // text: + // the string to pad + // size: + // length to provide padding + // ch: + // character to pad, defaults to '0' + // end: + // adds padding at the end if true, otherwise pads at start + // example: + // | // Fill the string to length 10 with "+" characters on the right. Yields "Dojo++++++". + // | dojo.string.pad("Dojo", 10, "+", true); + + if(!ch){ + ch = '0'; + } + var out = String(text), + pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length)); + return end ? out + pad : pad + out; // String +}; + +dojo.string.substitute = function( /*String*/ template, + /*Object|Array*/map, + /*Function?*/ transform, + /*Object?*/ thisObject){ + // summary: + // Performs parameterized substitutions on a string. Throws an + // exception if any parameter is unmatched. + // template: + // a string with expressions in the form `${key}` to be replaced or + // `${key:format}` which specifies a format function. keys are case-sensitive. + // map: + // hash to search for substitutions + // transform: + // a function to process all parameters before substitution takes + // place, e.g. mylib.encodeXML + // thisObject: + // where to look for optional format function; default to the global + // namespace + // example: + // Substitutes two expressions in a string from an Array or Object + // | // returns "File 'foo.html' is not found in directory '/temp'." + // | // by providing substitution data in an Array + // | dojo.string.substitute( + // | "File '${0}' is not found in directory '${1}'.", + // | ["foo.html","/temp"] + // | ); + // | + // | // also returns "File 'foo.html' is not found in directory '/temp'." + // | // but provides substitution data in an Object structure. Dotted + // | // notation may be used to traverse the structure. + // | dojo.string.substitute( + // | "File '${name}' is not found in directory '${info.dir}'.", + // | { name: "foo.html", info: { dir: "/temp" } } + // | ); + // example: + // Use a transform function to modify the values: + // | // returns "file 'foo.html' is not found in directory '/temp'." + // | dojo.string.substitute( + // | "${0} is not found in ${1}.", + // | ["foo.html","/temp"], + // | function(str){ + // | // try to figure out the type + // | var prefix = (str.charAt(0) == "/") ? "directory": "file"; + // | return prefix + " '" + str + "'"; + // | } + // | ); + // example: + // Use a formatter + // | // returns "thinger -- howdy" + // | dojo.string.substitute( + // | "${0:postfix}", ["thinger"], null, { + // | postfix: function(value, key){ + // | return value + " -- howdy"; + // | } + // | } + // | ); + + thisObject = thisObject || dojo.global; + transform = transform ? + lang.hitch(thisObject, transform) : function(v){ return v; }; + + return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g, + function(match, key, format){ + var value = lang.getObject(key, false, map); + if(format){ + value = lang.getObject(format, false, thisObject).call(thisObject, value, key); + } + return transform(value, key).toString(); + }); // String +}; + +/*===== +dojo.string.trim = function(str){ + // summary: + // Trims whitespace from both sides of the string + // str: String + // String to be trimmed + // returns: String + // Returns the trimmed string + // description: + // This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript). + // The short yet performant version of this function is dojo.trim(), + // which is part of Dojo base. Uses String.prototype.trim instead, if available. + return ""; // String +} +=====*/ + +dojo.string.trim = String.prototype.trim ? + lang.trim : // aliasing to the native function + function(str){ + str = str.replace(/^\s+/, ''); + for(var i = str.length - 1; i >= 0; i--){ + if(/\S/.test(str.charAt(i))){ + str = str.substring(0, i + 1); + break; + } + } + return str; + }; + +return dojo.string; +}); + +}, +'dojo/dnd/Avatar':function(){ +define(["../main", "./common"], function(dojo) { + // module: + // dojo/dnd/Avatar + // summary: + // TODOC + + +dojo.declare("dojo.dnd.Avatar", null, { + // summary: + // Object that represents transferred DnD items visually + // manager: Object + // a DnD manager object + + constructor: function(manager){ + this.manager = manager; + this.construct(); + }, + + // methods + construct: function(){ + // summary: + // constructor function; + // it is separate so it can be (dynamically) overwritten in case of need + this.isA11y = dojo.hasClass(dojo.body(),"dijit_a11y"); + var a = dojo.create("table", { + "class": "dojoDndAvatar", + style: { + position: "absolute", + zIndex: "1999", + margin: "0px" + } + }), + source = this.manager.source, node, + b = dojo.create("tbody", null, a), + tr = dojo.create("tr", null, b), + td = dojo.create("td", null, tr), + icon = this.isA11y ? dojo.create("span", { + id : "a11yIcon", + innerHTML : this.manager.copy ? '+' : "<" + }, td) : null, + span = dojo.create("span", { + innerHTML: source.generateText ? this._generateText() : "" + }, td), + k = Math.min(5, this.manager.nodes.length), i = 0; + // we have to set the opacity on IE only after the node is live + dojo.attr(tr, { + "class": "dojoDndAvatarHeader", + style: {opacity: 0.9} + }); + for(; i < k; ++i){ + if(source.creator){ + // create an avatar representation of the node + node = source._normalizedCreator(source.getItem(this.manager.nodes[i].id).data, "avatar").node; + }else{ + // or just clone the node and hope it works + node = this.manager.nodes[i].cloneNode(true); + if(node.tagName.toLowerCase() == "tr"){ + // insert extra table nodes + var table = dojo.create("table"), + tbody = dojo.create("tbody", null, table); + tbody.appendChild(node); + node = table; + } + } + node.id = ""; + tr = dojo.create("tr", null, b); + td = dojo.create("td", null, tr); + td.appendChild(node); + dojo.attr(tr, { + "class": "dojoDndAvatarItem", + style: {opacity: (9 - i) / 10} + }); + } + this.node = a; + }, + destroy: function(){ + // summary: + // destructor for the avatar; called to remove all references so it can be garbage-collected + dojo.destroy(this.node); + this.node = false; + }, + update: function(){ + // summary: + // updates the avatar to reflect the current DnD state + dojo[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop"); + if (this.isA11y){ + var icon = dojo.byId("a11yIcon"); + var text = '+'; // assume canDrop && copy + if (this.manager.canDropFlag && !this.manager.copy) { + text = '< '; // canDrop && move + }else if (!this.manager.canDropFlag && !this.manager.copy) { + text = "o"; //!canDrop && move + }else if(!this.manager.canDropFlag){ + text = 'x'; // !canDrop && copy + } + icon.innerHTML=text; + } + // replace text + dojo.query(("tr.dojoDndAvatarHeader td span" +(this.isA11y ? " span" : "")), this.node).forEach( + function(node){ + node.innerHTML = this._generateText(); + }, this); + }, + _generateText: function(){ + // summary: generates a proper text to reflect copying or moving of items + return this.manager.nodes.length.toString(); + } +}); + +return dojo.dnd.Avatar; +}); + +}, +'dojox/grid/_Scroller':function(){ +define("dojox/grid/_Scroller", [ + "dijit/registry", + "dojo/_base/declare", + "dojo/_base/lang", + "./util", + "dojo/_base/html" +], function(dijitRegistry, declare, lang, util, html){ + + var indexInParent = function(inNode){ + var i=0, n, p=inNode.parentNode; + while((n = p.childNodes[i++])){ + if(n == inNode){ + return i - 1; + } + } + return -1; + }; + + var cleanNode = function(inNode){ + if(!inNode){ + return; + } + dojo.forEach(dijitRegistry.toArray(), function(w){ + if(w.domNode && html.isDescendant(w.domNode, inNode, true)){ + w.destroy(); + } + }); + }; + + var getTagName = function(inNodeOrId){ + var node = html.byId(inNodeOrId); + return (node && node.tagName ? node.tagName.toLowerCase() : ''); + }; + + var nodeKids = function(inNode, inTag){ + var result = []; + var i=0, n; + while((n = inNode.childNodes[i])){ + i++; + if(getTagName(n) == inTag){ + result.push(n); + } + } + return result; + }; + + var divkids = function(inNode){ + return nodeKids(inNode, 'div'); + }; + + return declare("dojox.grid._Scroller", null, { + constructor: function(inContentNodes){ + this.setContentNodes(inContentNodes); + this.pageHeights = []; + this.pageNodes = []; + this.stack = []; + }, + // specified + rowCount: 0, // total number of rows to manage + defaultRowHeight: 32, // default height of a row + keepRows: 100, // maximum number of rows that should exist at one time + contentNode: null, // node to contain pages + scrollboxNode: null, // node that controls scrolling + // calculated + defaultPageHeight: 0, // default height of a page + keepPages: 10, // maximum number of pages that should exists at one time + pageCount: 0, + windowHeight: 0, + firstVisibleRow: 0, + lastVisibleRow: 0, + averageRowHeight: 0, // the average height of a row + // private + page: 0, + pageTop: 0, + // init + init: function(inRowCount, inKeepRows, inRowsPerPage){ + switch(arguments.length){ + case 3: this.rowsPerPage = inRowsPerPage; + case 2: this.keepRows = inKeepRows; + case 1: this.rowCount = inRowCount; + default: break; + } + this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage; + this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage); + this.setKeepInfo(this.keepRows); + this.invalidate(); + if(this.scrollboxNode){ + this.scrollboxNode.scrollTop = 0; + this.scroll(0); + this.scrollboxNode.onscroll = lang.hitch(this, 'onscroll'); + } + }, + _getPageCount: function(rowCount, rowsPerPage){ + return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0; + }, + destroy: function(){ + this.invalidateNodes(); + delete this.contentNodes; + delete this.contentNode; + delete this.scrollboxNode; + }, + setKeepInfo: function(inKeepRows){ + this.keepRows = inKeepRows; + this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2); + }, + // nodes + setContentNodes: function(inNodes){ + this.contentNodes = inNodes; + this.colCount = (this.contentNodes ? this.contentNodes.length : 0); + this.pageNodes = []; + for(var i=0; i<this.colCount; i++){ + this.pageNodes[i] = []; + } + }, + getDefaultNodes: function(){ + return this.pageNodes[0] || []; + }, + // updating + invalidate: function(){ + this._invalidating = true; + this.invalidateNodes(); + this.pageHeights = []; + this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0); + this.resize(); + this._invalidating = false; + }, + updateRowCount: function(inRowCount){ + this.invalidateNodes(); + this.rowCount = inRowCount; + // update page count, adjust document height + var oldPageCount = this.pageCount; + if(oldPageCount === 0){ + //We want to have at least 1px in height to keep scroller. Otherwise with an + //empty grid you can't scroll to see the header. + this.height = 1; + } + this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage); + if(this.pageCount < oldPageCount){ + for(var i=oldPageCount-1; i>=this.pageCount; i--){ + this.height -= this.getPageHeight(i); + delete this.pageHeights[i]; + } + }else if(this.pageCount > oldPageCount){ + this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight(); + } + this.resize(); + }, + // implementation for page manager + pageExists: function(inPageIndex){ + return Boolean(this.getDefaultPageNode(inPageIndex)); + }, + measurePage: function(inPageIndex){ + if(this.grid.rowHeight){ + var height = this.grid.rowHeight + 1; + return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ? + this.rowCount - inPageIndex * this.rowsPerPage : + this.rowsPerPage) * height; + + } + var n = this.getDefaultPageNode(inPageIndex); + return (n && n.innerHTML) ? n.offsetHeight : undefined; + }, + positionPage: function(inPageIndex, inPos){ + for(var i=0; i<this.colCount; i++){ + this.pageNodes[i][inPageIndex].style.top = inPos + 'px'; + } + }, + repositionPages: function(inPageIndex){ + var nodes = this.getDefaultNodes(); + var last = 0; + + for(var i=0; i<this.stack.length; i++){ + last = Math.max(this.stack[i], last); + } + // + var n = nodes[inPageIndex]; + var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0); + for(var p=inPageIndex+1; p<=last; p++){ + n = nodes[p]; + if(n){ + if(this.getPageNodePosition(n) == y){ + return; + } + this.positionPage(p, y); + } + y += this.getPageHeight(p); + } + }, + installPage: function(inPageIndex){ + for(var i=0; i<this.colCount; i++){ + this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]); + } + }, + preparePage: function(inPageIndex, inReuseNode){ + var p = (inReuseNode ? this.popPage() : null); + for(var i=0; i<this.colCount; i++){ + var nodes = this.pageNodes[i]; + var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes)); + new_p.pageIndex = inPageIndex; + nodes[inPageIndex] = new_p; + } + }, + // rendering implementation + renderPage: function(inPageIndex){ + var nodes = []; + var i, j; + for(i=0; i<this.colCount; i++){ + nodes[i] = this.pageNodes[i][inPageIndex]; + } + for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){ + this.renderRow(j, nodes); + } + }, + removePage: function(inPageIndex){ + for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){ + this.removeRow(j); + } + }, + destroyPage: function(inPageIndex){ + for(var i=0; i<this.colCount; i++){ + var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]); + if(n){ + html.destroy(n); + } + } + }, + pacify: function(inShouldPacify){ + }, + // pacification + pacifying: false, + pacifyTicks: 200, + setPacifying: function(inPacifying){ + if(this.pacifying != inPacifying){ + this.pacifying = inPacifying; + this.pacify(this.pacifying); + } + }, + startPacify: function(){ + this.startPacifyTicks = new Date().getTime(); + }, + doPacify: function(){ + var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks; + this.setPacifying(true); + this.startPacify(); + return result; + }, + endPacify: function(){ + this.setPacifying(false); + }, + // default sizing implementation + resize: function(){ + if(this.scrollboxNode){ + this.windowHeight = this.scrollboxNode.clientHeight; + } + for(var i=0; i<this.colCount; i++){ + //We want to have 1px in height min to keep scroller. Otherwise can't scroll + //and see header in empty grid. + util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height)); + } + + // Calculate the average row height and update the defaults (row and page). + var needPage = (!this._invalidating); + if(!needPage){ + var ah = this.grid.get("autoHeight"); + if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){ + needPage = true; + } + } + if(needPage){ + this.needPage(this.page, this.pageTop); + } + var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage); + var pageHeight = this.getPageHeight(this.page); + this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0; + }, + calcLastPageHeight: function(){ + if(!this.pageCount){ + return 0; + } + var lastPage = this.pageCount - 1; + var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight; + this.pageHeights[lastPage] = lastPageHeight; + return lastPageHeight; + }, + updateContentHeight: function(inDh){ + this.height += inDh; + this.resize(); + }, + updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){ + if(this.pageExists(inPageIndex)){ + var oh = this.getPageHeight(inPageIndex); + var h = (this.measurePage(inPageIndex)); + if(h === undefined){ + h = oh; + } + this.pageHeights[inPageIndex] = h; + if(oh != h){ + this.updateContentHeight(h - oh); + var ah = this.grid.get("autoHeight"); + if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){ + if(!fromAsynRendering){ + this.grid.sizeChange(); + }else{//fix #11101 by using fromAsynRendering to avoid deadlock + var ns = this.grid.viewsNode.style; + ns.height = parseInt(ns.height) + h - oh + 'px'; + this.repositionPages(inPageIndex); + } + }else{ + this.repositionPages(inPageIndex); + } + } + return h; + } + return 0; + }, + rowHeightChanged: function(inRowIndex, fromAsynRendering){ + this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering); + }, + // scroller core + invalidateNodes: function(){ + while(this.stack.length){ + this.destroyPage(this.popPage()); + } + }, + createPageNode: function(){ + var p = document.createElement('div'); + html.attr(p,"role","presentation"); + p.style.position = 'absolute'; + //p.style.width = '100%'; + p.style[this.grid.isLeftToRight() ? "left" : "right"] = '0'; + return p; + }, + getPageHeight: function(inPageIndex){ + var ph = this.pageHeights[inPageIndex]; + return (ph !== undefined ? ph : this.defaultPageHeight); + }, + // FIXME: this is not a stack, it's a FIFO list + pushPage: function(inPageIndex){ + return this.stack.push(inPageIndex); + }, + popPage: function(){ + return this.stack.shift(); + }, + findPage: function(inTop){ + var i = 0, h = 0; + for(var ph = 0; i<this.pageCount; i++, h += ph){ + ph = this.getPageHeight(i); + if(h + ph >= inTop){ + break; + } + } + this.page = i; + this.pageTop = h; + }, + buildPage: function(inPageIndex, inReuseNode, inPos){ + this.preparePage(inPageIndex, inReuseNode); + this.positionPage(inPageIndex, inPos); + // order of operations is key below + this.installPage(inPageIndex); + this.renderPage(inPageIndex); + // order of operations is key above + this.pushPage(inPageIndex); + }, + needPage: function(inPageIndex, inPos){ + var h = this.getPageHeight(inPageIndex), oh = h; + if(!this.pageExists(inPageIndex)){ + this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos); + h = this.updatePageHeight(inPageIndex, true); + }else{ + this.positionPage(inPageIndex, inPos); + } + return h; + }, + onscroll: function(){ + this.scroll(this.scrollboxNode.scrollTop); + }, + scroll: function(inTop){ + this.grid.scrollTop = inTop; + if(this.colCount){ + this.startPacify(); + this.findPage(inTop); + var h = this.height; + var b = this.getScrollBottom(inTop); + for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){ + y += this.needPage(p, y); + } + this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop); + this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b); + // indicates some page size has been updated + if(h != this.height){ + this.repositionPages(p-1); + } + this.endPacify(); + } + }, + getScrollBottom: function(inTop){ + return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1); + }, + // events + processNodeEvent: function(e, inNode){ + var t = e.target; + while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){ + t = t.parentNode; + } + if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){ + return false; + } + var page = t.parentNode; + e.topRowIndex = page.pageIndex * this.rowsPerPage; + e.rowIndex = e.topRowIndex + indexInParent(t); + e.rowTarget = t; + return true; + }, + processEvent: function(e){ + return this.processNodeEvent(e, this.contentNode); + }, + // virtual rendering interface + renderRow: function(inRowIndex, inPageNode){ + }, + removeRow: function(inRowIndex){ + }, + // page node operations + getDefaultPageNode: function(inPageIndex){ + return this.getDefaultNodes()[inPageIndex]; + }, + positionPageNode: function(inNode, inPos){ + }, + getPageNodePosition: function(inNode){ + return inNode.offsetTop; + }, + invalidatePageNode: function(inPageIndex, inNodes){ + var p = inNodes[inPageIndex]; + if(p){ + delete inNodes[inPageIndex]; + this.removePage(inPageIndex, p); + cleanNode(p); + p.innerHTML = ''; + } + return p; + }, + // scroll control + getPageRow: function(inPage){ + return inPage * this.rowsPerPage; + }, + getLastPageRow: function(inPage){ + return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1; + }, + getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){ + if(!this.pageExists(inPage)){ + return 0; + } + var row = this.getPageRow(inPage); + var nodes = this.getDefaultNodes(); + var rows = divkids(nodes[inPage]); + for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){ + inPageTop += rows[i].offsetHeight; + } + return (row ? row - 1 : row); + }, + getLastVisibleRow: function(inPage, inBottom, inScrollBottom){ + if(!this.pageExists(inPage)){ + return 0; + } + var nodes = this.getDefaultNodes(); + var row = this.getLastPageRow(inPage); + var rows = divkids(nodes[inPage]); + for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){ + inBottom -= rows[i].offsetHeight; + } + return row + 1; + }, + findTopRow: function(inScrollTop){ + var nodes = this.getDefaultNodes(); + var rows = divkids(nodes[this.page]); + for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){ + h = rows[i].offsetHeight; + t += h; + if(t >= inScrollTop){ + this.offset = h - (t - inScrollTop); + return i + this.page * this.rowsPerPage; + } + } + return -1; + }, + findScrollTop: function(inRow){ + var rowPage = Math.floor(inRow / this.rowsPerPage); + var t = 0; + var i, l; + for(i=0; i<rowPage; i++){ + t += this.getPageHeight(i); + } + this.pageTop = t; + this.page = rowPage;//fix #10543 + this.needPage(rowPage, this.pageTop); + + var nodes = this.getDefaultNodes(); + var rows = divkids(nodes[rowPage]); + var r = inRow - this.rowsPerPage * rowPage; + for(i=0,l=rows.length; i<l && i<r; i++){ + t += rows[i].offsetHeight; + } + return t; + }, + dummy: 0 + }); +}); + +}, +'dojox/grid/_Events':function(){ +define("dojox/grid/_Events", [ + "dojo/keys", + "dojo/dom-class", + "dojo/_base/declare", + "dojo/_base/event", + "dojo/_base/sniff" +], function(keys, domClass, declare, event, has){ + +return declare("dojox.grid._Events", null, { + // summary: + // _Grid mixin that provides default implementations for grid events. + // description: + // Default synthetic events dispatched for _Grid. dojo.connect to events to + // retain default implementation or override them for custom handling. + + // cellOverClass: String + // css class to apply to grid cells over which the cursor is placed. + cellOverClass: "dojoxGridCellOver", + + onKeyEvent: function(e){ + // summary: top level handler for Key Events + this.dispatchKeyEvent(e); + }, + + onContentEvent: function(e){ + // summary: Top level handler for Content events + this.dispatchContentEvent(e); + }, + + onHeaderEvent: function(e){ + // summary: Top level handler for header events + this.dispatchHeaderEvent(e); + }, + + onStyleRow: function(inRow){ + // summary: + // Perform row styling on a given row. Called whenever row styling is updated. + // + // inRow: Object + // Object containing row state information: selected, true if the row is selcted; over: + // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and + // customStyles to control row css classes and styles; both properties are strings. + // + // example: onStyleRow({ selected: true, over:true, odd:false }) + var i = inRow; + i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":""); + this.focus.styleRow(inRow); + this.edit.styleRow(inRow); + }, + + onKeyDown: function(e){ + // summary: + // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit, + // tab, shift-tab, and arrow keys move grid cell focus. + if(e.altKey || e.metaKey){ + return; + } + var colIdx; + switch(e.keyCode){ + case keys.ESCAPE: + this.edit.cancel(); + break; + case keys.ENTER: + if(!this.edit.isEditing()){ + colIdx = this.focus.getHeaderIndex(); + if(colIdx >= 0) { + this.setSortIndex(colIdx); + break; + }else { + this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey); + } + event.stop(e); + } + if(!e.shiftKey){ + var isEditing = this.edit.isEditing(); + this.edit.apply(); + if(!isEditing){ + this.edit.setEditCell(this.focus.cell, this.focus.rowIndex); + } + } + if (!this.edit.isEditing()){ + var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view + curView.content.decorateEvent(e); + this.onRowClick(e); + event.stop(e); + } + break; + case keys.SPACE: + if(!this.edit.isEditing()){ + colIdx = this.focus.getHeaderIndex(); + if(colIdx >= 0) { + this.setSortIndex(colIdx); + break; + }else { + this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey); + } + event.stop(e); + } + break; + case keys.TAB: + this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e); + break; + case keys.LEFT_ARROW: + case keys.RIGHT_ARROW: + if(!this.edit.isEditing()){ + var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys + event.stop(e); + colIdx = this.focus.getHeaderIndex(); + if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){ + this.focus.colSizeAdjust(e, colIdx, (keyCode == keys.LEFT_ARROW ? -1 : 1)*5); + } + else{ + var offset = (keyCode == keys.LEFT_ARROW) ? 1 : -1; + if(this.isLeftToRight()){ offset *= -1; } + this.focus.move(0, offset); + } + } + break; + case keys.UP_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex !== 0){ + event.stop(e); + this.focus.move(-1, 0); + } + break; + case keys.DOWN_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){ + event.stop(e); + this.focus.move(1, 0); + } + break; + case keys.PAGE_UP: + if(!this.edit.isEditing() && this.focus.rowIndex !== 0){ + event.stop(e); + if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){ + this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0); + }else{ + this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1)); + this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0); + } + } + break; + case keys.PAGE_DOWN: + if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){ + event.stop(e); + if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){ + this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0); + }else{ + this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1)); + this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0); + } + } + break; + default: + break; + } + }, + + onMouseOver: function(e){ + // summary: + // Event fired when mouse is over the grid. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e); + }, + + onMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of the grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e); + }, + + onMouseDown: function(e){ + // summary: + // Event fired when mouse is down inside grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e); + }, + + onMouseOverRow: function(e){ + // summary: + // Event fired when mouse is over any row (data or header). + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(!this.rows.isOver(e.rowIndex)){ + this.rows.setOverRow(e.rowIndex); + e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e); + } + }, + onMouseOutRow: function(e){ + // summary: + // Event fired when mouse moves out of any row (data or header). + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(this.rows.isOver(-1)){ + this.onHeaderMouseOut(e); + }else if(!this.rows.isOver(-2)){ + this.rows.setOverRow(-2); + this.onRowMouseOut(e); + } + }, + + onMouseDownRow: function(e){ + // summary: + // Event fired when mouse is down inside grid row + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + if(e.rowIndex != -1) + this.onRowMouseDown(e); + }, + + // cell events + onCellMouseOver: function(e){ + // summary: + // Event fired when mouse is over a cell. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.add(e.cellNode, this.cellOverClass); + } + }, + + onCellMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.remove(e.cellNode, this.cellOverClass); + } + }, + + onCellMouseDown: function(e){ + // summary: + // Event fired when mouse is down in a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onCellClick: function(e){ + // summary: + // Event fired when a cell is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this._click[0] = this._click[1]; + this._click[1] = e; + if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){ + this.focus.setFocusCell(e.cell, e.rowIndex); + } + // in some cases click[0] is null which causes false doubeClicks. Fixes #100703 + if(this._click.length > 1 && this._click[0] == null){ + this._click.shift(); + } + this.onRowClick(e); + }, + + onCellDblClick: function(e){ + // summary: + // Event fired when a cell is double-clicked. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + var event; + if(this._click.length > 1 && has("ie")){ + event = this._click[1]; + }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){ + event = this._click[0]; + }else{ + event = e; + } + this.focus.setFocusCell(event.cell, event.rowIndex); + this.onRowClick(event); + this.edit.setEditCell(event.cell, event.rowIndex); + this.onRowDblClick(e); + }, + + onCellContextMenu: function(e){ + // summary: + // Event fired when a cell context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onRowContextMenu(e); + }, + + onCellFocus: function(inCell, inRowIndex){ + // summary: + // Event fired when a cell receives focus. + // inCell: Object + // Cell object containing properties of the grid column. + // inRowIndex: Integer + // Index of the grid row + this.edit.cellFocus(inCell, inRowIndex); + }, + + // row events + onRowClick: function(e){ + // summary: + // Event fired when a row is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.edit.rowClick(e); + this.selection.clickSelectEvent(e); + }, + + onRowDblClick: function(e){ + // summary: + // Event fired when a row is double clicked. + // e: Event + // decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a data row. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a data row. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + }, + + onRowMouseDown: function(e){ + // summary: + // Event fired when mouse is down in a row. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowContextMenu: function(e){ + // summary: + // Event fired when a row context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + event.stop(e); + }, + + // header events + onHeaderMouseOver: function(e){ + // summary: + // Event fired when mouse moves over the grid header. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + }, + + onHeaderMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of the grid header. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.add(e.cellNode, this.cellOverClass); + } + }, + + onHeaderCellMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.remove(e.cellNode, this.cellOverClass); + } + }, + + onHeaderCellMouseDown: function(e) { + // summary: + // Event fired when mouse is down in a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderClick: function(e){ + // summary: + // Event fired when the grid header is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellClick: function(e){ + // summary: + // Event fired when a header cell is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.setSortIndex(e.cell.index); + this.onHeaderClick(e); + }, + + onHeaderDblClick: function(e){ + // summary: + // Event fired when the grid header is double clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellDblClick: function(e){ + // summary: + // Event fired when a header cell is double clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onHeaderDblClick(e); + }, + + onHeaderCellContextMenu: function(e){ + // summary: + // Event fired when a header cell context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onHeaderContextMenu(e); + }, + + onHeaderContextMenu: function(e){ + // summary: + // Event fired when the grid header context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(!this.headerMenu){ + event.stop(e); + } + }, + + // editing + onStartEdit: function(inCell, inRowIndex){ + // summary: + // Event fired when editing is started for a given grid cell + // inCell: Object + // Cell object containing properties of the grid column. + // inRowIndex: Integer + // Index of the grid row + }, + + onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){ + // summary: + // Event fired when editing is applied for a given grid cell + // inValue: String + // Value from cell editor + // inRowIndex: Integer + // Index of the grid row + // inFieldIndex: Integer + // Index in the grid's data store + }, + + onCancelEdit: function(inRowIndex){ + // summary: + // Event fired when editing is cancelled for a given grid cell + // inRowIndex: Integer + // Index of the grid row + }, + + onApplyEdit: function(inRowIndex){ + // summary: + // Event fired when editing is applied for a given grid row + // inRowIndex: Integer + // Index of the grid row + }, + + onCanSelect: function(inRowIndex){ + // summary: + // Event to determine if a grid row may be selected + // inRowIndex: Integer + // Index of the grid row + // returns: Boolean + // true if the row can be selected + return true; + }, + + onCanDeselect: function(inRowIndex){ + // summary: + // Event to determine if a grid row may be deselected + // inRowIndex: Integer + // Index of the grid row + // returns: Boolean + // true if the row can be deselected + return true; + }, + + onSelected: function(inRowIndex){ + // summary: + // Event fired when a grid row is selected + // inRowIndex: Integer + // Index of the grid row + this.updateRowStyles(inRowIndex); + }, + + onDeselected: function(inRowIndex){ + // summary: + // Event fired when a grid row is deselected + // inRowIndex: Integer + // Index of the grid row + this.updateRowStyles(inRowIndex); + }, + + onSelectionChanged: function(){ + } +}); +}); +}, +'dojo/dnd/autoscroll':function(){ +define(["../main", "../window"], function(dojo) { + // module: + // dojo/dnd/autoscroll + // summary: + // TODOC + +dojo.getObject("dnd", true, dojo); + +dojo.dnd.getViewport = dojo.window.getBox; + +dojo.dnd.V_TRIGGER_AUTOSCROLL = 32; +dojo.dnd.H_TRIGGER_AUTOSCROLL = 32; + +dojo.dnd.V_AUTOSCROLL_VALUE = 16; +dojo.dnd.H_AUTOSCROLL_VALUE = 16; + +dojo.dnd.autoScroll = function(e){ + // summary: + // a handler for onmousemove event, which scrolls the window, if + // necesary + // e: Event + // onmousemove event + + // FIXME: needs more docs! + var v = dojo.window.getBox(), dx = 0, dy = 0; + if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){ + dx = -dojo.dnd.H_AUTOSCROLL_VALUE; + }else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){ + dx = dojo.dnd.H_AUTOSCROLL_VALUE; + } + if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){ + dy = -dojo.dnd.V_AUTOSCROLL_VALUE; + }else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){ + dy = dojo.dnd.V_AUTOSCROLL_VALUE; + } + window.scrollBy(dx, dy); +}; + +dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1}; +dojo.dnd._validOverflow = {"auto": 1, "scroll": 1}; + +dojo.dnd.autoScrollNodes = function(e){ + // summary: + // a handler for onmousemove event, which scrolls the first avaialble + // Dom element, it falls back to dojo.dnd.autoScroll() + // e: Event + // onmousemove event + + // FIXME: needs more docs! + + var b, t, w, h, rx, ry, dx = 0, dy = 0, oldLeft, oldTop; + + for(var n = e.target; n;){ + if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){ + var s = dojo.getComputedStyle(n), + overflow = (s.overflow.toLowerCase() in dojo.dnd._validOverflow), + overflowX = (s.overflowX.toLowerCase() in dojo.dnd._validOverflow), + overflowY = (s.overflowY.toLowerCase() in dojo.dnd._validOverflow); + if(overflow || overflowX || overflowY){ + b = dojo._getContentBox(n, s); + t = dojo.position(n, true); + } + // overflow-x + if(overflow || overflowX){ + w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2); + rx = e.pageX - t.x; + if(dojo.isWebKit || dojo.isOpera){ + // FIXME: this code should not be here, it should be taken into account + // either by the event fixing code, or the dojo.position() + // FIXME: this code doesn't work on Opera 9.5 Beta + rx += dojo.body().scrollLeft; + } + dx = 0; + if(rx > 0 && rx < b.w){ + if(rx < w){ + dx = -w; + }else if(rx > b.w - w){ + dx = w; + } + oldLeft = n.scrollLeft; + n.scrollLeft = n.scrollLeft + dx; + } + } + // overflow-y + if(overflow || overflowY){ + //console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop); + h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2); + ry = e.pageY - t.y; + if(dojo.isWebKit || dojo.isOpera){ + // FIXME: this code should not be here, it should be taken into account + // either by the event fixing code, or the dojo.position() + // FIXME: this code doesn't work on Opera 9.5 Beta + ry += dojo.body().scrollTop; + } + dy = 0; + if(ry > 0 && ry < b.h){ + if(ry < h){ + dy = -h; + }else if(ry > b.h - h){ + dy = h; + } + oldTop = n.scrollTop; + n.scrollTop = n.scrollTop + dy; + } + } + if(dx || dy){ return; } + } + try{ + n = n.parentNode; + }catch(x){ + n = null; + } + } + dojo.dnd.autoScroll(e); +}; + + return dojo.dnd; +}); + +}, +'dijit/registry':function(){ +define("dijit/registry", [ + "dojo/_base/array", // array.forEach array.map + "dojo/_base/sniff", // has("ie") + "dojo/_base/unload", // unload.addOnWindowUnload + "dojo/_base/window", // win.body + "." // dijit._scopeName +], function(array, has, unload, win, dijit){ + + // module: + // dijit/registry + // summary: + // Registry of existing widget on page, plus some utility methods. + // Must be accessed through AMD api, ex: + // require(["dijit/registry"], function(registry){ registry.byId("foo"); }) + + var _widgetTypeCtr = {}, hash = {}; + + var registry = { + // summary: + // A set of widgets indexed by id + + length: 0, + + add: function(/*dijit._Widget*/ widget){ + // summary: + // Add a widget to the registry. If a duplicate ID is detected, a error is thrown. + // + // widget: dijit._Widget + // Any dijit._Widget subclass. + if(hash[widget.id]){ + throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered"); + } + hash[widget.id] = widget; + this.length++; + }, + + remove: function(/*String*/ id){ + // summary: + // Remove a widget from the registry. Does not destroy the widget; simply + // removes the reference. + if(hash[id]){ + delete hash[id]; + this.length--; + } + }, + + byId: function(/*String|Widget*/ id){ + // summary: + // Find a widget by it's id. + // If passed a widget then just returns the widget. + return typeof id == "string" ? hash[id] : id; // dijit._Widget + }, + + byNode: function(/*DOMNode*/ node){ + // summary: + // Returns the widget corresponding to the given DOMNode + return hash[node.getAttribute("widgetId")]; // dijit._Widget + }, + + toArray: function(){ + // summary: + // Convert registry into a true Array + // + // example: + // Work with the widget .domNodes in a real Array + // | array.map(dijit.registry.toArray(), function(w){ return w.domNode; }); + + var ar = []; + for(var id in hash){ + ar.push(hash[id]); + } + return ar; // dijit._Widget[] + }, + + getUniqueId: function(/*String*/widgetType){ + // summary: + // Generates a unique id for a given widgetType + + var id; + do{ + id = widgetType + "_" + + (widgetType in _widgetTypeCtr ? + ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0); + }while(hash[id]); + return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String + }, + + findWidgets: function(/*DomNode*/ root){ + // summary: + // Search subtree under root returning widgets found. + // Doesn't search for nested widgets (ie, widgets inside other widgets). + + var outAry = []; + + function getChildrenHelper(root){ + for(var node = root.firstChild; node; node = node.nextSibling){ + if(node.nodeType == 1){ + var widgetId = node.getAttribute("widgetId"); + if(widgetId){ + var widget = hash[widgetId]; + if(widget){ // may be null on page w/multiple dojo's loaded + outAry.push(widget); + } + }else{ + getChildrenHelper(node); + } + } + } + } + + getChildrenHelper(root); + return outAry; + }, + + _destroyAll: function(){ + // summary: + // Code to destroy all widgets and do other cleanup on page unload + + // Clean up focus manager lingering references to widgets and nodes + dijit._curFocus = null; + dijit._prevFocus = null; + dijit._activeStack = []; + + // Destroy all the widgets, top down + array.forEach(registry.findWidgets(win.body()), function(widget){ + // Avoid double destroy of widgets like Menu that are attached to <body> + // even though they are logically children of other widgets. + if(!widget._destroyed){ + if(widget.destroyRecursive){ + widget.destroyRecursive(); + }else if(widget.destroy){ + widget.destroy(); + } + } + }); + }, + + getEnclosingWidget: function(/*DOMNode*/ node){ + // summary: + // Returns the widget whose DOM tree contains the specified DOMNode, or null if + // the node is not contained within the DOM tree of any widget + while(node){ + var id = node.getAttribute && node.getAttribute("widgetId"); + if(id){ + return hash[id]; + } + node = node.parentNode; + } + return null; + }, + + // In case someone needs to access hash. + // Actually, this is accessed from WidgetSet back-compatibility code + _hash: hash + }; + + if(has("ie")){ + // Only run _destroyAll() for IE because we think it's only necessary in that case, + // and because it causes problems on FF. See bug #3531 for details. + unload.addOnWindowUnload(function(){ + registry._destroyAll(); + }); + } + + /*===== + dijit.registry = { + // summary: + // A list of widgets on a page. + }; + =====*/ + dijit.registry = registry; + + return registry; +}); + +}, +'dijit/_base/manager':function(){ +define("dijit/_base/manager", [ + "dojo/_base/array", + "dojo/_base/config", // defaultDuration + "../registry", + ".." // for setting exports to dijit namespace +], function(array, config, registry, dijit){ + + // module: + // dijit/_base/manager + // summary: + // Shim to methods on registry, plus a few other declarations. + // New code should access dijit/registry directly when possible. + + /*===== + dijit.byId = function(id){ + // summary: + // Returns a widget by it's id, or if passed a widget, no-op (like dom.byId()) + // id: String|dijit._Widget + return registry.byId(id); // dijit._Widget + }; + + dijit.getUniqueId = function(widgetType){ + // summary: + // Generates a unique id for a given widgetType + // widgetType: String + return registry.getUniqueId(widgetType); // String + }; + + dijit.findWidgets = function(root){ + // summary: + // Search subtree under root returning widgets found. + // Doesn't search for nested widgets (ie, widgets inside other widgets). + // root: DOMNode + return registry.findWidgets(root); + }; + + dijit._destroyAll = function(){ + // summary: + // Code to destroy all widgets and do other cleanup on page unload + + return registry._destroyAll(); + }; + + dijit.byNode = function(node){ + // summary: + // Returns the widget corresponding to the given DOMNode + // node: DOMNode + return registry.byNode(node); // dijit._Widget + }; + + dijit.getEnclosingWidget = function(node){ + // summary: + // Returns the widget whose DOM tree contains the specified DOMNode, or null if + // the node is not contained within the DOM tree of any widget + // node: DOMNode + return registry.getEnclosingWidget(node); + }; + =====*/ + array.forEach(["byId", "getUniqueId", "findWidgets", "_destroyAll", "byNode", "getEnclosingWidget"], function(name){ + dijit[name] = registry[name]; + }); + + /*===== + dojo.mixin(dijit, { + // defaultDuration: Integer + // The default fx.animation speed (in ms) to use for all Dijit + // transitional fx.animations, unless otherwise specified + // on a per-instance basis. Defaults to 200, overrided by + // `djConfig.defaultDuration` + defaultDuration: 200 + }); + =====*/ + dijit.defaultDuration = config["defaultDuration"] || 200; + + return dijit; +}); + +}, +'dojox/html/metrics':function(){ +define("dojox/html/metrics", ["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready", "dojo/_base/unload", + "dojo/_base/window", "dojo/dom-geometry"], + function(kernel,lang,has,ready,UnloadUtil,Window,DOMGeom){ + var dhm = lang.getObject("dojox.html.metrics",true); + var dojox = lang.getObject("dojox"); + + // derived from Morris John's emResized measurer + dhm.getFontMeasurements = function(){ + // summary + // Returns an object that has pixel equivilents of standard font size values. + var heights = { + '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0, + 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0 + }; + + if(has("ie")){ + // we do a font-size fix if and only if one isn't applied already. + // NOTE: If someone set the fontSize on the HTML Element, this will kill it. + Window.doc.documentElement.style.fontSize="100%"; + } + + // set up the measuring node. + var div=Window.doc.createElement("div"); + var ds = div.style; + ds.position="absolute"; + ds.left="-100px"; + ds.top="0"; + ds.width="30px"; + ds.height="1000em"; + ds.borderWidth="0"; + ds.margin="0"; + ds.padding="0"; + ds.outline="0"; + ds.lineHeight="1"; + ds.overflow="hidden"; + Window.body().appendChild(div); + + // do the measurements. + for(var p in heights){ + ds.fontSize = p; + heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000; + } + + Window.body().removeChild(div); + div = null; + return heights; // object + }; + + var fontMeasurements = null; + + dhm.getCachedFontMeasurements = function(recalculate){ + if(recalculate || !fontMeasurements){ + fontMeasurements = dhm.getFontMeasurements(); + } + return fontMeasurements; + }; + + var measuringNode = null, empty = {}; + dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){ + var m, s; + if(!measuringNode){ + m = measuringNode = Window.doc.createElement("div"); + // Container that we can set contraints on so that it doesn't + // trigger a scrollbar. + var c = Window.doc.createElement("div"); + c.appendChild(m); + s = c.style; + s.overflow='scroll'; + s.position = "absolute"; + s.left = "0px"; + s.top = "-10000px"; + s.width = "1px"; + s.height = "1px"; + s.visibility = "hidden"; + s.borderWidth = "0"; + s.margin = "0"; + s.padding = "0"; + s.outline = "0"; + Window.body().appendChild(c); + }else{ + m = measuringNode; + } + // reset styles + m.className = ""; + s = m.style; + s.borderWidth = "0"; + s.margin = "0"; + s.padding = "0"; + s.outline = "0"; + // set new style + if(arguments.length > 1 && style){ + for(var i in style){ + if(i in empty){ continue; } + s[i] = style[i]; + } + } + // set classes + if(arguments.length > 2 && className){ + m.className = className; + } + // take a measure + m.innerHTML = text; + var box = DOMGeom.position(m); + // position doesn't report right (reports 1, since parent is 1) + // So we have to look at the scrollWidth to get the real width + // Height is right. + box.w = m.parentNode.scrollWidth; + return box; + }; + + // determine the scrollbar sizes on load. + var scroll={ w:16, h:16 }; + dhm.getScrollbar=function(){ return { w:scroll.w, h:scroll.h }; }; + + dhm._fontResizeNode = null; + + dhm.initOnFontResize = function(interval){ + var f = dhm._fontResizeNode = Window.doc.createElement("iframe"); + var fs = f.style; + fs.position = "absolute"; + fs.width = "5em"; + fs.height = "10em"; + fs.top = "-10000px"; + if(has("ie")){ + f.onreadystatechange = function(){ + if(f.contentWindow.document.readyState == "complete"){ + f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize; + } + }; + }else{ + f.onload = function(){ + f.contentWindow.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize; + }; + } + //The script tag is to work around a known firebug race condition. See comments in bug #9046 + f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'"); + Window.body().appendChild(f); + dhm.initOnFontResize = function(){}; + }; + + dhm.onFontResize = function(){}; + dhm._fontresize = function(){ + dhm.onFontResize(); + } + + UnloadUtil.addOnUnload(function(){ + // destroy our font resize iframe if we have one + var f = dhm._fontResizeNode; + if(f){ + if(has("ie") && f.onresize){ + f.onresize = null; + }else if(f.contentWindow && f.contentWindow.onresize){ + f.contentWindow.onresize = null; + } + dhm._fontResizeNode = null; + } + }); + + ready(function(){ + // getScrollbar metrics node + try{ + var n=Window.doc.createElement("div"); + n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;"; + Window.body().appendChild(n); + scroll.w = n.offsetWidth - n.clientWidth; + scroll.h = n.offsetHeight - n.clientHeight; + Window.body().removeChild(n); + //console.log("Scroll bar dimensions: ", scroll); + delete n; + }catch(e){} + + // text size poll setup + if("fontSizeWatch" in kernel.config && !!kernel.config.fontSizeWatch){ + dhm.initOnFontResize(); + } + }); + return dhm; +}); +}, +'dojox/grid/_EditManager':function(){ +define("dojox/grid/_EditManager", [ + "dojo/_base/lang", + "dojo/_base/array", + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/sniff", + "./util" +], function(lang, array, declare, connect, has, util){ + +return declare("dojox.grid._EditManager", null, { + // summary: + // Controls grid cell editing process. Owned by grid and used internally for editing. + constructor: function(inGrid){ + // inGrid: dojox.Grid + // The dojox.Grid this editor should be attached to + this.grid = inGrid; + if(has("ie")){ + this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))]; + }else{ + this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')]; + } + }, + + info: {}, + + destroy: function(){ + array.forEach(this.connections, connect.disconnect); + }, + + cellFocus: function(inCell, inRowIndex){ + // summary: + // Invoke editing when cell is focused + // inCell: cell object + // Grid cell object + // inRowIndex: Integer + // Grid row index + if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){ + // if same row or quick editing, edit + this.setEditCell(inCell, inRowIndex); + }else{ + // otherwise, apply any pending row edits + this.apply(); + } + // if dynamic or static editing... + if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){ + // let the editor focus itself as needed + this._focusEditor(inCell, inRowIndex); + } + }, + + rowClick: function(e){ + if(this.isEditing() && !this.isEditRow(e.rowIndex)){ + this.apply(); + } + }, + + styleRow: function(inRow){ + if(inRow.index == this.info.rowIndex){ + inRow.customClasses += ' dojoxGridRowEditing'; + } + }, + + dispatchEvent: function(e){ + var c = e.cell, ed = (c && c["editable"]) ? c : 0; + return ed && ed.dispatchEvent(e.dispatch, e); + }, + + // Editing + isEditing: function(){ + // summary: + // Indicates editing state of the grid. + // returns: Boolean + // True if grid is actively editing + return this.info.rowIndex !== undefined; + }, + + isEditCell: function(inRowIndex, inCellIndex){ + // summary: + // Indicates if the given cell is being edited. + // inRowIndex: Integer + // Grid row index + // inCellIndex: Integer + // Grid cell index + // returns: Boolean + // True if given cell is being edited + return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex); + }, + + isEditRow: function(inRowIndex){ + // summary: + // Indicates if the given row is being edited. + // inRowIndex: Integer + // Grid row index + // returns: Boolean + // True if given row is being edited + return this.info.rowIndex === inRowIndex; + }, + + setEditCell: function(inCell, inRowIndex){ + // summary: + // Set the given cell to be edited + // inRowIndex: Integer + // Grid row index + // inCell: Object + // Grid cell object + if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){ + this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable); + } + }, + + _focusEditor: function(inCell, inRowIndex){ + util.fire(inCell, "focus", [inRowIndex]); + }, + + focusEditor: function(){ + if(this.isEditing()){ + this._focusEditor(this.info.cell, this.info.rowIndex); + } + }, + + // implement fix for focus boomerang effect on IE + _boomerangWindow: 500, + _shouldCatchBoomerang: function(){ + return this._catchBoomerang > new Date().getTime(); + }, + _boomerangFocus: function(){ + //console.log("_boomerangFocus"); + if(this._shouldCatchBoomerang()){ + // make sure we don't utterly lose focus + this.grid.focus.focusGrid(); + // let the editor focus itself as needed + this.focusEditor(); + // only catch once + this._catchBoomerang = 0; + } + }, + _doCatchBoomerang: function(){ + // give ourselves a few ms to boomerang IE focus effects + if(has("ie")){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;} + }, + // end boomerang fix API + + start: function(inCell, inRowIndex, inEditing){ + if(!this._isValidInput()){ + return; + } + this.grid.beginUpdate(); + this.editorApply(); + if(this.isEditing() && !this.isEditRow(inRowIndex)){ + this.applyRowEdit(); + this.grid.updateRow(inRowIndex); + } + if(inEditing){ + this.info = { cell: inCell, rowIndex: inRowIndex }; + this.grid.doStartEdit(inCell, inRowIndex); + this.grid.updateRow(inRowIndex); + }else{ + this.info = {}; + } + this.grid.endUpdate(); + // make sure we don't utterly lose focus + this.grid.focus.focusGrid(); + // let the editor focus itself as needed + this._focusEditor(inCell, inRowIndex); + // give ourselves a few ms to boomerang IE focus effects + this._doCatchBoomerang(); + }, + + _editorDo: function(inMethod){ + var c = this.info.cell; + //c && c.editor && c.editor[inMethod](c, this.info.rowIndex); + if(c && c.editable){ + c[inMethod](this.info.rowIndex); + } + }, + + editorApply: function(){ + this._editorDo("apply"); + }, + + editorCancel: function(){ + this._editorDo("cancel"); + }, + + applyCellEdit: function(inValue, inCell, inRowIndex){ + if(this.grid.canEdit(inCell, inRowIndex)){ + this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field); + } + }, + + applyRowEdit: function(){ + this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field); + }, + + apply: function(){ + // summary: + // Apply a grid edit + if(this.isEditing() && this._isValidInput()){ + this.grid.beginUpdate(); + this.editorApply(); + this.applyRowEdit(); + this.info = {}; + this.grid.endUpdate(); + this.grid.focus.focusGrid(); + this._doCatchBoomerang(); + } + }, + + cancel: function(){ + // summary: + // Cancel a grid edit + if(this.isEditing()){ + this.grid.beginUpdate(); + this.editorCancel(); + this.info = {}; + this.grid.endUpdate(); + this.grid.focus.focusGrid(); + this._doCatchBoomerang(); + } + }, + + save: function(inRowIndex, inView){ + // summary: + // Save the grid editing state + // inRowIndex: Integer + // Grid row index + // inView: Object + // Grid view + var c = this.info.cell; + if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){ + c.save(c, this.info.rowIndex); + } + }, + + restore: function(inView, inRowIndex){ + // summary: + // Restores the grid editing state + // inRowIndex: Integer + // Grid row index + // inView: Object + // Grid view + var c = this.info.cell; + if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){ + c.restore(this.info.rowIndex); + } + }, + + _isValidInput: function(){ + var w = (this.info.cell || {}).widget; + if(!w || !w.isValid){ + //no validation needed + return true; + } + w.focused = true; + return w.isValid(true); + } +}); +}); +}, +'dijit/a11y':function(){ +define("dijit/a11y", [ + "dojo/_base/array", // array.forEach array.map + "dojo/_base/config", // defaultDuration + "dojo/_base/declare", // declare + "dojo/dom", // dom.byId + "dojo/dom-attr", // domAttr.attr domAttr.has + "dojo/dom-style", // style.style + "dojo/_base/sniff", // has("ie") + "./_base/manager", // manager._isElementShown + "." // for exporting methods to dijit namespace +], function(array, config, declare, dom, domAttr, domStyle, has, manager, dijit){ + + // module: + // dijit/a11y + // summary: + // Accessibility utility functions (keyboard, tab stops, etc.) + + var shown = (dijit._isElementShown = function(/*Element*/ elem){ + var s = domStyle.get(elem); + return (s.visibility != "hidden") + && (s.visibility != "collapsed") + && (s.display != "none") + && (domAttr.get(elem, "type") != "hidden"); + }); + + dijit.hasDefaultTabStop = function(/*Element*/ elem){ + // summary: + // Tests if element is tab-navigable even without an explicit tabIndex setting + + // No explicit tabIndex setting, need to investigate node type + switch(elem.nodeName.toLowerCase()){ + case "a": + // An <a> w/out a tabindex is only navigable if it has an href + return domAttr.has(elem, "href"); + case "area": + case "button": + case "input": + case "object": + case "select": + case "textarea": + // These are navigable by default + return true; + case "iframe": + // If it's an editor <iframe> then it's tab navigable. + var body; + try{ + // non-IE + var contentDocument = elem.contentDocument; + if("designMode" in contentDocument && contentDocument.designMode == "on"){ + return true; + } + body = contentDocument.body; + }catch(e1){ + // contentWindow.document isn't accessible within IE7/8 + // if the iframe.src points to a foreign url and this + // page contains an element, that could get focus + try{ + body = elem.contentWindow.document.body; + }catch(e2){ + return false; + } + } + return body && (body.contentEditable == 'true' || + (body.firstChild && body.firstChild.contentEditable == 'true')); + default: + return elem.contentEditable == 'true'; + } + }; + + var isTabNavigable = (dijit.isTabNavigable = function(/*Element*/ elem){ + // summary: + // Tests if an element is tab-navigable + + // TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable() + if(domAttr.get(elem, "disabled")){ + return false; + }else if(domAttr.has(elem, "tabIndex")){ + // Explicit tab index setting + return domAttr.get(elem, "tabIndex") >= 0; // boolean + }else{ + // No explicit tabIndex setting, so depends on node type + return dijit.hasDefaultTabStop(elem); + } + }); + + dijit._getTabNavigable = function(/*DOMNode*/ root){ + // summary: + // Finds descendants of the specified root node. + // + // description: + // Finds the following descendants of the specified root node: + // * the first tab-navigable element in document order + // without a tabIndex or with tabIndex="0" + // * the last tab-navigable element in document order + // without a tabIndex or with tabIndex="0" + // * the first element in document order with the lowest + // positive tabIndex value + // * the last element in document order with the highest + // positive tabIndex value + var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {}; + + function radioName(node){ + // If this element is part of a radio button group, return the name for that group. + return node && node.tagName.toLowerCase() == "input" && + node.type && node.type.toLowerCase() == "radio" && + node.name && node.name.toLowerCase(); + } + + var walkTree = function(/*DOMNode*/parent){ + for(var child = parent.firstChild; child; child = child.nextSibling){ + // Skip text elements, hidden elements, and also non-HTML elements (those in custom namespaces) in IE, + // since show() invokes getAttribute("type"), which crash on VML nodes in IE. + if(child.nodeType != 1 || (has("ie") && child.scopeName !== "HTML") || !shown(child)){ + continue; + } + + if(isTabNavigable(child)){ + var tabindex = domAttr.get(child, "tabIndex"); + if(!domAttr.has(child, "tabIndex") || tabindex == 0){ + if(!first){ + first = child; + } + last = child; + }else if(tabindex > 0){ + if(!lowest || tabindex < lowestTabindex){ + lowestTabindex = tabindex; + lowest = child; + } + if(!highest || tabindex >= highestTabindex){ + highestTabindex = tabindex; + highest = child; + } + } + var rn = radioName(child); + if(domAttr.get(child, "checked") && rn){ + radioSelected[rn] = child; + } + } + if(child.nodeName.toUpperCase() != 'SELECT'){ + walkTree(child); + } + } + }; + if(shown(root)){ + walkTree(root); + } + function rs(node){ + // substitute checked radio button for unchecked one, if there is a checked one with the same name. + return radioSelected[radioName(node)] || node; + } + + return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) }; + }; + dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/ root){ + // summary: + // Finds the descendant of the specified root node + // that is first in the tabbing order + var elems = dijit._getTabNavigable(dom.byId(root)); + return elems.lowest ? elems.lowest : elems.first; // DomNode + }; + + dijit.getLastInTabbingOrder = function(/*String|DOMNode*/ root){ + // summary: + // Finds the descendant of the specified root node + // that is last in the tabbing order + var elems = dijit._getTabNavigable(dom.byId(root)); + return elems.last ? elems.last : elems.highest; // DomNode + }; + + return { + hasDefaultTabStop: dijit.hasDefaultTabStop, + isTabNavigable: dijit.isTabNavigable, + _getTabNavigable: dijit._getTabNavigable, + getFirstInTabbingOrder: dijit.getFirstInTabbingOrder, + getLastInTabbingOrder: dijit.getLastInTabbingOrder + }; +}); + +}, +'dijit/CheckedMenuItem':function(){ +require({cache:{ +'url:dijit/templates/CheckedMenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">✓</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\"> </td>\n</tr>\n"}}); +define("dijit/CheckedMenuItem", [ + "dojo/_base/declare", // declare + "dojo/dom-class", // domClass.toggle + "./MenuItem", + "dojo/text!./templates/CheckedMenuItem.html", + "./hccss" +], function(declare, domClass, MenuItem, template){ + +/*===== + var MenuItem = dijit.MenuItem; +=====*/ + + // module: + // dijit/CheckedMenuItem + // summary: + // A checkbox-like menu item for toggling on and off + + return declare("dijit.CheckedMenuItem", MenuItem, { + // summary: + // A checkbox-like menu item for toggling on and off + + templateString: template, + + // checked: Boolean + // Our checked state + checked: false, + _setCheckedAttr: function(/*Boolean*/ checked){ + // summary: + // Hook so attr('checked', bool) works. + // Sets the class and state for the check box. + domClass.toggle(this.domNode, "dijitCheckedMenuItemChecked", checked); + this.domNode.setAttribute("aria-checked", checked); + this._set("checked", checked); + }, + + iconClass: "", // override dijitNoIcon + + onChange: function(/*Boolean*/ /*===== checked =====*/){ + // summary: + // User defined function to handle check/uncheck events + // tags: + // callback + }, + + _onClick: function(/*Event*/ e){ + // summary: + // Clicking this item just toggles its state + // tags: + // private + if(!this.disabled){ + this.set("checked", !this.checked); + this.onChange(this.checked); + } + this.inherited(arguments); + } + }); +}); + +}, +'dojo/dnd/Container':function(){ +define(["../main", "../Evented", "./common", "../parser"], function(dojo, Evented) { + // module: + // dojo/dnd/Container + // summary: + // TODOC + + +/* + Container states: + "" - normal state + "Over" - mouse over a container + Container item states: + "" - normal state + "Over" - mouse over a container item +*/ + +/*===== +dojo.declare("dojo.dnd.__ContainerArgs", [], { + creator: function(){ + // summary: + // a creator function, which takes a data item, and returns an object like that: + // {node: newNode, data: usedData, type: arrayOfStrings} + }, + + // skipForm: Boolean + // don't start the drag operation, if clicked on form elements + skipForm: false, + + // dropParent: Node||String + // node or node's id to use as the parent node for dropped items + // (must be underneath the 'node' parameter in the DOM) + dropParent: null, + + // _skipStartup: Boolean + // skip startup(), which collects children, for deferred initialization + // (this is used in the markup mode) + _skipStartup: false +}); + +dojo.dnd.Item = function(){ + // summary: + // Represents (one of) the source node(s) being dragged. + // Contains (at least) the "type" and "data" attributes. + // type: String[] + // Type(s) of this item, by default this is ["text"] + // data: Object + // Logical representation of the object being dragged. + // If the drag object's type is "text" then data is a String, + // if it's another type then data could be a different Object, + // perhaps a name/value hash. + + this.type = type; + this.data = data; +} +=====*/ + +dojo.declare("dojo.dnd.Container", Evented, { + // summary: + // a Container object, which knows when mouse hovers over it, + // and over which element it hovers + + // object attributes (for markup) + skipForm: false, + + /*===== + // current: DomNode + // The DOM node the mouse is currently hovered over + current: null, + + // map: Hash<String, dojo.dnd.Item> + // Map from an item's id (which is also the DOMNode's id) to + // the dojo.dnd.Item itself. + map: {}, + =====*/ + + constructor: function(node, params){ + // summary: + // a constructor of the Container + // node: Node + // node or node's id to build the container on + // params: dojo.dnd.__ContainerArgs + // a dictionary of parameters + this.node = dojo.byId(node); + if(!params){ params = {}; } + this.creator = params.creator || null; + this.skipForm = params.skipForm; + this.parent = params.dropParent && dojo.byId(params.dropParent); + + // class-specific variables + this.map = {}; + this.current = null; + + // states + this.containerState = ""; + dojo.addClass(this.node, "dojoDndContainer"); + + // mark up children + if(!(params && params._skipStartup)){ + this.startup(); + } + + // set up events + this.events = [ + dojo.connect(this.node, "onmouseover", this, "onMouseOver"), + dojo.connect(this.node, "onmouseout", this, "onMouseOut"), + // cancel text selection and text dragging + dojo.connect(this.node, "ondragstart", this, "onSelectStart"), + dojo.connect(this.node, "onselectstart", this, "onSelectStart") + ]; + }, + + // object attributes (for markup) + creator: function(){ + // summary: + // creator function, dummy at the moment + }, + + // abstract access to the map + getItem: function(/*String*/ key){ + // summary: + // returns a data item by its key (id) + return this.map[key]; // dojo.dnd.Item + }, + setItem: function(/*String*/ key, /*dojo.dnd.Item*/ data){ + // summary: + // associates a data item with its key (id) + this.map[key] = data; + }, + delItem: function(/*String*/ key){ + // summary: + // removes a data item from the map by its key (id) + delete this.map[key]; + }, + forInItems: function(/*Function*/ f, /*Object?*/ o){ + // summary: + // iterates over a data map skipping members that + // are present in the empty object (IE and/or 3rd-party libraries). + o = o || dojo.global; + var m = this.map, e = dojo.dnd._empty; + for(var i in m){ + if(i in e){ continue; } + f.call(o, m[i], i, this); + } + return o; // Object + }, + clearItems: function(){ + // summary: + // removes all data items from the map + this.map = {}; + }, + + // methods + getAllNodes: function(){ + // summary: + // returns a list (an array) of all valid child nodes + return dojo.query("> .dojoDndItem", this.parent); // NodeList + }, + sync: function(){ + // summary: + // sync up the node list with the data map + var map = {}; + this.getAllNodes().forEach(function(node){ + if(node.id){ + var item = this.getItem(node.id); + if(item){ + map[node.id] = item; + return; + } + }else{ + node.id = dojo.dnd.getUniqueId(); + } + var type = node.getAttribute("dndType"), + data = node.getAttribute("dndData"); + map[node.id] = { + data: data || node.innerHTML, + type: type ? type.split(/\s*,\s*/) : ["text"] + }; + }, this); + this.map = map; + return this; // self + }, + insertNodes: function(data, before, anchor){ + // summary: + // inserts an array of new nodes before/after an anchor node + // data: Array + // a list of data items, which should be processed by the creator function + // before: Boolean + // insert before the anchor, if true, and after the anchor otherwise + // anchor: Node + // the anchor node to be used as a point of insertion + if(!this.parent.firstChild){ + anchor = null; + }else if(before){ + if(!anchor){ + anchor = this.parent.firstChild; + } + }else{ + if(anchor){ + anchor = anchor.nextSibling; + } + } + if(anchor){ + for(var i = 0; i < data.length; ++i){ + var t = this._normalizedCreator(data[i]); + this.setItem(t.node.id, {data: t.data, type: t.type}); + this.parent.insertBefore(t.node, anchor); + } + }else{ + for(var i = 0; i < data.length; ++i){ + var t = this._normalizedCreator(data[i]); + this.setItem(t.node.id, {data: t.data, type: t.type}); + this.parent.appendChild(t.node); + } + } + return this; // self + }, + destroy: function(){ + // summary: + // prepares this object to be garbage-collected + dojo.forEach(this.events, dojo.disconnect); + this.clearItems(); + this.node = this.parent = this.current = null; + }, + + // markup methods + markupFactory: function(params, node, ctor){ + params._skipStartup = true; + return new ctor(node, params); + }, + startup: function(){ + // summary: + // collects valid child items and populate the map + + // set up the real parent node + if(!this.parent){ + // use the standard algorithm, if not assigned + this.parent = this.node; + if(this.parent.tagName.toLowerCase() == "table"){ + var c = this.parent.getElementsByTagName("tbody"); + if(c && c.length){ this.parent = c[0]; } + } + } + this.defaultCreator = dojo.dnd._defaultCreator(this.parent); + + // process specially marked children + this.sync(); + }, + + // mouse events + onMouseOver: function(e){ + // summary: + // event processor for onmouseover + // e: Event + // mouse event + var n = e.relatedTarget; + while(n){ + if(n == this.node){ break; } + try{ + n = n.parentNode; + }catch(x){ + n = null; + } + } + if(!n){ + this._changeState("Container", "Over"); + this.onOverEvent(); + } + n = this._getChildByEvent(e); + if(this.current == n){ return; } + if(this.current){ this._removeItemClass(this.current, "Over"); } + if(n){ this._addItemClass(n, "Over"); } + this.current = n; + }, + onMouseOut: function(e){ + // summary: + // event processor for onmouseout + // e: Event + // mouse event + for(var n = e.relatedTarget; n;){ + if(n == this.node){ return; } + try{ + n = n.parentNode; + }catch(x){ + n = null; + } + } + if(this.current){ + this._removeItemClass(this.current, "Over"); + this.current = null; + } + this._changeState("Container", ""); + this.onOutEvent(); + }, + onSelectStart: function(e){ + // summary: + // event processor for onselectevent and ondragevent + // e: Event + // mouse event + if(!this.skipForm || !dojo.dnd.isFormElement(e)){ + dojo.stopEvent(e); + } + }, + + // utilities + onOverEvent: function(){ + // summary: + // this function is called once, when mouse is over our container + }, + onOutEvent: function(){ + // summary: + // this function is called once, when mouse is out of our container + }, + _changeState: function(type, newState){ + // summary: + // changes a named state to new state value + // type: String + // a name of the state to change + // newState: String + // new state + var prefix = "dojoDnd" + type; + var state = type.toLowerCase() + "State"; + //dojo.replaceClass(this.node, prefix + newState, prefix + this[state]); + dojo.replaceClass(this.node, prefix + newState, prefix + this[state]); + this[state] = newState; + }, + _addItemClass: function(node, type){ + // summary: + // adds a class with prefix "dojoDndItem" + // node: Node + // a node + // type: String + // a variable suffix for a class name + dojo.addClass(node, "dojoDndItem" + type); + }, + _removeItemClass: function(node, type){ + // summary: + // removes a class with prefix "dojoDndItem" + // node: Node + // a node + // type: String + // a variable suffix for a class name + dojo.removeClass(node, "dojoDndItem" + type); + }, + _getChildByEvent: function(e){ + // summary: + // gets a child, which is under the mouse at the moment, or null + // e: Event + // a mouse event + var node = e.target; + if(node){ + for(var parent = node.parentNode; parent; node = parent, parent = node.parentNode){ + if(parent == this.parent && dojo.hasClass(node, "dojoDndItem")){ return node; } + } + } + return null; + }, + _normalizedCreator: function(/*dojo.dnd.Item*/ item, /*String*/ hint){ + // summary: + // adds all necessary data to the output of the user-supplied creator function + var t = (this.creator || this.defaultCreator).call(this, item, hint); + if(!dojo.isArray(t.type)){ t.type = ["text"]; } + if(!t.node.id){ t.node.id = dojo.dnd.getUniqueId(); } + dojo.addClass(t.node, "dojoDndItem"); + return t; + } +}); + +dojo.dnd._createNode = function(tag){ + // summary: + // returns a function, which creates an element of given tag + // (SPAN by default) and sets its innerHTML to given text + // tag: String + // a tag name or empty for SPAN + if(!tag){ return dojo.dnd._createSpan; } + return function(text){ // Function + return dojo.create(tag, {innerHTML: text}); // Node + }; +}; + +dojo.dnd._createTrTd = function(text){ + // summary: + // creates a TR/TD structure with given text as an innerHTML of TD + // text: String + // a text for TD + var tr = dojo.create("tr"); + dojo.create("td", {innerHTML: text}, tr); + return tr; // Node +}; + +dojo.dnd._createSpan = function(text){ + // summary: + // creates a SPAN element with given text as its innerHTML + // text: String + // a text for SPAN + return dojo.create("span", {innerHTML: text}); // Node +}; + +// dojo.dnd._defaultCreatorNodes: Object +// a dictionary that maps container tag names to child tag names +dojo.dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"}; + +dojo.dnd._defaultCreator = function(node){ + // summary: + // takes a parent node, and returns an appropriate creator function + // node: Node + // a container node + var tag = node.tagName.toLowerCase(); + var c = tag == "tbody" || tag == "thead" ? dojo.dnd._createTrTd : + dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]); + return function(item, hint){ // Function + var isObj = item && dojo.isObject(item), data, type, n; + if(isObj && item.tagName && item.nodeType && item.getAttribute){ + // process a DOM node + data = item.getAttribute("dndData") || item.innerHTML; + type = item.getAttribute("dndType"); + type = type ? type.split(/\s*,\s*/) : ["text"]; + n = item; // this node is going to be moved rather than copied + }else{ + // process a DnD item object or a string + data = (isObj && item.data) ? item.data : item; + type = (isObj && item.type) ? item.type : ["text"]; + n = (hint == "avatar" ? dojo.dnd._createSpan : c)(String(data)); + } + if(!n.id){ + n.id = dojo.dnd.getUniqueId(); + } + return {node: n, data: data, type: type}; + }; +}; + +return dojo.dnd.Container; +}); + +}, +'dojo/dnd/common':function(){ +define(["../main"], function(dojo) { + // module: + // dojo/dnd/common + // summary: + // TODOC + +dojo.getObject("dnd", true, dojo); + +dojo.dnd.getCopyKeyState = dojo.isCopyKey; + +dojo.dnd._uniqueId = 0; +dojo.dnd.getUniqueId = function(){ + // summary: + // returns a unique string for use with any DOM element + var id; + do{ + id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId); + }while(dojo.byId(id)); + return id; +}; + +dojo.dnd._empty = {}; + +dojo.dnd.isFormElement = function(/*Event*/ e){ + // summary: + // returns true if user clicked on a form element + var t = e.target; + if(t.nodeType == 3 /*TEXT_NODE*/){ + t = t.parentNode; + } + return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0; // Boolean +}; + +return dojo.dnd; +}); + +}, +'dojox/grid/_ViewManager':function(){ +define("dojox/grid/_ViewManager", [ + "dojo/_base/declare", + "dojo/_base/sniff", + "dojo/dom-class" +], function(declare, has, domClass){ + +return declare('dojox.grid._ViewManager', null, { + // summary: + // A collection of grid views. Owned by grid and used internally for managing grid views. + // description: + // Grid creates views automatically based on grid's layout structure. + // Users should typically not need to access individual views or the views collection directly. + constructor: function(inGrid){ + this.grid = inGrid; + }, + + defaultWidth: 200, + + views: [], + + // operations + resize: function(){ + this.onEach("resize"); + }, + + render: function(){ + this.onEach("render"); + }, + + // views + addView: function(inView){ + inView.idx = this.views.length; + this.views.push(inView); + }, + + destroyViews: function(){ + for(var i=0, v; v=this.views[i]; i++){ + v.destroy(); + } + this.views = []; + }, + + getContentNodes: function(){ + var nodes = []; + for(var i=0, v; v=this.views[i]; i++){ + nodes.push(v.contentNode); + } + return nodes; + }, + + forEach: function(inCallback){ + for(var i=0, v; v=this.views[i]; i++){ + inCallback(v, i); + } + }, + + onEach: function(inMethod, inArgs){ + inArgs = inArgs || []; + for(var i=0, v; v=this.views[i]; i++){ + if(inMethod in v){ + v[inMethod].apply(v, inArgs); + } + } + }, + + // layout + normalizeHeaderNodeHeight: function(){ + var rowNodes = []; + for(var i=0, v; (v=this.views[i]); i++){ + if(v.headerContentNode.firstChild){ + rowNodes.push(v.headerContentNode); + } + } + this.normalizeRowNodeHeights(rowNodes); + }, + + normalizeRowNodeHeights: function(inRowNodes){ + var h = 0; + var currHeights = []; + if(this.grid.rowHeight){ + h = this.grid.rowHeight; + }else{ + if(inRowNodes.length <= 1){ + // no need to normalize if we are the only one... + return; + } + for(var i=0, n; (n=inRowNodes[i]); i++){ + // We only care about the height - so don't use marginBox. This + // depends on the container not having any margin (which it shouldn't) + // Also - we only look up the height if the cell doesn't have the + // dojoxGridNonNormalizedCell class (like for row selectors) + if(!domClass.contains(n, "dojoxGridNonNormalizedCell")){ + currHeights[i] = n.firstChild.offsetHeight; + h = Math.max(h, currHeights[i]); + } + } + h = (h >= 0 ? h : 0); + + //Work around odd FF3 rendering bug: #8864. + //A one px increase fixes FireFox 3's rounding bug for fractional font sizes. + if((has("mozilla") || has("ie") > 8 ) && h){h++;} + } + for(i=0; (n=inRowNodes[i]); i++){ + if(currHeights[i] != h){ + n.firstChild.style.height = h + "px"; + } + } + }, + + resetHeaderNodeHeight: function(){ + for(var i=0, v, n; (v=this.views[i]); i++){ + n = v.headerContentNode.firstChild; + if(n){ + n.style.height = ""; + } + } + }, + + renormalizeRow: function(inRowIndex){ + var rowNodes = []; + for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){ + n.firstChild.style.height = ''; + rowNodes.push(n); + } + this.normalizeRowNodeHeights(rowNodes); + }, + + getViewWidth: function(inIndex){ + return this.views[inIndex].getWidth() || this.defaultWidth; + }, + + // must be called after view widths are properly set or height can be miscalculated + // if there are flex columns + measureHeader: function(){ + // need to reset view header heights so they are properly measured. + this.resetHeaderNodeHeight(); + this.forEach(function(inView){ + inView.headerContentNode.style.height = ''; + }); + var h = 0; + // calculate maximum view header height + this.forEach(function(inView){ + h = Math.max(inView.headerNode.offsetHeight, h); + }); + return h; + }, + + measureContent: function(){ + var h = 0; + this.forEach(function(inView){ + h = Math.max(inView.domNode.offsetHeight, h); + }); + return h; + }, + + findClient: function(inAutoWidth){ + // try to use user defined client + var c = this.grid.elasticView || -1; + // attempt to find implicit client + if(c < 0){ + for(var i=1, v; (v=this.views[i]); i++){ + if(v.viewWidth){ + for(i=1; (v=this.views[i]); i++){ + if(!v.viewWidth){ + c = i; + break; + } + } + break; + } + } + } + // client is in the middle by default + if(c < 0){ + c = Math.floor(this.views.length / 2); + } + return c; + }, + + arrange: function(l, w){ + var i, v, vw, len = this.views.length, self = this; + // find the client + var c = (w <= 0 ? len : this.findClient()); + // layout views + var setPosition = function(v, l){ + var ds = v.domNode.style; + var hs = v.headerNode.style; + + if(!self.grid.isLeftToRight()){ + ds.right = l + 'px'; + // fixed rtl, the scrollbar is on the right side in FF or WebKit + if (has("ff") < 4 || has("webkit")){ + hs.right = l + v.getScrollbarWidth() + 'px'; + hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px'; + }else{ + hs.right = l + 'px'; + } + }else{ + ds.left = l + 'px'; + hs.left = l + 'px'; + } + ds.top = 0 + 'px'; + hs.top = 0; + }; + // for views left of the client + //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with + //leading and tailing concept. + for(i=0; (v=this.views[i])&&(i<c); i++){ + // get width + vw = this.getViewWidth(i); + // process boxes + v.setSize(vw, 0); + setPosition(v, l); + if(v.headerContentNode && v.headerContentNode.firstChild){ + vw = v.getColumnsWidth()+v.getScrollbarWidth(); + }else{ + vw = v.domNode.offsetWidth; + } + // update position + l += vw; + } + // next view (is the client, i++ == c) + i++; + // start from the right edge + var r = w; + // for views right of the client (iterated from the right) + for(var j=len-1; (v=this.views[j])&&(i<=j); j--){ + // get width + vw = this.getViewWidth(j); + // set size + v.setSize(vw, 0); + // measure in pixels + vw = v.domNode.offsetWidth; + // update position + r -= vw; + // set position + setPosition(v, r); + } + if(c<len){ + v = this.views[c]; + // position the client box between left and right boxes + vw = Math.max(1, r-l); + // set size + v.setSize(vw + 'px', 0); + setPosition(v, l); + } + return l; + }, + + // rendering + renderRow: function(inRowIndex, inNodes, skipRenorm){ + var rowNodes = []; + for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){ + rowNode = v.renderRow(inRowIndex); + n.appendChild(rowNode); + rowNodes.push(rowNode); + } + if(!skipRenorm){ + this.normalizeRowNodeHeights(rowNodes); + } + }, + + rowRemoved: function(inRowIndex){ + this.onEach("rowRemoved", [ inRowIndex ]); + }, + + // updating + updateRow: function(inRowIndex, skipRenorm){ + for(var i=0, v; v=this.views[i]; i++){ + v.updateRow(inRowIndex); + } + if(!skipRenorm){ + this.renormalizeRow(inRowIndex); + } + }, + + updateRowStyles: function(inRowIndex){ + this.onEach("updateRowStyles", [ inRowIndex ]); + }, + + // scrolling + setScrollTop: function(inTop){ + var top = inTop; + for(var i=0, v; v=this.views[i]; i++){ + top = v.setScrollTop(inTop); + // Work around IE not firing scroll events that cause header offset + // issues to occur. + if(has("ie") && v.headerNode && v.scrollboxNode){ + v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft; + } + } + return top; + //this.onEach("setScrollTop", [ inTop ]); + }, + + getFirstScrollingView: function(){ + // summary: Returns the first grid view with a scroll bar + for(var i=0, v; (v=this.views[i]); i++){ + if(v.hasHScrollbar() || v.hasVScrollbar()){ + return v; + } + } + return null; + } +}); +}); +}, +'dojox/grid/cells':function(){ +define("dojox/grid/cells", ["../main", "./cells/_base"], function(dojox){ + return dojox.grid.cells; +}); +}, +'dijit/_Widget':function(){ +define("dijit/_Widget", [ + "dojo/aspect", // aspect.around + "dojo/_base/config", // config.isDebug + "dojo/_base/connect", // connect.connect + "dojo/_base/declare", // declare + "dojo/_base/kernel", // kernel.deprecated + "dojo/_base/lang", // lang.hitch + "dojo/query", + "dojo/ready", + "./registry", // registry.byNode + "./_WidgetBase", + "./_OnDijitClickMixin", + "./_FocusMixin", + "dojo/uacss", // browser sniffing (included for back-compat; subclasses may be using) + "./hccss" // high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused) +], function(aspect, config, connect, declare, kernel, lang, query, ready, + registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){ + +/*===== + var _WidgetBase = dijit._WidgetBase; + var _OnDijitClickMixin = dijit._OnDijitClickMixin; + var _FocusMixin = dijit._FocusMixin; +=====*/ + + +// module: +// dijit/_Widget +// summary: +// Old base for widgets. New widgets should extend _WidgetBase instead + + +function connectToDomNode(){ + // summary: + // If user connects to a widget method === this function, then they will + // instead actually be connecting the equivalent event on this.domNode +} + +// Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on() +function aroundAdvice(originalConnect){ + return function(obj, event, scope, method){ + if(obj && typeof event == "string" && obj[event] == connectToDomNode){ + return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method)); + } + return originalConnect.apply(connect, arguments); + }; +} +aspect.around(connect, "connect", aroundAdvice); +if(kernel.connect){ + aspect.around(kernel, "connect", aroundAdvice); +} + +var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], { + // summary: + // Base class for all Dijit widgets. + // + // Extends _WidgetBase, adding support for: + // - declaratively/programatically specifying widget initialization parameters like + // onMouseMove="foo" that call foo when this.domNode gets a mousemove event + // - ondijitclick + // Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress + // - focus related functions + // In particular, the onFocus()/onBlur() callbacks. Driven internally by + // dijit/_base/focus.js. + // - deprecated methods + // - onShow(), onHide(), onClose() + // + // Also, by loading code in dijit/_base, turns on: + // - browser sniffing (putting browser id like .dj_ie on <html> node) + // - high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode) + + + ////////////////// DEFERRED CONNECTS /////////////////// + + onClick: connectToDomNode, + /*===== + onClick: function(event){ + // summary: + // Connect to this function to receive notifications of mouse click events. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onDblClick: connectToDomNode, + /*===== + onDblClick: function(event){ + // summary: + // Connect to this function to receive notifications of mouse double click events. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onKeyDown: connectToDomNode, + /*===== + onKeyDown: function(event){ + // summary: + // Connect to this function to receive notifications of keys being pressed down. + // event: + // key Event + // tags: + // callback + }, + =====*/ + onKeyPress: connectToDomNode, + /*===== + onKeyPress: function(event){ + // summary: + // Connect to this function to receive notifications of printable keys being typed. + // event: + // key Event + // tags: + // callback + }, + =====*/ + onKeyUp: connectToDomNode, + /*===== + onKeyUp: function(event){ + // summary: + // Connect to this function to receive notifications of keys being released. + // event: + // key Event + // tags: + // callback + }, + =====*/ + onMouseDown: connectToDomNode, + /*===== + onMouseDown: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse button is pressed down. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onMouseMove: connectToDomNode, + /*===== + onMouseMove: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onMouseOut: connectToDomNode, + /*===== + onMouseOut: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onMouseOver: connectToDomNode, + /*===== + onMouseOver: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onMouseLeave: connectToDomNode, + /*===== + onMouseLeave: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse moves off of this widget. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onMouseEnter: connectToDomNode, + /*===== + onMouseEnter: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse moves onto this widget. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + onMouseUp: connectToDomNode, + /*===== + onMouseUp: function(event){ + // summary: + // Connect to this function to receive notifications of when the mouse button is released. + // event: + // mouse Event + // tags: + // callback + }, + =====*/ + + constructor: function(params){ + // extract parameters like onMouseMove that should connect directly to this.domNode + this._toConnect = {}; + for(var name in params){ + if(this[name] === connectToDomNode){ + this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name]; + delete params[name]; + } + } + }, + + postCreate: function(){ + this.inherited(arguments); + + // perform connection from this.domNode to user specified handlers (ex: onMouseMove) + for(var name in this._toConnect){ + this.on(name, this._toConnect[name]); + } + delete this._toConnect; + }, + + on: function(/*String*/ type, /*Function*/ func){ + if(this[this._onMap(type)] === connectToDomNode){ + // Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE, etc. + // Also, need to specify context as "this" rather than the default context of the DOMNode + return connect.connect(this.domNode, type.toLowerCase(), this, func); + } + return this.inherited(arguments); + }, + + _setFocusedAttr: function(val){ + // Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat + // (but since it's a private variable we aren't required to keep supporting it). + this._focused = val; + this._set("focused", val); + }, + + ////////////////// DEPRECATED METHODS /////////////////// + + setAttribute: function(/*String*/ attr, /*anything*/ value){ + // summary: + // Deprecated. Use set() instead. + // tags: + // deprecated + kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0"); + this.set(attr, value); + }, + + attr: function(/*String|Object*/name, /*Object?*/value){ + // summary: + // Set or get properties on a widget instance. + // name: + // The property to get or set. If an object is passed here and not + // a string, its keys are used as names of attributes to be set + // and the value of the object as values to set in the widget. + // value: + // Optional. If provided, attr() operates as a setter. If omitted, + // the current value of the named property is returned. + // description: + // This method is deprecated, use get() or set() directly. + + // Print deprecation warning but only once per calling function + if(config.isDebug){ + var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}), + caller = (arguments.callee.caller || "unknown caller").toString(); + if(!alreadyCalledHash[caller]){ + kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " + + caller, "", "2.0"); + alreadyCalledHash[caller] = true; + } + } + + var args = arguments.length; + if(args >= 2 || typeof name === "object"){ // setter + return this.set.apply(this, arguments); + }else{ // getter + return this.get(name); + } + }, + + getDescendants: function(){ + // summary: + // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode. + // This method should generally be avoided as it returns widgets declared in templates, which are + // supposed to be internal/hidden, but it's left here for back-compat reasons. + + kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0"); + return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit._Widget[] + }, + + ////////////////// MISCELLANEOUS METHODS /////////////////// + + _onShow: function(){ + // summary: + // Internal method called when this widget is made visible. + // See `onShow` for details. + this.onShow(); + }, + + onShow: function(){ + // summary: + // Called when this widget becomes the selected pane in a + // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`, + // `dijit.layout.AccordionContainer`, etc. + // + // Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`. + // tags: + // callback + }, + + onHide: function(){ + // summary: + // Called when another widget becomes the selected pane in a + // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`, + // `dijit.layout.AccordionContainer`, etc. + // + // Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`. + // tags: + // callback + }, + + onClose: function(){ + // summary: + // Called when this widget is being displayed as a popup (ex: a Calendar popped + // up from a DateTextBox), and it is hidden. + // This is called from the dijit.popup code, and should not be called directly. + // + // Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses. + // Callback if a user tries to close the child. Child will be closed if this function returns true. + // tags: + // extension + + return true; // Boolean + } +}); + +// For back-compat, remove in 2.0. +if(!kernel.isAsync){ + ready(0, function(){ + var requires = ["dijit/_base"]; + require(requires); // use indirection so modules not rolled into a build + }); +} +return _Widget; +}); + +}, +'dijit/_FocusMixin':function(){ +define("dijit/_FocusMixin", [ + "./focus", + "./_WidgetBase", + "dojo/_base/declare", // declare + "dojo/_base/lang" // lang.extend +], function(focus, _WidgetBase, declare, lang){ + +/*===== + var _WidgetBase = dijit._WidgetBase; +=====*/ + + // module: + // dijit/_FocusMixin + // summary: + // Mixin to widget to provide _onFocus() and _onBlur() methods that + // fire when a widget or it's descendants get/lose focus + + // We don't know where _FocusMixin will occur in the inheritance chain, but we need the _onFocus()/_onBlur() below + // to be last in the inheritance chain, so mixin to _WidgetBase. + lang.extend(_WidgetBase, { + // focused: [readonly] Boolean + // This widget or a widget it contains has focus, or is "active" because + // it was recently clicked. + focused: false, + + onFocus: function(){ + // summary: + // Called when the widget becomes "active" because + // it or a widget inside of it either has focus, or has recently + // been clicked. + // tags: + // callback + }, + + onBlur: function(){ + // summary: + // Called when the widget stops being "active" because + // focus moved to something outside of it, or the user + // clicked somewhere outside of it, or the widget was + // hidden. + // tags: + // callback + }, + + _onFocus: function(){ + // summary: + // This is where widgets do processing for when they are active, + // such as changing CSS classes. See onFocus() for more details. + // tags: + // protected + this.onFocus(); + }, + + _onBlur: function(){ + // summary: + // This is where widgets do processing for when they stop being active, + // such as changing CSS classes. See onBlur() for more details. + // tags: + // protected + this.onBlur(); + } + }); + + return declare("dijit._FocusMixin", null, { + // summary: + // Mixin to widget to provide _onFocus() and _onBlur() methods that + // fire when a widget or it's descendants get/lose focus + + // flag that I want _onFocus()/_onBlur() notifications from focus manager + _focusManager: focus + }); + +}); + +}, +'dijit/_OnDijitClickMixin':function(){ +define("dijit/_OnDijitClickMixin", [ + "dojo/on", + "dojo/_base/array", // array.forEach + "dojo/keys", // keys.ENTER keys.SPACE + "dojo/_base/declare", // declare + "dojo/_base/sniff", // has("ie") + "dojo/_base/unload", // unload.addOnWindowUnload + "dojo/_base/window" // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent +], function(on, array, keys, declare, has, unload, win){ + + // module: + // dijit/_OnDijitClickMixin + // summary: + // Mixin so you can pass "ondijitclick" to this.connect() method, + // as a way to handle clicks by mouse, or by keyboard (SPACE/ENTER key) + + + // Keep track of where the last keydown event was, to help avoid generating + // spurious ondijitclick events when: + // 1. focus is on a <button> or <a> + // 2. user presses then releases the ENTER key + // 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler + // 4. onkeyup event fires, causing the ondijitclick handler to fire + var lastKeyDownNode = null; + if(has("ie")){ + (function(){ + var keydownCallback = function(evt){ + lastKeyDownNode = evt.srcElement; + }; + win.doc.attachEvent('onkeydown', keydownCallback); + unload.addOnWindowUnload(function(){ + win.doc.detachEvent('onkeydown', keydownCallback); + }); + })(); + }else{ + win.doc.addEventListener('keydown', function(evt){ + lastKeyDownNode = evt.target; + }, true); + } + + // Custom a11yclick (a.k.a. ondijitclick) event + var a11yclick = function(node, listener){ + if(/input|button/i.test(node.nodeName)){ + // pass through, the browser already generates click event on SPACE/ENTER key + return on(node, "click", listener); + }else{ + // Don't fire the click event unless both the keydown and keyup occur on this node. + // Avoids problems where focus shifted to this node or away from the node on keydown, + // either causing this node to process a stray keyup event, or causing another node + // to get a stray keyup event. + + function clickKey(/*Event*/ e){ + return (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) && + !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey; + } + var handles = [ + on(node, "keypress", function(e){ + //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode)); + if(clickKey(e)){ + // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work + lastKeyDownNode = e.target; + + // Prevent viewport scrolling on space key in IE<9. + // (Reproducible on test_Button.html on any of the first dijit.form.Button examples) + // Do this onkeypress rather than onkeydown because onkeydown.preventDefault() will + // suppress the onkeypress event, breaking _HasDropDown + e.preventDefault(); + } + }), + + on(node, "keyup", function(e){ + //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode)); + if(clickKey(e) && e.target == lastKeyDownNode){ // === breaks greasemonkey + //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert + lastKeyDownNode = null; + listener.call(this, e); + } + }), + + on(node, "click", function(e){ + // and connect for mouse clicks too (or touch-clicks on mobile) + listener.call(this, e); + }) + ]; + + return { + remove: function(){ + array.forEach(handles, function(h){ h.remove(); }); + } + }; + } + }; + + return declare("dijit._OnDijitClickMixin", null, { + connect: function( + /*Object|null*/ obj, + /*String|Function*/ event, + /*String|Function*/ method){ + // summary: + // Connects specified obj/event to specified method of this object + // and registers for disconnect() on widget destroy. + // description: + // Provide widget-specific analog to connect.connect, except with the + // implicit use of this widget as the target object. + // This version of connect also provides a special "ondijitclick" + // event which triggers on a click or space or enter keyup. + // Events connected with `this.connect` are disconnected upon + // destruction. + // returns: + // A handle that can be passed to `disconnect` in order to disconnect before + // the widget is destroyed. + // example: + // | var btn = new dijit.form.Button(); + // | // when foo.bar() is called, call the listener we're going to + // | // provide in the scope of btn + // | btn.connect(foo, "bar", function(){ + // | console.debug(this.toString()); + // | }); + // tags: + // protected + + return this.inherited(arguments, [obj, event == "ondijitclick" ? a11yclick : event, method]); + } + }); +}); + +}, +'dojo/cache':function(){ +define(["./_base/kernel", "./text"], function(dojo, text){ + // module: + // dojo/cache + // summary: + // The module defines dojo.cache by loading dojo/text. + + //dojo.cache is defined in dojo/text + return dojo.cache; +}); + +}, +'dijit/focus':function(){ +define("dijit/focus", [ + "dojo/aspect", + "dojo/_base/declare", // declare + "dojo/dom", // domAttr.get dom.isDescendant + "dojo/dom-attr", // domAttr.get dom.isDescendant + "dojo/dom-construct", // connect to domConstruct.empty, domConstruct.destroy + "dojo/Evented", + "dojo/_base/lang", // lang.hitch + "dojo/on", + "dojo/ready", + "dojo/_base/sniff", // has("ie") + "dojo/Stateful", + "dojo/_base/unload", // unload.addOnWindowUnload + "dojo/_base/window", // win.body + "dojo/window", // winUtils.get + "./a11y", // a11y.isTabNavigable + "./registry", // registry.byId + "." // to set dijit.focus +], function(aspect, declare, dom, domAttr, domConstruct, Evented, lang, on, ready, has, Stateful, unload, win, winUtils, + a11y, registry, dijit){ + + // module: + // dijit/focus + // summary: + // Returns a singleton that tracks the currently focused node, and which widgets are currently "active". + +/*===== + dijit.focus = { + // summary: + // Tracks the currently focused node, and which widgets are currently "active". + // Access via require(["dijit/focus"], function(focus){ ... }). + // + // A widget is considered active if it or a descendant widget has focus, + // or if a non-focusable node of this widget or a descendant was recently clicked. + // + // Call focus.watch("curNode", callback) to track the current focused DOMNode, + // or focus.watch("activeStack", callback) to track the currently focused stack of widgets. + // + // Call focus.on("widget-blur", func) or focus.on("widget-focus", ...) to monitor when + // when widgets become active/inactive + // + // Finally, focus(node) will focus a node, suppressing errors if the node doesn't exist. + + // curNode: DomNode + // Currently focused item on screen + curNode: null, + + // activeStack: dijit._Widget[] + // List of currently active widgets (focused widget and it's ancestors) + activeStack: [], + + registerIframe: function(iframe){ + // summary: + // Registers listeners on the specified iframe so that any click + // or focus event on that iframe (or anything in it) is reported + // as a focus/click event on the <iframe> itself. + // description: + // Currently only used by editor. + // returns: + // Handle with remove() method to deregister. + }, + + registerWin: function(targetWindow, effectiveNode){ + // summary: + // Registers listeners on the specified window (either the main + // window or an iframe's window) to detect when the user has clicked somewhere + // or focused somewhere. + // description: + // Users should call registerIframe() instead of this method. + // targetWindow: Window? + // If specified this is the window associated with the iframe, + // i.e. iframe.contentWindow. + // effectiveNode: DOMNode? + // If specified, report any focus events inside targetWindow as + // an event on effectiveNode, rather than on evt.target. + // returns: + // Handle with remove() method to deregister. + } + }; +=====*/ + + var FocusManager = declare([Stateful, Evented], { + // curNode: DomNode + // Currently focused item on screen + curNode: null, + + // activeStack: dijit._Widget[] + // List of currently active widgets (focused widget and it's ancestors) + activeStack: [], + + constructor: function(){ + // Don't leave curNode/prevNode pointing to bogus elements + var check = lang.hitch(this, function(node){ + if(dom.isDescendant(this.curNode, node)){ + this.set("curNode", null); + } + if(dom.isDescendant(this.prevNode, node)){ + this.set("prevNode", null); + } + }); + aspect.before(domConstruct, "empty", check); + aspect.before(domConstruct, "destroy", check); + }, + + registerIframe: function(/*DomNode*/ iframe){ + // summary: + // Registers listeners on the specified iframe so that any click + // or focus event on that iframe (or anything in it) is reported + // as a focus/click event on the <iframe> itself. + // description: + // Currently only used by editor. + // returns: + // Handle with remove() method to deregister. + return this.registerWin(iframe.contentWindow, iframe); + }, + + registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){ + // summary: + // Registers listeners on the specified window (either the main + // window or an iframe's window) to detect when the user has clicked somewhere + // or focused somewhere. + // description: + // Users should call registerIframe() instead of this method. + // targetWindow: + // If specified this is the window associated with the iframe, + // i.e. iframe.contentWindow. + // effectiveNode: + // If specified, report any focus events inside targetWindow as + // an event on effectiveNode, rather than on evt.target. + // returns: + // Handle with remove() method to deregister. + + // TODO: make this function private in 2.0; Editor/users should call registerIframe(), + + var _this = this; + var mousedownListener = function(evt){ + _this._justMouseDowned = true; + setTimeout(function(){ _this._justMouseDowned = false; }, 0); + + // workaround weird IE bug where the click is on an orphaned node + // (first time clicking a Select/DropDownButton inside a TooltipDialog) + if(has("ie") && evt && evt.srcElement && evt.srcElement.parentNode == null){ + return; + } + + _this._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse"); + }; + + // Listen for blur and focus events on targetWindow's document. + // IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble + // through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers + // fire. + // Connect to <html> (rather than document) on IE to avoid memory leaks, but document on other browsers because + // (at least for FF) the focus event doesn't fire on <html> or <body>. + var doc = has("ie") ? targetWindow.document.documentElement : targetWindow.document; + if(doc){ + if(has("ie")){ + targetWindow.document.body.attachEvent('onmousedown', mousedownListener); + var activateListener = function(evt){ + // IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1, + // ignore those events + var tag = evt.srcElement.tagName.toLowerCase(); + if(tag == "#document" || tag == "body"){ return; } + + // Previous code called _onTouchNode() for any activate event on a non-focusable node. Can + // probably just ignore such an event as it will be handled by onmousedown handler above, but + // leaving the code for now. + if(a11y.isTabNavigable(evt.srcElement)){ + _this._onFocusNode(effectiveNode || evt.srcElement); + }else{ + _this._onTouchNode(effectiveNode || evt.srcElement); + } + }; + doc.attachEvent('onactivate', activateListener); + var deactivateListener = function(evt){ + _this._onBlurNode(effectiveNode || evt.srcElement); + }; + doc.attachEvent('ondeactivate', deactivateListener); + + return { + remove: function(){ + targetWindow.document.detachEvent('onmousedown', mousedownListener); + doc.detachEvent('onactivate', activateListener); + doc.detachEvent('ondeactivate', deactivateListener); + doc = null; // prevent memory leak (apparent circular reference via closure) + } + }; + }else{ + doc.body.addEventListener('mousedown', mousedownListener, true); + doc.body.addEventListener('touchstart', mousedownListener, true); + var focusListener = function(evt){ + _this._onFocusNode(effectiveNode || evt.target); + }; + doc.addEventListener('focus', focusListener, true); + var blurListener = function(evt){ + _this._onBlurNode(effectiveNode || evt.target); + }; + doc.addEventListener('blur', blurListener, true); + + return { + remove: function(){ + doc.body.removeEventListener('mousedown', mousedownListener, true); + doc.body.removeEventListener('touchstart', mousedownListener, true); + doc.removeEventListener('focus', focusListener, true); + doc.removeEventListener('blur', blurListener, true); + doc = null; // prevent memory leak (apparent circular reference via closure) + } + }; + } + } + }, + + _onBlurNode: function(/*DomNode*/ /*===== node =====*/){ + // summary: + // Called when focus leaves a node. + // Usually ignored, _unless_ it *isn't* followed by touching another node, + // which indicates that we tabbed off the last field on the page, + // in which case every widget is marked inactive + this.set("prevNode", this.curNode); + this.set("curNode", null); + + if(this._justMouseDowned){ + // the mouse down caused a new widget to be marked as active; this blur event + // is coming late, so ignore it. + return; + } + + // if the blur event isn't followed by a focus event then mark all widgets as inactive. + if(this._clearActiveWidgetsTimer){ + clearTimeout(this._clearActiveWidgetsTimer); + } + this._clearActiveWidgetsTimer = setTimeout(lang.hitch(this, function(){ + delete this._clearActiveWidgetsTimer; + this._setStack([]); + this.prevNode = null; + }), 100); + }, + + _onTouchNode: function(/*DomNode*/ node, /*String*/ by){ + // summary: + // Callback when node is focused or mouse-downed + // node: + // The node that was touched. + // by: + // "mouse" if the focus/touch was caused by a mouse down event + + // ignore the recent blurNode event + if(this._clearActiveWidgetsTimer){ + clearTimeout(this._clearActiveWidgetsTimer); + delete this._clearActiveWidgetsTimer; + } + + // compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem) + var newStack=[]; + try{ + while(node){ + var popupParent = domAttr.get(node, "dijitPopupParent"); + if(popupParent){ + node=registry.byId(popupParent).domNode; + }else if(node.tagName && node.tagName.toLowerCase() == "body"){ + // is this the root of the document or just the root of an iframe? + if(node === win.body()){ + // node is the root of the main document + break; + } + // otherwise, find the iframe this node refers to (can't access it via parentNode, + // need to do this trick instead). window.frameElement is supported in IE/FF/Webkit + node=winUtils.get(node.ownerDocument).frameElement; + }else{ + // if this node is the root node of a widget, then add widget id to stack, + // except ignore clicks on disabled widgets (actually focusing a disabled widget still works, + // to support MenuItem) + var id = node.getAttribute && node.getAttribute("widgetId"), + widget = id && registry.byId(id); + if(widget && !(by == "mouse" && widget.get("disabled"))){ + newStack.unshift(id); + } + node=node.parentNode; + } + } + }catch(e){ /* squelch */ } + + this._setStack(newStack, by); + }, + + _onFocusNode: function(/*DomNode*/ node){ + // summary: + // Callback when node is focused + + if(!node){ + return; + } + + if(node.nodeType == 9){ + // Ignore focus events on the document itself. This is here so that + // (for example) clicking the up/down arrows of a spinner + // (which don't get focus) won't cause that widget to blur. (FF issue) + return; + } + + this._onTouchNode(node); + + if(node == this.curNode){ return; } + this.set("curNode", node); + }, + + _setStack: function(/*String[]*/ newStack, /*String*/ by){ + // summary: + // The stack of active widgets has changed. Send out appropriate events and records new stack. + // newStack: + // array of widget id's, starting from the top (outermost) widget + // by: + // "mouse" if the focus/touch was caused by a mouse down event + + var oldStack = this.activeStack; + this.set("activeStack", newStack); + + // compare old stack to new stack to see how many elements they have in common + for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){ + if(oldStack[nCommon] != newStack[nCommon]){ + break; + } + } + + var widget; + // for all elements that have gone out of focus, set focused=false + for(var i=oldStack.length-1; i>=nCommon; i--){ + widget = registry.byId(oldStack[i]); + if(widget){ + widget._hasBeenBlurred = true; // TODO: used by form widgets, should be moved there + widget.set("focused", false); + if(widget._focusManager == this){ + widget._onBlur(by); + } + this.emit("widget-blur", widget, by); + } + } + + // for all element that have come into focus, set focused=true + for(i=nCommon; i<newStack.length; i++){ + widget = registry.byId(newStack[i]); + if(widget){ + widget.set("focused", true); + if(widget._focusManager == this){ + widget._onFocus(by); + } + this.emit("widget-focus", widget, by); + } + } + }, + + focus: function(node){ + // summary: + // Focus the specified node, suppressing errors if they occur + if(node){ + try{ node.focus(); }catch(e){/*quiet*/} + } + } + }); + + var singleton = new FocusManager(); + + // register top window and all the iframes it contains + ready(function(){ + var handle = singleton.registerWin(win.doc.parentWindow || win.doc.defaultView); + if(has("ie")){ + unload.addOnWindowUnload(function(){ + handle.remove(); + handle = null; + }) + } + }); + + // Setup dijit.focus as a pointer to the singleton but also (for backwards compatibility) + // as a function to set focus. + dijit.focus = function(node){ + singleton.focus(node); // indirection here allows dijit/_base/focus.js to override behavior + }; + for(var attr in singleton){ + if(!/^_/.test(attr)){ + dijit.focus[attr] = typeof singleton[attr] == "function" ? lang.hitch(singleton, attr) : singleton[attr]; + } + } + singleton.watch(function(attr, oldVal, newVal){ + dijit.focus[attr] = newVal; + }); + + return singleton; +}); + +}, +'dojox/grid/util':function(){ +define("dojox/grid/util", [ + "../main", + "dojo/_base/lang", + "dojo/dom" +], function(dojox, lang, dom){ + +// summary: grid utility library + var dgu = lang.getObject("grid.util", true, dojox); + + dgu.na = '...'; + dgu.rowIndexTag = "gridRowIndex"; + dgu.gridViewTag = "gridView"; + + + dgu.fire = function(ob, ev, args){ + var fn = ob && ev && ob[ev]; + return fn && (args ? fn.apply(ob, args) : ob[ev]()); + }; + + dgu.setStyleHeightPx = function(inElement, inHeight){ + if(inHeight >= 0){ + var s = inElement.style; + var v = inHeight + 'px'; + if(inElement && s['height'] != v){ + s['height'] = v; + } + } + }; + + dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ]; + + dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ]; + + dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){ + var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents)); + for (var i=0, l=evts.length; i<l; i++){ + inObject.connect(inNode, 'on' + evts[i], inMethod); + } + }; + + dgu.removeNode = function(inNode){ + inNode = dom.byId(inNode); + inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode); + return inNode; + }; + + dgu.arrayCompare = function(inA, inB){ + for(var i=0,l=inA.length; i<l; i++){ + if(inA[i] != inB[i]){return false;} + } + return (inA.length == inB.length); + }; + + dgu.arrayInsert = function(inArray, inIndex, inValue){ + if(inArray.length <= inIndex){ + inArray[inIndex] = inValue; + }else{ + inArray.splice(inIndex, 0, inValue); + } + }; + + dgu.arrayRemove = function(inArray, inIndex){ + inArray.splice(inIndex, 1); + }; + + dgu.arraySwap = function(inArray, inI, inJ){ + var cache = inArray[inI]; + inArray[inI] = inArray[inJ]; + inArray[inJ] = cache; + }; + + return dojox.grid.util; + +}); +}, +'url:dijit/templates/MenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n", +'dijit/main':function(){ +define("dijit/main", [ + "dojo/_base/kernel" +], function(dojo){ + // module: + // dijit + // summary: + // The dijit package main module + + return dojo.dijit; +}); + +}, +'dojo/date/stamp':function(){ +define(["../_base/kernel", "../_base/lang", "../_base/array"], function(dojo, lang, array) { + // module: + // dojo/date/stamp + // summary: + // TODOC + +lang.getObject("date.stamp", true, dojo); + +// Methods to convert dates to or from a wire (string) format using well-known conventions + +dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){ + // summary: + // Returns a Date object given a string formatted according to a subset of the ISO-8601 standard. + // + // description: + // Accepts a string formatted according to a profile of ISO8601 as defined by + // [RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed. + // Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime) + // The following combinations are valid: + // + // * dates only + // | * yyyy + // | * yyyy-MM + // | * yyyy-MM-dd + // * times only, with an optional time zone appended + // | * THH:mm + // | * THH:mm:ss + // | * THH:mm:ss.SSS + // * and "datetimes" which could be any combination of the above + // + // timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm + // Assumes the local time zone if not specified. Does not validate. Improperly formatted + // input may return null. Arguments which are out of bounds will be handled + // by the Date constructor (e.g. January 32nd typically gets resolved to February 1st) + // Only years between 100 and 9999 are supported. + // + // formattedString: + // A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00 + // + // defaultTime: + // Used for defaults for fields omitted in the formattedString. + // Uses 1970-01-01T00:00:00.0Z by default. + + if(!dojo.date.stamp._isoRegExp){ + dojo.date.stamp._isoRegExp = +//TODO: could be more restrictive and check for 00-59, etc. + /^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/; + } + + var match = dojo.date.stamp._isoRegExp.exec(formattedString), + result = null; + + if(match){ + match.shift(); + if(match[1]){match[1]--;} // Javascript Date months are 0-based + if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds + + if(defaultTime){ + // mix in defaultTime. Relatively expensive, so use || operators for the fast path of defaultTime === 0 + defaultTime = new Date(defaultTime); + array.forEach(array.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){ + return defaultTime["get" + prop](); + }), function(value, index){ + match[index] = match[index] || value; + }); + } + result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0); //TODO: UTC defaults + if(match[0] < 100){ + result.setFullYear(match[0] || 1970); + } + + var offset = 0, + zoneSign = match[7] && match[7].charAt(0); + if(zoneSign != 'Z'){ + offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0); + if(zoneSign != '-'){ offset *= -1; } + } + if(zoneSign){ + offset -= result.getTimezoneOffset(); + } + if(offset){ + result.setTime(result.getTime() + offset * 60000); + } + } + + return result; // Date or null +}; + +/*===== + dojo.date.stamp.__Options = function(){ + // selector: String + // "date" or "time" for partial formatting of the Date object. + // Both date and time will be formatted by default. + // zulu: Boolean + // if true, UTC/GMT is used for a timezone + // milliseconds: Boolean + // if true, output milliseconds + this.selector = selector; + this.zulu = zulu; + this.milliseconds = milliseconds; + } +=====*/ + +dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){ + // summary: + // Format a Date object as a string according a subset of the ISO-8601 standard + // + // description: + // When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt) + // The local time zone is included as an offset from GMT, except when selector=='time' (time without a date) + // Does not check bounds. Only years between 100 and 9999 are supported. + // + // dateObject: + // A Date object + + var _ = function(n){ return (n < 10) ? "0" + n : n; }; + options = options || {}; + var formattedDate = [], + getter = options.zulu ? "getUTC" : "get", + date = ""; + if(options.selector != "time"){ + var year = dateObject[getter+"FullYear"](); + date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-'); + } + formattedDate.push(date); + if(options.selector != "date"){ + var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':'); + var millis = dateObject[getter+"Milliseconds"](); + if(options.milliseconds){ + time += "."+ (millis < 100 ? "0" : "") + _(millis); + } + if(options.zulu){ + time += "Z"; + }else if(options.selector != "time"){ + var timezoneOffset = dateObject.getTimezoneOffset(); + var absOffset = Math.abs(timezoneOffset); + time += (timezoneOffset > 0 ? "-" : "+") + + _(Math.floor(absOffset/60)) + ":" + _(absOffset%60); + } + formattedDate.push(time); + } + return formattedDate.join('T'); // String +}; + +return dojo.date.stamp; +}); + +}, +'url:dojox/grid/resources/View.html':"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n", +'dojox/grid/_FocusManager':function(){ +define("dojox/grid/_FocusManager", [ + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/event", + "dojo/_base/sniff", + "dojo/query", + "./util", + "dojo/_base/html" +], function(array, lang, declare, connect, event, has, query, util, html){ + +// focus management +return declare("dojox.grid._FocusManager", null, { + // summary: + // Controls grid cell focus. Owned by grid and used internally for focusing. + // Note: grid cell actually receives keyboard input only when cell is being edited. + constructor: function(inGrid){ + this.grid = inGrid; + this.cell = null; + this.rowIndex = -1; + this._connects = []; + this._headerConnects = []; + this.headerMenu = this.grid.headerMenu; + this._connects.push(connect.connect(this.grid.domNode, "onfocus", this, "doFocus")); + this._connects.push(connect.connect(this.grid.domNode, "onblur", this, "doBlur")); + this._connects.push(connect.connect(this.grid.domNode, "mousedown", this, "_mouseDown")); + this._connects.push(connect.connect(this.grid.domNode, "mouseup", this, "_mouseUp")); + this._connects.push(connect.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu")); + this._connects.push(connect.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus")); + this._connects.push(connect.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur")); + this._connects.push(connect.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus")); + this._connects.push(connect.connect(this.grid,"postrender", this, "_delayedHeaderFocus")); + }, + destroy: function(){ + array.forEach(this._connects, connect.disconnect); + array.forEach(this._headerConnects, connect.disconnect); + delete this.grid; + delete this.cell; + }, + _colHeadNode: null, + _colHeadFocusIdx: null, + _contextMenuBindNode: null, + tabbingOut: false, + focusClass: "dojoxGridCellFocus", + focusView: null, + initFocusView: function(){ + this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0]; + this._initColumnHeaders(); + }, + isFocusCell: function(inCell, inRowIndex){ + // summary: + // states if the given cell is focused + // inCell: object + // grid cell object + // inRowIndex: int + // grid row index + // returns: + // true of the given grid cell is focused + return (this.cell == inCell) && (this.rowIndex == inRowIndex); + }, + isLastFocusCell: function(){ + if(this.cell){ + return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1); + } + return false; + }, + isFirstFocusCell: function(){ + if(this.cell){ + return (this.rowIndex === 0) && (this.cell.index === 0); + } + return false; + }, + isNoFocusCell: function(){ + return (this.rowIndex < 0) || !this.cell; + }, + isNavHeader: function(){ + // summary: + // states whether currently navigating among column headers. + // returns: + // true if focus is on a column header; false otherwise. + return (!!this._colHeadNode); + }, + getHeaderIndex: function(){ + // summary: + // if one of the column headers currently has focus, return its index. + // returns: + // index of the focused column header, or -1 if none have focus. + if(this._colHeadNode){ + return array.indexOf(this._findHeaderCells(), this._colHeadNode); + }else{ + return -1; + } + }, + _focusifyCellNode: function(inBork){ + var n = this.cell && this.cell.getNode(this.rowIndex); + if(n){ + html.toggleClass(n, this.focusClass, inBork); + if(inBork){ + var sl = this.scrollIntoView(); + try{ + if(!this.grid.edit.isEditing()){ + util.fire(n, "focus"); + if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; } + } + }catch(e){} + } + } + }, + _delayedCellFocus: function(){ + if(this.isNavHeader()||!this.grid.focused){ + return; + } + var n = this.cell && this.cell.getNode(this.rowIndex); + if(n){ + try{ + if(!this.grid.edit.isEditing()){ + html.toggleClass(n, this.focusClass, true); + if(this._colHeadNode){ + this.blurHeader(); + } + util.fire(n, "focus"); + } + } + catch(e){} + } + }, + _delayedHeaderFocus: function(){ + if(this.isNavHeader()){ + this.focusHeader(); + this.grid.domNode.focus(); + } + }, + _initColumnHeaders: function(){ + array.forEach(this._headerConnects, connect.disconnect); + this._headerConnects = []; + var headers = this._findHeaderCells(); + for(var i = 0; i < headers.length; i++){ + this._headerConnects.push(connect.connect(headers[i], "onfocus", this, "doColHeaderFocus")); + this._headerConnects.push(connect.connect(headers[i], "onblur", this, "doColHeaderBlur")); + } + }, + _findHeaderCells: function(){ + // This should be a one liner: + // query("th[tabindex=-1]", this.grid.viewsHeaderNode); + // But there is a bug in query() for IE -- see trac #7037. + var allHeads = query("th", this.grid.viewsHeaderNode); + var headers = []; + for (var i = 0; i < allHeads.length; i++){ + var aHead = allHeads[i]; + var hasTabIdx = html.hasAttr(aHead, "tabIndex"); + var tabindex = html.attr(aHead, "tabIndex"); + if (hasTabIdx && tabindex < 0) { + headers.push(aHead); + } + } + return headers; + }, + _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){ + //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx); + this.grid.domNode.setAttribute("aria-activedescendant",colHeaderNode.id); + if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){ + html.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false); + } + html.toggleClass(colHeaderNode,this.focusClass, true); + this._colHeadNode = colHeaderNode; + this._colHeadFocusIdx = colFocusIdx; + this._scrollHeader(this._colHeadFocusIdx); + }, + scrollIntoView: function(){ + var info = (this.cell ? this._scrollInfo(this.cell) : null); + if(!info || !info.s){ + return null; + } + var rt = this.grid.scroller.findScrollTop(this.rowIndex); + // place cell within horizontal view + if(info.n && info.sr){ + if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){ + info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w; + }else if(info.n.offsetLeft < info.sr.l){ + info.s.scrollLeft = info.n.offsetLeft; + } + } + // place cell within vertical view + if(info.r && info.sr){ + if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){ + this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h); + }else if(rt < info.sr.t){ + this.grid.setScrollTop(rt); + } + } + + return info.s.scrollLeft; + }, + _scrollInfo: function(cell, domNode){ + if(cell){ + var cl = cell, + sbn = cl.view.scrollboxNode, + sbnr = { + w: sbn.clientWidth, + l: sbn.scrollLeft, + t: sbn.scrollTop, + h: sbn.clientHeight + }, + rn = cl.view.getRowNode(this.rowIndex); + return { + c: cl, + s: sbn, + sr: sbnr, + n: (domNode ? domNode : cell.getNode(this.rowIndex)), + r: rn + }; + } + return null; + }, + _scrollHeader: function(currentIdx){ + var info = null; + if(this._colHeadNode){ + var cell = this.grid.getCell(currentIdx); + if(!cell){ return; } + info = this._scrollInfo(cell, cell.getNode(0)); + } + if(info && info.s && info.sr && info.n){ + // scroll horizontally as needed. + var scroll = info.sr.l + info.sr.w; + if(info.n.offsetLeft + info.n.offsetWidth > scroll){ + info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w; + }else if(info.n.offsetLeft < info.sr.l){ + info.s.scrollLeft = info.n.offsetLeft; + }else if(has("ie") <= 7 && cell && cell.view.headerNode){ + // Trac 7158: scroll dojoxGridHeader for IE7 and lower + cell.view.headerNode.scrollLeft = info.s.scrollLeft; + } + } + }, + _isHeaderHidden: function(){ + // summary: + // determine if the grid headers are hidden + // relies on documented technique of setting .dojoxGridHeader { display:none; } + // returns: Boolean + // true if headers are hidden + // false if headers are not hidden + + var curView = this.focusView; + if (!curView){ + // find one so we can determine if headers are hidden + // there is no focusView after adding items to empty grid (test_data_grid_empty.html) + for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) { + if(cView.headerNode ){ + curView=cView; + break; + } + } + } + return (curView && html.getComputedStyle(curView.headerNode).display == "none"); + }, + colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px + var headers = this._findHeaderCells(); + var view = this.focusView; + if (!view) { + for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) { + // find first view with a tableMap in order to work with empty grid + if(cView.header.tableMap.map ){ + view=cView; + break; + } + } + } + var curHeader = headers[colIdx]; + if (!view || (colIdx == headers.length-1 && colIdx === 0)){ + return; // can't adjust single col. grid + } + view.content.baseDecorateEvent(e); + // need to adjust event with header cell info since focus is no longer on header cell + e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode); + e.cellIndex = view.content.getCellNodeIndex(e.cellNode); + e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null); + if (view.header.canResize(e)){ + var deltaObj = { + l: delta + }; + var drag = view.header.colResizeSetup(e,false); + view.header.doResizeColumn(drag, null, deltaObj); + view.update(); + } + }, + styleRow: function(inRow){ + return; + }, + setFocusIndex: function(inRowIndex, inCellIndex){ + // summary: + // focuses the given grid cell + // inRowIndex: int + // grid row index + // inCellIndex: int + // grid cell index + this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex); + }, + setFocusCell: function(inCell, inRowIndex){ + // summary: + // focuses the given grid cell + // inCell: object + // grid cell object + // inRowIndex: int + // grid row index + if(inCell && !this.isFocusCell(inCell, inRowIndex)){ + this.tabbingOut = false; + if (this._colHeadNode){ + this.blurHeader(); + } + this._colHeadNode = this._colHeadFocusIdx = null; + this.focusGridView(); + this._focusifyCellNode(false); + this.cell = inCell; + this.rowIndex = inRowIndex; + this._focusifyCellNode(true); + } + // even if this cell isFocusCell, the document focus may need to be rejiggered + // call opera on delay to prevent keypress from altering focus + if(has("opera")){ + setTimeout(lang.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1); + }else{ + this.grid.onCellFocus(this.cell, this.rowIndex); + } + }, + next: function(){ + // summary: + // focus next grid cell + if(this.cell){ + var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1; + if(col > cc){ + col = 0; + row++; + } + if(row > rc){ + col = cc; + row = rc; + } + if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells + var nextCell = this.grid.getCell(col); + if (!this.isLastFocusCell() && (!nextCell.editable || + this.grid.canEdit && !this.grid.canEdit(nextCell, row))){ + this.cell=nextCell; + this.rowIndex=row; + this.next(); + return; + } + } + this.setFocusIndex(row, col); + } + }, + previous: function(){ + // summary: + // focus previous grid cell + if(this.cell){ + var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1; + if(col < 0){ + col = this.grid.layout.cellCount-1; + row--; + } + if(row < 0){ + row = 0; + col = 0; + } + if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells + var prevCell = this.grid.getCell(col); + if (!this.isFirstFocusCell() && !prevCell.editable){ + this.cell=prevCell; + this.rowIndex=row; + this.previous(); + return; + } + } + this.setFocusIndex(row, col); + } + }, + move: function(inRowDelta, inColDelta) { + // summary: + // focus grid cell or simulate focus to column header based on position relative to current focus + // inRowDelta: int + // vertical distance from current focus + // inColDelta: int + // horizontal distance from current focus + + var colDir = inColDelta < 0 ? -1 : 1; + // Handle column headers. + if(this.isNavHeader()){ + var headers = this._findHeaderCells(); + var savedIdx = currentIdx = array.indexOf(headers, this._colHeadNode); + currentIdx += inColDelta; + while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){ + // skip over hidden column headers + currentIdx += colDir; + } + if((currentIdx >= 0) && (currentIdx < headers.length)){ + this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx); + } + }else{ + if(this.cell){ + // Handle grid proper. + var sc = this.grid.scroller, + r = this.rowIndex, + rc = this.grid.rowCount-1, + row = Math.min(rc, Math.max(0, r+inRowDelta)); + if(inRowDelta){ + if(inRowDelta>0){ + if(row > sc.getLastPageRow(sc.page)){ + //need to load additional data, let scroller do that + this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r)); + } + }else if(inRowDelta<0){ + if(row <= sc.getPageRow(sc.page)){ + //need to load additional data, let scroller do that + this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row)); + } + } + } + var cc = this.grid.layout.cellCount-1, + i = this.cell.index, + col = Math.min(cc, Math.max(0, i+inColDelta)); + var cell = this.grid.getCell(col); + while(col>=0 && col < cc && cell && cell.hidden === true){ + // skip hidden cells + col += colDir; + cell = this.grid.getCell(col); + } + if (!cell || cell.hidden === true){ + // don't change col if would move to hidden + col = i; + } + //skip hidden row|cell + var n = cell.getNode(row); + if(!n && inRowDelta){ + if((row + inRowDelta) >= 0 && (row + inRowDelta) <= rc){ + this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta); + } + return; + }else if((!n || html.style(n, "display") === "none") && inColDelta){ + if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){ + this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta); + } + return; + } + this.setFocusIndex(row, col); + if(inRowDelta){ + this.grid.updateRow(r); + } + } + } + }, + previousKey: function(e){ + if(this.grid.edit.isEditing()){ + event.stop(e); + this.previous(); + }else if(!this.isNavHeader() && !this._isHeaderHidden()) { + this.grid.domNode.focus(); // will call doFocus and set focus into header. + event.stop(e); + }else{ + this.tabOut(this.grid.domNode); + if (this._colHeadFocusIdx != null) { // clear grid header focus + html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false); + this._colHeadFocusIdx = null; + } + this._focusifyCellNode(false); + } + }, + nextKey: function(e) { + var isEmpty = (this.grid.rowCount === 0); + if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){ + this.focusHeader(); + event.stop(e); + }else if(this.isNavHeader()){ + // if tabbing from col header, then go to grid proper. + this.blurHeader(); + if(!this.findAndFocusGridCell()){ + this.tabOut(this.grid.lastFocusNode); + } + this._colHeadNode = this._colHeadFocusIdx= null; + }else if(this.grid.edit.isEditing()){ + event.stop(e); + this.next(); + }else{ + this.tabOut(this.grid.lastFocusNode); + } + }, + tabOut: function(inFocusNode){ + this.tabbingOut = true; + inFocusNode.focus(); + }, + focusGridView: function(){ + util.fire(this.focusView, "focus"); + }, + focusGrid: function(inSkipFocusCell){ + this.focusGridView(); + this._focusifyCellNode(true); + }, + findAndFocusGridCell: function(){ + // summary: + // find the first focusable grid cell + // returns: Boolean + // true if focus was set to a cell + // false if no cell found to set focus onto + + var didFocus = true; + var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0 + if (this.isNoFocusCell() && !isEmpty){ + var cellIdx = 0; + var cell = this.grid.getCell(cellIdx); + if (cell.hidden) { + // if first cell isn't visible, use _colHeadFocusIdx + // could also use a while loop to find first visible cell - not sure that is worth it + cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0; + } + this.setFocusIndex(0, cellIdx); + } + else if (this.cell && !isEmpty){ + if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){ + // if rowNode for current index is undefined (likely as a result of a sort and because of #7304) + // scroll to that row + this.grid.scrollToRow(this.rowIndex); + } + this.focusGrid(); + }else { + didFocus = false; + } + this._colHeadNode = this._colHeadFocusIdx= null; + return didFocus; + }, + focusHeader: function(){ + var headerNodes = this._findHeaderCells(); + var saveColHeadFocusIdx = this._colHeadFocusIdx; + if (this._isHeaderHidden()){ + // grid header is hidden, focus a cell + this.findAndFocusGridCell(); + } + else if (!this._colHeadFocusIdx) { + if (this.isNoFocusCell()) { + this._colHeadFocusIdx = 0; + } + else { + this._colHeadFocusIdx = this.cell.index; + } + } + this._colHeadNode = headerNodes[this._colHeadFocusIdx]; + while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length && + this._colHeadNode.style.display == "none"){ + // skip over hidden column headers + this._colHeadFocusIdx++; + this._colHeadNode = headerNodes[this._colHeadFocusIdx]; + } + if(this._colHeadNode && this._colHeadNode.style.display != "none"){ + // Column header cells know longer receive actual focus. So, for keyboard invocation of + // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode. + // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset + // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483 + if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){ + this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode); + this.headerMenu.bindDomNode(this.grid.domNode); + this._contextMenuBindNode = this.grid.domNode; + } + this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx); + this._scrollHeader(this._colHeadFocusIdx); + this._focusifyCellNode(false); + }else { + // all col head nodes are hidden - focus the grid + this.findAndFocusGridCell(); + } + }, + blurHeader: function(){ + html.removeClass(this._colHeadNode, this.focusClass); + html.removeAttr(this.grid.domNode,"aria-activedescendant"); + // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader) + if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) { + var viewsHeader = this.grid.viewsHeaderNode; + this.headerMenu.unBindDomNode(this.grid.domNode); + this.headerMenu.bindDomNode(viewsHeader); + this._contextMenuBindNode = viewsHeader; + } + }, + doFocus: function(e){ + // trap focus only for grid dom node + if(e && e.target != e.currentTarget){ + event.stop(e); + return; + } + // don't change focus if clicking on scroller bar + if(this._clickFocus){ + return; + } + // do not focus for scrolling if grid is about to blur + if(!this.tabbingOut){ + this.focusHeader(); + } + this.tabbingOut = false; + event.stop(e); + }, + doBlur: function(e){ + event.stop(e); // FF2 + }, + doContextMenu: function(e){ + //stop contextMenu event if no header Menu to prevent default/browser contextMenu + if (!this.headerMenu){ + event.stop(e); + } + }, + doLastNodeFocus: function(e){ + if (this.tabbingOut){ + this._focusifyCellNode(false); + }else if(this.grid.rowCount >0){ + if (this.isNoFocusCell()){ + this.setFocusIndex(0,0); + } + this._focusifyCellNode(true); + }else { + this.focusHeader(); + } + this.tabbingOut = false; + event.stop(e); // FF2 + }, + doLastNodeBlur: function(e){ + event.stop(e); // FF2 + }, + doColHeaderFocus: function(e){ + this._setActiveColHeader(e.target,html.attr(e.target, "idx"),this._colHeadFocusIdx); + this._scrollHeader(this.getHeaderIndex()); + event.stop(e); + }, + doColHeaderBlur: function(e){ + html.toggleClass(e.target, this.focusClass, false); + }, + _mouseDown: function(e){ + // a flag indicating grid is being focused by clicking + this._clickFocus = dojo.some(this.grid.views.views, function(v){ + return v.scrollboxNode === e.target; + }); + }, + _mouseUp: function(e){ + this._clickFocus = false; + } +}); +}); +}, +'dijit/MenuItem':function(){ +require({cache:{ +'url:dijit/templates/MenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n"}}); +define("dijit/MenuItem", [ + "dojo/_base/declare", // declare + "dojo/dom", // dom.setSelectable + "dojo/dom-attr", // domAttr.set + "dojo/dom-class", // domClass.toggle + "dojo/_base/event", // event.stop + "dojo/_base/kernel", // kernel.deprecated + "dojo/_base/sniff", // has("ie") + "./_Widget", + "./_TemplatedMixin", + "./_Contained", + "./_CssStateMixin", + "dojo/text!./templates/MenuItem.html" +], function(declare, dom, domAttr, domClass, event, kernel, has, + _Widget, _TemplatedMixin, _Contained, _CssStateMixin, template){ + +/*===== + var _Widget = dijit._Widget; + var _TemplatedMixin = dijit._TemplatedMixin; + var _Contained = dijit._Contained; + var _CssStateMixin = dijit._CssStateMixin; +=====*/ + + // module: + // dijit/MenuItem + // summary: + // A line item in a Menu Widget + + + return declare("dijit.MenuItem", + [_Widget, _TemplatedMixin, _Contained, _CssStateMixin], + { + // summary: + // A line item in a Menu Widget + + // Make 3 columns + // icon, label, and expand arrow (BiDi-dependent) indicating sub-menu + templateString: template, + + baseClass: "dijitMenuItem", + + // label: String + // Menu text + label: '', + _setLabelAttr: { node: "containerNode", type: "innerHTML" }, + + // iconClass: String + // Class to apply to DOMNode to make it display an icon. + iconClass: "dijitNoIcon", + _setIconClassAttr: { node: "iconNode", type: "class" }, + + // accelKey: String + // Text for the accelerator (shortcut) key combination. + // Note that although Menu can display accelerator keys there + // is no infrastructure to actually catch and execute these + // accelerators. + accelKey: "", + + // disabled: Boolean + // If true, the menu item is disabled. + // If false, the menu item is enabled. + disabled: false, + + _fillContent: function(/*DomNode*/ source){ + // If button label is specified as srcNodeRef.innerHTML rather than + // this.params.label, handle it here. + if(source && !("label" in this.params)){ + this.set('label', source.innerHTML); + } + }, + + buildRendering: function(){ + this.inherited(arguments); + var label = this.id+"_text"; + domAttr.set(this.containerNode, "id", label); + if(this.accelKeyNode){ + domAttr.set(this.accelKeyNode, "id", this.id + "_accel"); + label += " " + this.id + "_accel"; + } + this.domNode.setAttribute("aria-labelledby", label); + dom.setSelectable(this.domNode, false); + }, + + _onHover: function(){ + // summary: + // Handler when mouse is moved onto menu item + // tags: + // protected + this.getParent().onItemHover(this); + }, + + _onUnhover: function(){ + // summary: + // Handler when mouse is moved off of menu item, + // possibly to a child menu, or maybe to a sibling + // menuitem or somewhere else entirely. + // tags: + // protected + + // if we are unhovering the currently selected item + // then unselect it + this.getParent().onItemUnhover(this); + + // When menu is hidden (collapsed) due to clicking a MenuItem and having it execute, + // FF and IE don't generate an onmouseout event for the MenuItem. + // So, help out _CssStateMixin in this case. + this._set("hovering", false); + }, + + _onClick: function(evt){ + // summary: + // Internal handler for click events on MenuItem. + // tags: + // private + this.getParent().onItemClick(this, evt); + event.stop(evt); + }, + + onClick: function(/*Event*/){ + // summary: + // User defined function to handle clicks + // tags: + // callback + }, + + focus: function(){ + // summary: + // Focus on this MenuItem + try{ + if(has("ie") == 8){ + // needed for IE8 which won't scroll TR tags into view on focus yet calling scrollIntoView creates flicker (#10275) + this.containerNode.focus(); + } + this.focusNode.focus(); + }catch(e){ + // this throws on IE (at least) in some scenarios + } + }, + + _onFocus: function(){ + // summary: + // This is called by the focus manager when focus + // goes to this MenuItem or a child menu. + // tags: + // protected + this._setSelected(true); + this.getParent()._onItemFocus(this); + + this.inherited(arguments); + }, + + _setSelected: function(selected){ + // summary: + // Indicate that this node is the currently selected one + // tags: + // private + + /*** + * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem. + * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu. + * That's not supposed to happen, but the problem is: + * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent + * points to the parent Menu, bypassing the parent MenuItem... thus the + * MenuItem is not in the chain of active widgets and gets a premature call to + * _onBlur() + */ + + domClass.toggle(this.domNode, "dijitMenuItemSelected", selected); + }, + + setLabel: function(/*String*/ content){ + // summary: + // Deprecated. Use set('label', ...) instead. + // tags: + // deprecated + kernel.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.", "", "2.0"); + this.set("label", content); + }, + + setDisabled: function(/*Boolean*/ disabled){ + // summary: + // Deprecated. Use set('disabled', bool) instead. + // tags: + // deprecated + kernel.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.", "", "2.0"); + this.set('disabled', disabled); + }, + _setDisabledAttr: function(/*Boolean*/ value){ + // summary: + // Hook for attr('disabled', ...) to work. + // Enable or disable this menu item. + + this.focusNode.setAttribute('aria-disabled', value ? 'true' : 'false'); + this._set("disabled", value); + }, + _setAccelKeyAttr: function(/*String*/ value){ + // summary: + // Hook for attr('accelKey', ...) to work. + // Set accelKey on this menu item. + + this.accelKeyNode.style.display=value?"":"none"; + this.accelKeyNode.innerHTML=value; + //have to use colSpan to make it work in IE + domAttr.set(this.containerNode,'colSpan',value?"1":"2"); + + this._set("accelKey", value); + } + }); +}); + +}, +'dijit/_TemplatedMixin':function(){ +define("dijit/_TemplatedMixin", [ + "dojo/_base/lang", // lang.getObject + "dojo/touch", + "./_WidgetBase", + "dojo/string", // string.substitute string.trim + "dojo/cache", // dojo.cache + "dojo/_base/array", // array.forEach + "dojo/_base/declare", // declare + "dojo/dom-construct", // domConstruct.destroy, domConstruct.toDom + "dojo/_base/sniff", // has("ie") + "dojo/_base/unload", // unload.addOnWindowUnload + "dojo/_base/window" // win.doc +], function(lang, touch, _WidgetBase, string, cache, array, declare, domConstruct, has, unload, win) { + +/*===== + var _WidgetBase = dijit._WidgetBase; +=====*/ + + // module: + // dijit/_TemplatedMixin + // summary: + // Mixin for widgets that are instantiated from a template + + var _TemplatedMixin = declare("dijit._TemplatedMixin", null, { + // summary: + // Mixin for widgets that are instantiated from a template + + // templateString: [protected] String + // A string that represents the widget template. + // Use in conjunction with dojo.cache() to load from a file. + templateString: null, + + // templatePath: [protected deprecated] String + // Path to template (HTML file) for this widget relative to dojo.baseUrl. + // Deprecated: use templateString with require([... "dojo/text!..."], ...) instead + templatePath: null, + + // skipNodeCache: [protected] Boolean + // If using a cached widget template nodes poses issues for a + // particular widget class, it can set this property to ensure + // that its template is always re-built from a string + _skipNodeCache: false, + + // _earlyTemplatedStartup: Boolean + // A fallback to preserve the 1.0 - 1.3 behavior of children in + // templates having their startup called before the parent widget + // fires postCreate. Defaults to 'false', causing child widgets to + // have their .startup() called immediately before a parent widget + // .startup(), but always after the parent .postCreate(). Set to + // 'true' to re-enable to previous, arguably broken, behavior. + _earlyTemplatedStartup: false, + +/*===== + // _attachPoints: [private] String[] + // List of widget attribute names associated with data-dojo-attach-point=... in the + // template, ex: ["containerNode", "labelNode"] + _attachPoints: [], + =====*/ + +/*===== + // _attachEvents: [private] Handle[] + // List of connections associated with data-dojo-attach-event=... in the + // template + _attachEvents: [], + =====*/ + + constructor: function(){ + this._attachPoints = []; + this._attachEvents = []; + }, + + _stringRepl: function(tmpl){ + // summary: + // Does substitution of ${foo} type properties in template string + // tags: + // private + var className = this.declaredClass, _this = this; + // Cache contains a string because we need to do property replacement + // do the property replacement + return string.substitute(tmpl, this, function(value, key){ + if(key.charAt(0) == '!'){ value = lang.getObject(key.substr(1), false, _this); } + if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide + if(value == null){ return ""; } + + // Substitution keys beginning with ! will skip the transform step, + // in case a user wishes to insert unescaped markup, e.g. ${!foo} + return key.charAt(0) == "!" ? value : + // Safer substitution, see heading "Attribute values" in + // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2 + value.toString().replace(/"/g,"""); //TODO: add &? use encodeXML method? + }, this); + }, + + buildRendering: function(){ + // summary: + // Construct the UI for this widget from a template, setting this.domNode. + // tags: + // protected + + if(!this.templateString){ + this.templateString = cache(this.templatePath, {sanitize: true}); + } + + // Lookup cached version of template, and download to cache if it + // isn't there already. Returns either a DomNode or a string, depending on + // whether or not the template contains ${foo} replacement parameters. + var cached = _TemplatedMixin.getCachedTemplate(this.templateString, this._skipNodeCache); + + var node; + if(lang.isString(cached)){ + node = domConstruct.toDom(this._stringRepl(cached)); + if(node.nodeType != 1){ + // Flag common problems such as templates with multiple top level nodes (nodeType == 11) + throw new Error("Invalid template: " + cached); + } + }else{ + // if it's a node, all we have to do is clone it + node = cached.cloneNode(true); + } + + this.domNode = node; + + // Call down to _Widget.buildRendering() to get base classes assigned + // TODO: change the baseClass assignment to _setBaseClassAttr + this.inherited(arguments); + + // recurse through the node, looking for, and attaching to, our + // attachment points and events, which should be defined on the template node. + this._attachTemplateNodes(node, function(n,p){ return n.getAttribute(p); }); + + this._beforeFillContent(); // hook for _WidgetsInTemplateMixin + + this._fillContent(this.srcNodeRef); + }, + + _beforeFillContent: function(){ + }, + + _fillContent: function(/*DomNode*/ source){ + // summary: + // Relocate source contents to templated container node. + // this.containerNode must be able to receive children, or exceptions will be thrown. + // tags: + // protected + var dest = this.containerNode; + if(source && dest){ + while(source.hasChildNodes()){ + dest.appendChild(source.firstChild); + } + } + }, + + _attachTemplateNodes: function(rootNode, getAttrFunc){ + // summary: + // Iterate through the template and attach functions and nodes accordingly. + // Alternately, if rootNode is an array of widgets, then will process data-dojo-attach-point + // etc. for those widgets. + // description: + // Map widget properties and functions to the handlers specified in + // the dom node and it's descendants. This function iterates over all + // nodes and looks for these properties: + // * dojoAttachPoint/data-dojo-attach-point + // * dojoAttachEvent/data-dojo-attach-event + // rootNode: DomNode|Widget[] + // the node to search for properties. All children will be searched. + // getAttrFunc: Function + // a function which will be used to obtain property for a given + // DomNode/Widget + // tags: + // private + + var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*")); + var x = lang.isArray(rootNode) ? 0 : -1; + for(; x<nodes.length; x++){ + var baseNode = (x == -1) ? rootNode : nodes[x]; + if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){ + continue; + } + // Process data-dojo-attach-point + var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point"); + if(attachPoint){ + var point, points = attachPoint.split(/\s*,\s*/); + while((point = points.shift())){ + if(lang.isArray(this[point])){ + this[point].push(baseNode); + }else{ + this[point]=baseNode; + } + this._attachPoints.push(point); + } + } + + // Process data-dojo-attach-event + var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event"); + if(attachEvent){ + // NOTE: we want to support attributes that have the form + // "domEvent: nativeEvent; ..." + var event, events = attachEvent.split(/\s*,\s*/); + var trim = lang.trim; + while((event = events.shift())){ + if(event){ + var thisFunc = null; + if(event.indexOf(":") != -1){ + // oh, if only JS had tuple assignment + var funcNameArr = event.split(":"); + event = trim(funcNameArr[0]); + thisFunc = trim(funcNameArr[1]); + }else{ + event = trim(event); + } + if(!thisFunc){ + thisFunc = event; + } + // Map "press", "move" and "release" to keys.touch, keys.move, keys.release + this._attachEvents.push(this.connect(baseNode, touch[event] || event, thisFunc)); + } + } + } + } + }, + + destroyRendering: function(){ + // Delete all attach points to prevent IE6 memory leaks. + array.forEach(this._attachPoints, function(point){ + delete this[point]; + }, this); + this._attachPoints = []; + + // And same for event handlers + array.forEach(this._attachEvents, this.disconnect, this); + this._attachEvents = []; + + this.inherited(arguments); + } + }); + + // key is templateString; object is either string or DOM tree + _TemplatedMixin._templateCache = {}; + + _TemplatedMixin.getCachedTemplate = function(templateString, alwaysUseString){ + // summary: + // Static method to get a template based on the templatePath or + // templateString key + // templateString: String + // The template + // alwaysUseString: Boolean + // Don't cache the DOM tree for this template, even if it doesn't have any variables + // returns: Mixed + // Either string (if there are ${} variables that need to be replaced) or just + // a DOM tree (if the node can be cloned directly) + + // is it already cached? + var tmplts = _TemplatedMixin._templateCache; + var key = templateString; + var cached = tmplts[key]; + if(cached){ + try{ + // if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value + if(!cached.ownerDocument || cached.ownerDocument == win.doc){ + // string or node of the same document + return cached; + } + }catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded + domConstruct.destroy(cached); + } + + templateString = string.trim(templateString); + + if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){ + // there are variables in the template so all we can do is cache the string + return (tmplts[key] = templateString); //String + }else{ + // there are no variables in the template so we can cache the DOM tree + var node = domConstruct.toDom(templateString); + if(node.nodeType != 1){ + throw new Error("Invalid template: " + templateString); + } + return (tmplts[key] = node); //Node + } + }; + + if(has("ie")){ + unload.addOnWindowUnload(function(){ + var cache = _TemplatedMixin._templateCache; + for(var key in cache){ + var value = cache[key]; + if(typeof value == "object"){ // value is either a string or a DOM node template + domConstruct.destroy(value); + } + delete cache[key]; + } + }); + } + + // These arguments can be specified for widgets which are used in templates. + // Since any widget can be specified as sub widgets in template, mix it + // into the base widget class. (This is a hack, but it's effective.) + lang.extend(_WidgetBase,{ + dojoAttachEvent: "", + dojoAttachPoint: "" + }); + + return _TemplatedMixin; +}); + +}, +'dojox/grid/_SelectionPreserver':function(){ +define("dojox/grid/_SelectionPreserver", [ + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/lang", + "dojo/_base/array" +], function(declare, connect, lang, array){ + +return declare("dojox.grid._SelectionPreserver", null, { + // summary: + // Preserve selections across various user actions. + // + // description: + // When this feature is turned on, Grid will try to preserve selections across actions, e.g. sorting, filtering etc. + // + // Precondition - Identifier(id) is required for store since id is the only way for differentiating row items. + // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click) + // + // example: + // | //To turn on this - please set 'keepSelection' attribute to true + // | <div dojoType="dojox.grid.DataGrid" keepSelection = true .../> + // | <div dojoType="dojox.grid.TreeGrid" keepSelection = true .../> + // | <div dojoType="dojox.grid.LazyTreeGrid" keepSelection = true .../> + + constructor: function(selection){ + this.selection = selection; + var grid = this.grid = selection.grid; + this.reset(); + this._connects = [ + connect.connect(grid, '_setStore', this, 'reset'), + connect.connect(grid, '_addItem', this, '_reSelectById'), + connect.connect(selection, 'addToSelection', lang.hitch(this, '_selectById', true)), + connect.connect(selection, 'deselect', lang.hitch(this, '_selectById', false)), + connect.connect(selection, 'deselectAll', this, 'reset') + ]; + }, + destroy: function(){ + this.reset(); + array.forEach(this._connects, connect.disconnect); + delete this._connects; + }, + reset: function(){ + this._selectedById = {}; + }, + _reSelectById: function(item, index){ + // summary: + // When some rows is fetched, determine whether it should be selected. + if(item && this.grid._hasIdentity){ + this.selection.selected[index] = this._selectedById[this.grid.store.getIdentity(item)]; + } + }, + _selectById: function(toSelect, inItemOrIndex){ + // summary: + // Record selected rows by ID. + if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; } + var item = inItemOrIndex, g = this.grid; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + var entry = g._by_idx[inItemOrIndex]; + item = entry && entry.item; + } + if(item){ + this._selectedById[g.store.getIdentity(item)] = !!toSelect; + } + return item; + } +}); +}); +}, +'dojo/window':function(){ +define(["./_base/lang", "./_base/sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style"], + function(lang, has, baseWindow, dom, geom, style) { + +// module: +// dojo/window +// summary: +// TODOC + +var window = lang.getObject("dojo.window", true); + +/*===== +dojo.window = { + // summary: + // TODO +}; +window = dojo.window; +=====*/ + +window.getBox = function(){ + // summary: + // Returns the dimensions and scroll position of the viewable area of a browser window + + var + scrollRoot = (baseWindow.doc.compatMode == 'BackCompat') ? baseWindow.body() : baseWindow.doc.documentElement, + // get scroll position + scroll = geom.docScroll(), // scrollRoot.scrollTop/Left should work + w, h; + + if(has("touch")){ // if(scrollbars not supported) + var uiWindow = baseWindow.doc.parentWindow || baseWindow.doc.defaultView; // use UI window, not dojo.global window. baseWindow.doc.parentWindow probably not needed since it's not defined for webkit + // on mobile, scrollRoot.clientHeight <= uiWindow.innerHeight <= scrollRoot.offsetHeight, return uiWindow.innerHeight + w = uiWindow.innerWidth || scrollRoot.clientWidth; // || scrollRoot.clientXXX probably never evaluated + h = uiWindow.innerHeight || scrollRoot.clientHeight; + }else{ + // on desktops, scrollRoot.clientHeight <= scrollRoot.offsetHeight <= uiWindow.innerHeight, return scrollRoot.clientHeight + // uiWindow.innerWidth/Height includes the scrollbar and cannot be used + w = scrollRoot.clientWidth; + h = scrollRoot.clientHeight; + } + return { + l: scroll.x, + t: scroll.y, + w: w, + h: h + }; +}; + +window.get = function(doc){ + // summary: + // Get window object associated with document doc + + // In some IE versions (at least 6.0), document.parentWindow does not return a + // reference to the real window object (maybe a copy), so we must fix it as well + // We use IE specific execScript to attach the real window reference to + // document._parentWindow for later use + if(has("ie") && window !== document.parentWindow){ + /* + In IE 6, only the variable "window" can be used to connect events (others + may be only copies). + */ + doc.parentWindow.execScript("document._parentWindow = window;", "Javascript"); + //to prevent memory leak, unset it after use + //another possibility is to add an onUnload handler which seems overkill to me (liucougar) + var win = doc._parentWindow; + doc._parentWindow = null; + return win; // Window + } + + return doc.parentWindow || doc.defaultView; // Window +}; + +window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){ + // summary: + // Scroll the passed node into view, if it is not already. + + // don't rely on node.scrollIntoView working just because the function is there + + try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method + node = dom.byId(node); + var doc = node.ownerDocument || baseWindow.doc, + body = doc.body || baseWindow.body(), + html = doc.documentElement || body.parentNode, + isIE = has("ie"), isWK = has("webkit"); + // if an untested browser, then use the native method + if((!(has("mozilla") || isIE || isWK || has("opera")) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){ + node.scrollIntoView(false); // short-circuit to native if possible + return; + } + var backCompat = doc.compatMode == 'BackCompat', + clientAreaRoot = (isIE >= 9 && node.ownerDocument.parentWindow.frameElement) + ? ((html.clientHeight > 0 && html.clientWidth > 0 && (body.clientHeight == 0 || body.clientWidth == 0 || body.clientHeight > html.clientHeight || body.clientWidth > html.clientWidth)) ? html : body) + : (backCompat ? body : html), + scrollRoot = isWK ? body : clientAreaRoot, + rootWidth = clientAreaRoot.clientWidth, + rootHeight = clientAreaRoot.clientHeight, + rtl = !geom.isBodyLtr(), + nodePos = pos || geom.position(node), + el = node.parentNode, + isFixed = function(el){ + return ((isIE <= 6 || (isIE && backCompat))? false : (style.get(el, 'position').toLowerCase() == "fixed")); + }; + if(isFixed(node)){ return; } // nothing to do + + while(el){ + if(el == body){ el = scrollRoot; } + var elPos = geom.position(el), + fixedPos = isFixed(el); + + if(el == scrollRoot){ + elPos.w = rootWidth; elPos.h = rootHeight; + if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x + if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0 + if(elPos.y < 0 || !isIE){ elPos.y = 0; } + }else{ + var pb = geom.getPadBorderExtents(el); + elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t; + var clientSize = el.clientWidth, + scrollBarSize = elPos.w - clientSize; + if(clientSize > 0 && scrollBarSize > 0){ + elPos.w = clientSize; + elPos.x += (rtl && (isIE || el.clientLeft > pb.l/*Chrome*/)) ? scrollBarSize : 0; + } + clientSize = el.clientHeight; + scrollBarSize = elPos.h - clientSize; + if(clientSize > 0 && scrollBarSize > 0){ + elPos.h = clientSize; + } + } + if(fixedPos){ // bounded by viewport, not parents + if(elPos.y < 0){ + elPos.h += elPos.y; elPos.y = 0; + } + if(elPos.x < 0){ + elPos.w += elPos.x; elPos.x = 0; + } + if(elPos.y + elPos.h > rootHeight){ + elPos.h = rootHeight - elPos.y; + } + if(elPos.x + elPos.w > rootWidth){ + elPos.w = rootWidth - elPos.x; + } + } + // calculate overflow in all 4 directions + var l = nodePos.x - elPos.x, // beyond left: < 0 + t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0 + r = l + nodePos.w - elPos.w, // beyond right: > 0 + bot = t + nodePos.h - elPos.h; // beyond bottom: > 0 + if(r * l > 0){ + var s = Math[l < 0? "max" : "min"](l, r); + if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9)){ s = -s; } + nodePos.x += el.scrollLeft; + el.scrollLeft += s; + nodePos.x -= el.scrollLeft; + } + if(bot * t > 0){ + nodePos.y += el.scrollTop; + el.scrollTop += Math[t < 0? "max" : "min"](t, bot); + nodePos.y -= el.scrollTop; + } + el = (el != scrollRoot) && !fixedPos && el.parentNode; + } + }catch(error){ + console.error('scrollIntoView: ' + error); + node.scrollIntoView(false); + } +}; + +return window; +}); + +}, +'dojox/grid/_Builder':function(){ +define("dojox/grid/_Builder", [ + "../main", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/window", + "dojo/_base/event", + "dojo/_base/sniff", + "dojo/_base/connect", + "dojo/dnd/Moveable", + "dojox/html/metrics", + "./util", + "dojo/_base/html" +], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html){ + + var dg = dojox.grid; + + var getTdIndex = function(td){ + return td.cellIndex >=0 ? td.cellIndex : array.indexOf(td.parentNode.cells, td); + }; + + var getTrIndex = function(tr){ + return tr.rowIndex >=0 ? tr.rowIndex : array.indexOf(tr.parentNode.childNodes, tr); + }; + + var getTr = function(rowOwner, index){ + return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]); + }; + + var findTable = function(node){ + for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){} + return n; + }; + + var ascendDom = function(inNode, inWhile){ + for(var n=inNode; n && inWhile(n); n=n.parentNode){} + return n; + }; + + var makeNotTagName = function(inTagName){ + var name = inTagName.toUpperCase(); + return function(node){ return node.tagName != name; }; + }; + + var rowIndexTag = util.rowIndexTag; + var gridViewTag = util.gridViewTag; + + // base class for generating markup for the views + var _Builder = dg._Builder = lang.extend(function(view){ + if(view){ + this.view = view; + this.grid = view.grid; + } + },{ + view: null, + // boilerplate HTML + _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"', + + // Returns the table variable as an array - and with the view width, if specified + getTableArray: function(){ + var html = [this._table]; + if(this.view.viewWidth){ + html.push([' style="width:', this.view.viewWidth, ';"'].join('')); + } + html.push('>'); + return html; + }, + + // generate starting tags for a cell + generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){ + var result = [], html; + if(isHeader){ + var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"'; + if (!inCell.id){ + inCell.id = this.grid.id + "Hdr" + inCell.index; + } + // column headers are not editable, mark as aria-readonly=true + html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"']; + }else{ + // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable) + // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true + // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit + var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : ""; + html = ['<td tabIndex="-1" role="gridcell"', editInfo]; + } + if(inCell.colSpan){ + html.push(' colspan="', inCell.colSpan, '"'); + } + if(inCell.rowSpan){ + html.push(' rowspan="', inCell.rowSpan, '"'); + } + html.push(' class="dojoxGridCell '); + if(inCell.classes){ + html.push(inCell.classes, ' '); + } + if(inMoreClasses){ + html.push(inMoreClasses, ' '); + } + // result[0] => td opener, style + result.push(html.join('')); + // SLOT: result[1] => td classes + result.push(''); + html = ['" idx="', inCell.index, '" style="']; + if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){ + inMoreStyles += ';'; + } + html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':''); + if(inCell.unitWidth){ + html.push('width:', inCell.unitWidth, ';'); + } + // result[2] => markup + result.push(html.join('')); + // SLOT: result[3] => td style + result.push(''); + html = [ '"' ]; + if(inCell.attrs){ + html.push(" ", inCell.attrs); + } + html.push('>'); + // result[4] => td postfix + result.push(html.join('')); + // SLOT: result[5] => content + result.push(''); + // result[6] => td closes + result.push(isHeader?'</th>':'</td>'); + return result; // Array + }, + + // cell finding + isCellNode: function(inNode){ + return Boolean(inNode && inNode!=win.doc && html.attr(inNode, "idx")); + }, + + getCellNodeIndex: function(inCellNode){ + return inCellNode ? Number(html.attr(inCellNode, "idx")) : -1; + }, + + getCellNode: function(inRowNode, inCellIndex){ + for(var i=0, row; ((row = getTr(inRowNode.firstChild, i)) && row.cells); i++){ + for(var j=0, cell; (cell = row.cells[j]); j++){ + if(this.getCellNodeIndex(cell) == inCellIndex){ + return cell; + } + } + } + return null; + }, + + findCellTarget: function(inSourceNode, inTopNode){ + var n = inSourceNode; + while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){ + n = n.parentNode; + } + return n!=inTopNode ? n : null; + }, + + // event decoration + baseDecorateEvent: function(e){ + e.dispatch = 'do' + e.type; + e.grid = this.grid; + e.sourceView = this.view; + e.cellNode = this.findCellTarget(e.target, e.rowNode); + e.cellIndex = this.getCellNodeIndex(e.cellNode); + e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null); + }, + + // event dispatch + findTarget: function(inSource, inTag){ + var n = inSource; + while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){ + n = n.parentNode; + } + return (n != this.domNode) ? n : null; + }, + + findRowTarget: function(inSource){ + return this.findTarget(inSource, rowIndexTag); + }, + + isIntraNodeEvent: function(e){ + try{ + return (e.cellNode && e.relatedTarget && html.isDescendant(e.relatedTarget, e.cellNode)); + }catch(x){ + // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + return false; + } + }, + + isIntraRowEvent: function(e){ + try{ + var row = e.relatedTarget && this.findRowTarget(e.relatedTarget); + return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex); + }catch(x){ + // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + return false; + } + }, + + dispatchEvent: function(e){ + if(e.dispatch in this){ + return this[e.dispatch](e); + } + return false; + }, + + // dispatched event handlers + domouseover: function(e){ + if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){ + this.lastOverCellNode = e.cellNode; + this.grid.onMouseOver(e); + } + this.grid.onMouseOverRow(e); + }, + + domouseout: function(e){ + if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){ + this.lastOverCellNode = null; + this.grid.onMouseOut(e); + if(!this.isIntraRowEvent(e)){ + this.grid.onMouseOutRow(e); + } + } + }, + + domousedown: function(e){ + if (e.cellNode) + this.grid.onMouseDown(e); + this.grid.onMouseDownRow(e); + } + }); + + // Produces html for grid data content. Owned by grid and used internally + // for rendering data. Override to implement custom rendering. + var _ContentBuilder = dg._ContentBuilder = lang.extend(function(view){ + _Builder.call(this, view); + },_Builder.prototype,{ + update: function(){ + this.prepareHtml(); + }, + + // cache html for rendering data rows + prepareHtml: function(){ + var defaultGet=this.grid.get, cells=this.view.structure.cells; + for(var j=0, row; (row=cells[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + cell.get = cell.get || (cell.value == undefined) && defaultGet; + cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false); + if (!this.grid.editable && cell.editable){ + this.grid.editable = true; + } + } + } + }, + + // time critical: generate html using cache and data source + generateHtml: function(inDataIndex, inRowIndex){ + var + html = this.getTableArray(), + v = this.view, + cells = v.structure.cells, + item = this.grid.getItem(inRowIndex); + + util.fire(this.view, "onBeforeRow", [inRowIndex, cells]); + for(var j=0, row; (row=cells[j]); j++){ + if(row.hidden || row.header){ + continue; + } + html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">'); + for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){ + m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = []; + // content (format can fill in cc and cs as side-effects) + m[5] = cell.format(inRowIndex, item); + if(has("ie") < 8 && (m[5] === null || m[5] === '' || /^\s+$/.test(m[5]))){ + //fix IE 6/7 quirks - border style not effective for empty td + m[5] = ' ' + } + // classes + m[1] = cc.join(' '); + // styles + m[3] = cs.join(';'); + // in-place concat + html.push.apply(html, m); + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); // String + }, + + decorateEvent: function(e){ + e.rowNode = this.findRowTarget(e.target); + if(!e.rowNode){return false;} + e.rowIndex = e.rowNode[rowIndexTag]; + this.baseDecorateEvent(e); + e.cell = this.grid.getCell(e.cellIndex); + return true; // Boolean + } + }); + + // Produces html for grid header content. Owned by grid and used internally + // for rendering data. Override to implement custom rendering. + var _HeaderBuilder = dg._HeaderBuilder = lang.extend(function(view){ + this.moveable = null; + _Builder.call(this, view); + },_Builder.prototype,{ + _skipBogusClicks: false, + overResizeWidth: 4, + minColWidth: 1, + + update: function(){ + if(this.tableMap){ + this.tableMap.mapRows(this.view.structure.cells); + }else{ + this.tableMap = new dg._TableMap(this.view.structure.cells); + } + }, + + generateHtml: function(inGetValue, inValue){ + var html = this.getTableArray(), cells = this.view.structure.cells; + + util.fire(this.view, "onBeforeRow", [-1, cells]); + for(var j=0, row; (row=cells[j]); j++){ + if(row.hidden){ + continue; + } + html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">'); + for(var i=0, cell, markup; (cell=row[i]); i++){ + cell.customClasses = []; + cell.customStyles = []; + if(this.view.simpleStructure){ + if(cell.draggable){ + if(cell.headerClasses){ + if(cell.headerClasses.indexOf('dojoDndItem') == -1){ + cell.headerClasses += ' dojoDndItem'; + } + }else{ + cell.headerClasses = 'dojoDndItem'; + } + } + if(cell.attrs){ + if(cell.attrs.indexOf("dndType='gridColumn_") == -1){ + cell.attrs += " dndType='gridColumn_" + this.grid.id + "'"; + } + }else{ + cell.attrs = "dndType='gridColumn_" + this.grid.id + "'"; + } + } + markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true); + // content + markup[5] = (inValue != undefined ? inValue : inGetValue(cell)); + // styles + markup[3] = cell.customStyles.join(';'); + // classes + markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : ''); + html.push(markup.join('')); + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); + }, + + // event helpers + getCellX: function(e){ + var n, x = e.layerX; + if(has("mozilla") || has("ie") >= 9){ + n = ascendDom(e.target, makeNotTagName("th")); + x -= (n && n.offsetLeft) || 0; + var t = e.sourceView.getScrollbarWidth(); + if(!this.grid.isLeftToRight()/*&& e.sourceView.headerNode.scrollLeft < t*/){ + //fix #11253 + table = ascendDom(n,makeNotTagName("table")); + x -= (table && table.offsetLeft) || 0; + } + //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0; + } + n = ascendDom(e.target, function(){ + if(!n || n == e.cellNode){ + return false; + } + // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width + // when parent has border, overflow: hidden, and is positioned + // handle this problem here ... not a general solution! + x += (n.offsetLeft < 0 ? 0 : n.offsetLeft); + return true; + }); + return x; + }, + + // event decoration + decorateEvent: function(e){ + this.baseDecorateEvent(e); + e.rowIndex = -1; + e.cellX = this.getCellX(e); + return true; + }, + + // event handlers + // resizing + prepareResize: function(e, mod){ + do{ + var i = e.cellIndex; + e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null); + e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1); + }while(e.cellNode && e.cellNode.style.display == "none"); + return Boolean(e.cellNode); + }, + + canResize: function(e){ + if(!e.cellNode || e.cellNode.colSpan > 1){ + return false; + } + var cell = this.grid.getCell(e.cellIndex); + return !cell.noresize && cell.canResize(); + }, + + overLeftResizeArea: function(e){ + // We are never over a resize area if we are in the process of moving + if(html.hasClass(win.body(), "dojoDndMove")){ + return false; + } + //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs + //as if they were still on the left instead of returning the position they were 'float: right' to. + //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over + //the image or text nodes, then just ignored them/treat them not in scale range. + if(has("ie")){ + var tN = e.target; + if(html.hasClass(tN, "dojoxGridArrowButtonNode") || + html.hasClass(tN, "dojoxGridArrowButtonChar") || + html.hasClass(tN, "dojoxGridColCaption")){ + return false; + } + } + + if(this.grid.isLeftToRight()){ + return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1); + } + var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth); + return t; + }, + + overRightResizeArea: function(e){ + // We are never over a resize area if we are in the process of moving + if(html.hasClass(win.body(), "dojoDndMove")){ + return false; + } + //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs + //as if they were still on the left instead of returning the position they were 'float: right' to. + //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over + //the image or text nodes, then just ignored them/treat them not in scale range. + if(has("ie")){ + var tN = e.target; + if(html.hasClass(tN, "dojoxGridArrowButtonNode") || + html.hasClass(tN, "dojoxGridArrowButtonChar") || + html.hasClass(tN, "dojoxGridColCaption")){ + return false; + } + } + + if(this.grid.isLeftToRight()){ + return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth); + } + return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1); + }, + + domousemove: function(e){ + //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth); + if(!this.moveable){ + var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : '')); + if(c && !this.canResize(e)){ + c = 'dojoxGridColNoResize'; + } + html.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize")); + html.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize")); + if(c){ + event.stop(e); + } + } + }, + + domousedown: function(e){ + if(!this.moveable){ + if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){ + this.beginColumnResize(e); + }else{ + this.grid.onMouseDown(e); + this.grid.onMouseOverRow(e); + } + //else{ + // this.beginMoveColumn(e); + //} + } + }, + + doclick: function(e) { + if(this._skipBogusClicks){ + event.stop(e); + return true; + } + return false; + }, + + // column resizing + colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){ + //Set up the drag object for column resizing + // Called with mouse event in case of drag and drop, + // Also called from keyboard shift-arrow event when focus is on a header + var headContentBox = html.contentBox(e.sourceView.headerNode); + + if(isMouse){ //IE draws line even with no mouse down so separate from keyboard + this.lineDiv = document.createElement('div'); + + var vw = html.position(e.sourceView.headerNode, true); + var bodyContentBox = html.contentBox(e.sourceView.domNode); + //fix #11340 + var l = e.pageX; + if(!this.grid.isLeftToRight() && has("ie") < 8){ + l -= metrics.getScrollbar().w; + } + html.style(this.lineDiv, { + top: vw.y + "px", + left: l + "px", + height: (bodyContentBox.h + headContentBox.h) + "px" + }); + html.addClass(this.lineDiv, "dojoxGridResizeColLine"); + this.lineDiv._origLeft = l; + win.body().appendChild(this.lineDiv); + } + var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode); + for(var i=0, cell; (cell=nodes[i]); i++){ + spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth }); + //console.log("spanner: " + this.getCellNodeIndex(cell)); + } + + var view = e.sourceView; + var adj = this.grid.isLeftToRight() ? 1 : -1; + var views = e.grid.views.views; + var followers = []; + for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){ + followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) }); + } + var table = view.headerContentNode.firstChild; + var drag = { + scrollLeft: e.sourceView.headerNode.scrollLeft, + view: view, + node: e.cellNode, + index: e.cellIndex, + w: html.contentBox(e.cellNode).w, + vw: headContentBox.w, + table: table, + tw: html.contentBox(table).w, + spanners: spanners, + followers: followers + }; + return drag; + }, + beginColumnResize: function(e){ + this.moverDiv = document.createElement("div"); + html.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl + win.body().appendChild(this.moverDiv); + html.addClass(this.grid.domNode, "dojoxGridColumnResizing"); + var m = (this.moveable = new Moveable(this.moverDiv)); + + var drag = this.colResizeSetup(e,true); + + m.onMove = lang.hitch(this, "doResizeColumn", drag); + + connect.connect(m, "onMoveStop", lang.hitch(this, function(){ + this.endResizeColumn(drag); + if(drag.node.releaseCapture){ + drag.node.releaseCapture(); + } + this.moveable.destroy(); + delete this.moveable; + this.moveable = null; + html.removeClass(this.grid.domNode, "dojoxGridColumnResizing"); + })); + + if(e.cellNode.setCapture){ + e.cellNode.setCapture(); + } + m.onMouseDown(e); + }, + + doResizeColumn: function(inDrag, mover, leftTop){ + var changeX = leftTop.l; + var data = { + deltaX: changeX, + w: inDrag.w + (this.grid.isLeftToRight() ? changeX : -changeX),//fix #11341 + vw: inDrag.vw + changeX, + tw: inDrag.tw + changeX + }; + + this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop}; + + if(data.w >= this.minColWidth){ + if (!mover) { // we are using keyboard do immediate resize + this.doResizeNow(inDrag, data); + } + else{ + html.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px"); + } + } + }, + + endResizeColumn: function(inDrag){ + if(this.dragRecord){ + var leftTop = this.dragRecord.leftTop; + var changeX = this.grid.isLeftToRight() ? leftTop.l : -leftTop.l; + // Make sure we are not under our minimum + // http://bugs.dojotoolkit.org/ticket/9390 + changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX); + if(has("webkit") && inDrag.spanners.length){ + // Webkit needs the pad border extents back in + changeX += html._getPadBorderExtents(inDrag.spanners[0].node).w; + } + var data = { + deltaX: changeX, + w: inDrag.w + changeX, + vw: inDrag.vw + changeX, + tw: inDrag.tw + changeX + }; + // Only resize the columns when the drag has finished + this.doResizeNow(inDrag, data); + delete this.dragRecord; + } + + html.destroy(this.lineDiv); + html.destroy(this.moverDiv); + html.destroy(this.moverDiv); + delete this.moverDiv; + this._skipBogusClicks = true; + inDrag.view.update(); + this._skipBogusClicks = false; + this.grid.onResizeColumn(inDrag.index); + }, + doResizeNow: function(inDrag, data){ + inDrag.view.convertColPctToFixed(); + if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){ + var t = findTable(inDrag.node); + if(t){ + (t.style.width = ''); + } + } + var i, s, sw, f, fl; + for(i=0; (s=inDrag.spanners[i]); i++){ + sw = s.width + data.deltaX; + if(sw > 0){ + s.node.style.width = sw + 'px'; + inDrag.view.setColWidth(s.index, sw); + } + } + if(this.grid.isLeftToRight() || !has("ie")){//fix #11339 + for(i=0; (f=inDrag.followers[i]); i++){ + fl = f.left + data.deltaX; + f.node.style.left = fl + 'px'; + } + } + inDrag.node.style.width = data.w + 'px'; + inDrag.view.setColWidth(inDrag.index, data.w); + inDrag.view.headerNode.style.width = data.vw + 'px'; + inDrag.view.setColumnsWidth(data.tw); + if(!this.grid.isLeftToRight()){ + inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX; + } + } + }); + + // Maps an html table into a structure parsable for information about cell row and col spanning. + // Used by HeaderBuilder. + dg._TableMap = lang.extend(function(rows){ + this.mapRows(rows); + },{ + map: null, + + mapRows: function(inRows){ + // summary: Map table topography + + //console.log('mapRows'); + // # of rows + var rowCount = inRows.length; + if(!rowCount){ + return; + } + // map which columns and rows fill which cells + this.map = []; + var row; + for(var k=0; (row=inRows[k]); k++){ + this.map[k] = []; + } + for(var j=0; (row=inRows[j]); j++){ + for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){ + while(this.map[j][x]){x++;} + this.map[j][x] = { c: i, r: j }; + rowSpan = cell.rowSpan || 1; + colSpan = cell.colSpan || 1; + for(var y=0; y<rowSpan; y++){ + for(var s=0; s<colSpan; s++){ + this.map[j+y][x+s] = this.map[j][x]; + } + } + x += colSpan; + } + } + //this.dumMap(); + }, + + dumpMap: function(){ + for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){ + for(var i=0, cell; (cell=row[i]); i++){ + h += cell.r + ',' + cell.c + ' '; + } + } + }, + + getMapCoords: function(inRow, inCol){ + // summary: Find node's map coords by it's structure coords + for(var j=0, row; (row=this.map[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + if(cell.c==inCol && cell.r == inRow){ + return { j: j, i: i }; + } + //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); }; + } + } + return { j: -1, i: -1 }; + }, + + getNode: function(inTable, inRow, inCol){ + // summary: Find a node in inNode's table with the given structure coords + var row = inTable && inTable.rows[inRow]; + return row && row.cells[inCol]; + }, + + _findOverlappingNodes: function(inTable, inRow, inCol){ + var nodes = []; + var m = this.getMapCoords(inRow, inCol); + //console.log("node j: %d, i: %d", m.j, m.i); + for(var j=0, row; (row=this.map[j]); j++){ + if(j == m.j){ continue; } + var rw = row[m.i]; + //console.log("overlaps: r: %d, c: %d", rw.r, rw.c); + var n = (rw?this.getNode(inTable, rw.r, rw.c):null); + if(n){ nodes.push(n); } + } + //console.log(nodes); + return nodes; + }, + + findOverlappingNodes: function(inNode){ + return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode)); + } + }); + + return { + _Builder: _Builder, + _HeaderBuilder: _HeaderBuilder, + _ContentBuilder: _ContentBuilder + }; +}); +}, +'dojo/dnd/Source':function(){ +define(["../main", "./Selector", "./Manager"], function(dojo, Selector, Manager) { + // module: + // dojo/dnd/Source + // summary: + // TODOC + +/*===== +Selector = dojo.dnd.Selector; +=====*/ + +/* + Container property: + "Horizontal"- if this is the horizontal container + Source states: + "" - normal state + "Moved" - this source is being moved + "Copied" - this source is being copied + Target states: + "" - normal state + "Disabled" - the target cannot accept an avatar + Target anchor state: + "" - item is not selected + "Before" - insert point is before the anchor + "After" - insert point is after the anchor +*/ + +/*===== +dojo.dnd.__SourceArgs = function(){ + // summary: + // a dict of parameters for DnD Source configuration. Note that any + // property on Source elements may be configured, but this is the + // short-list + // isSource: Boolean? + // can be used as a DnD source. Defaults to true. + // accept: Array? + // list of accepted types (text strings) for a target; defaults to + // ["text"] + // autoSync: Boolean + // if true refreshes the node list on every operation; false by default + // copyOnly: Boolean? + // copy items, if true, use a state of Ctrl key otherwise, + // see selfCopy and selfAccept for more details + // delay: Number + // the move delay in pixels before detecting a drag; 0 by default + // horizontal: Boolean? + // a horizontal container, if true, vertical otherwise or when omitted + // selfCopy: Boolean? + // copy items by default when dropping on itself, + // false by default, works only if copyOnly is true + // selfAccept: Boolean? + // accept its own items when copyOnly is true, + // true by default, works only if copyOnly is true + // withHandles: Boolean? + // allows dragging only by handles, false by default + // generateText: Boolean? + // generate text node for drag and drop, true by default + this.isSource = isSource; + this.accept = accept; + this.autoSync = autoSync; + this.copyOnly = copyOnly; + this.delay = delay; + this.horizontal = horizontal; + this.selfCopy = selfCopy; + this.selfAccept = selfAccept; + this.withHandles = withHandles; + this.generateText = true; +} +=====*/ + +// For back-compat, remove in 2.0. +if(!dojo.isAsync){ + dojo.ready(0, function(){ + var requires = ["dojo/dnd/AutoSource", "dojo/dnd/Target"]; + require(requires); // use indirection so modules not rolled into a build + }) +} + +return dojo.declare("dojo.dnd.Source", Selector, { + // summary: + // a Source object, which can be used as a DnD source, or a DnD target + + // object attributes (for markup) + isSource: true, + horizontal: false, + copyOnly: false, + selfCopy: false, + selfAccept: true, + skipForm: false, + withHandles: false, + autoSync: false, + delay: 0, // pixels + accept: ["text"], + generateText: true, + + constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){ + // summary: + // a constructor of the Source + // node: + // node or node's id to build the source on + // params: + // any property of this class may be configured via the params + // object which is mixed-in to the `dojo.dnd.Source` instance + dojo.mixin(this, dojo.mixin({}, params)); + var type = this.accept; + if(type.length){ + this.accept = {}; + for(var i = 0; i < type.length; ++i){ + this.accept[type[i]] = 1; + } + } + // class-specific variables + this.isDragging = false; + this.mouseDown = false; + this.targetAnchor = null; + this.targetBox = null; + this.before = true; + this._lastX = 0; + this._lastY = 0; + // states + this.sourceState = ""; + if(this.isSource){ + dojo.addClass(this.node, "dojoDndSource"); + } + this.targetState = ""; + if(this.accept){ + dojo.addClass(this.node, "dojoDndTarget"); + } + if(this.horizontal){ + dojo.addClass(this.node, "dojoDndHorizontal"); + } + // set up events + this.topics = [ + dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"), + dojo.subscribe("/dnd/start", this, "onDndStart"), + dojo.subscribe("/dnd/drop", this, "onDndDrop"), + dojo.subscribe("/dnd/cancel", this, "onDndCancel") + ]; + }, + + // methods + checkAcceptance: function(source, nodes){ + // summary: + // checks if the target can accept nodes from this source + // source: Object + // the source which provides items + // nodes: Array + // the list of transferred items + if(this == source){ + return !this.copyOnly || this.selfAccept; + } + for(var i = 0; i < nodes.length; ++i){ + var type = source.getItem(nodes[i].id).type; + // type instanceof Array + var flag = false; + for(var j = 0; j < type.length; ++j){ + if(type[j] in this.accept){ + flag = true; + break; + } + } + if(!flag){ + return false; // Boolean + } + } + return true; // Boolean + }, + copyState: function(keyPressed, self){ + // summary: + // Returns true if we need to copy items, false to move. + // It is separated to be overwritten dynamically, if needed. + // keyPressed: Boolean + // the "copy" key was pressed + // self: Boolean? + // optional flag that means that we are about to drop on itself + + if(keyPressed){ return true; } + if(arguments.length < 2){ + self = this == Manager.manager().target; + } + if(self){ + if(this.copyOnly){ + return this.selfCopy; + } + }else{ + return this.copyOnly; + } + return false; // Boolean + }, + destroy: function(){ + // summary: + // prepares the object to be garbage-collected + dojo.dnd.Source.superclass.destroy.call(this); + dojo.forEach(this.topics, dojo.unsubscribe); + this.targetAnchor = null; + }, + + // mouse event processors + onMouseMove: function(e){ + // summary: + // event processor for onmousemove + // e: Event + // mouse event + if(this.isDragging && this.targetState == "Disabled"){ return; } + dojo.dnd.Source.superclass.onMouseMove.call(this, e); + var m = Manager.manager(); + if(!this.isDragging){ + if(this.mouseDown && this.isSource && + (Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay)){ + var nodes = this.getSelectedNodes(); + if(nodes.length){ + m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e), true)); + } + } + } + if(this.isDragging){ + // calculate before/after + var before = false; + if(this.current){ + if(!this.targetBox || this.targetAnchor != this.current){ + this.targetBox = dojo.position(this.current, true); + } + if(this.horizontal){ + before = (e.pageX - this.targetBox.x) < (this.targetBox.w / 2); + }else{ + before = (e.pageY - this.targetBox.y) < (this.targetBox.h / 2); + } + } + if(this.current != this.targetAnchor || before != this.before){ + this._markTargetAnchor(before); + m.canDrop(!this.current || m.source != this || !(this.current.id in this.selection)); + } + } + }, + onMouseDown: function(e){ + // summary: + // event processor for onmousedown + // e: Event + // mouse event + if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){ + this.mouseDown = true; + this._lastX = e.pageX; + this._lastY = e.pageY; + dojo.dnd.Source.superclass.onMouseDown.call(this, e); + } + }, + onMouseUp: function(e){ + // summary: + // event processor for onmouseup + // e: Event + // mouse event + if(this.mouseDown){ + this.mouseDown = false; + dojo.dnd.Source.superclass.onMouseUp.call(this, e); + } + }, + + // topic event processors + onDndSourceOver: function(source){ + // summary: + // topic event processor for /dnd/source/over, called when detected a current source + // source: Object + // the source which has the mouse over it + if(this != source){ + this.mouseDown = false; + if(this.targetAnchor){ + this._unmarkTargetAnchor(); + } + }else if(this.isDragging){ + var m = Manager.manager(); + m.canDrop(this.targetState != "Disabled" && (!this.current || m.source != this || !(this.current.id in this.selection))); + } + }, + onDndStart: function(source, nodes, copy){ + // summary: + // topic event processor for /dnd/start, called to initiate the DnD operation + // source: Object + // the source which provides items + // nodes: Array + // the list of transferred items + // copy: Boolean + // copy items, if true, move items otherwise + if(this.autoSync){ this.sync(); } + if(this.isSource){ + this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : ""); + } + var accepted = this.accept && this.checkAcceptance(source, nodes); + this._changeState("Target", accepted ? "" : "Disabled"); + if(this == source){ + Manager.manager().overSource(this); + } + this.isDragging = true; + }, + onDndDrop: function(source, nodes, copy, target){ + // summary: + // topic event processor for /dnd/drop, called to finish the DnD operation + // source: Object + // the source which provides items + // nodes: Array + // the list of transferred items + // copy: Boolean + // copy items, if true, move items otherwise + // target: Object + // the target which accepts items + if(this == target){ + // this one is for us => move nodes! + this.onDrop(source, nodes, copy); + } + this.onDndCancel(); + }, + onDndCancel: function(){ + // summary: + // topic event processor for /dnd/cancel, called to cancel the DnD operation + if(this.targetAnchor){ + this._unmarkTargetAnchor(); + this.targetAnchor = null; + } + this.before = true; + this.isDragging = false; + this.mouseDown = false; + this._changeState("Source", ""); + this._changeState("Target", ""); + }, + + // local events + onDrop: function(source, nodes, copy){ + // summary: + // called only on the current target, when drop is performed + // source: Object + // the source which provides items + // nodes: Array + // the list of transferred items + // copy: Boolean + // copy items, if true, move items otherwise + + if(this != source){ + this.onDropExternal(source, nodes, copy); + }else{ + this.onDropInternal(nodes, copy); + } + }, + onDropExternal: function(source, nodes, copy){ + // summary: + // called only on the current target, when drop is performed + // from an external source + // source: Object + // the source which provides items + // nodes: Array + // the list of transferred items + // copy: Boolean + // copy items, if true, move items otherwise + + var oldCreator = this._normalizedCreator; + // transferring nodes from the source to the target + if(this.creator){ + // use defined creator + this._normalizedCreator = function(node, hint){ + return oldCreator.call(this, source.getItem(node.id).data, hint); + }; + }else{ + // we have no creator defined => move/clone nodes + if(copy){ + // clone nodes + this._normalizedCreator = function(node, hint){ + var t = source.getItem(node.id); + var n = node.cloneNode(true); + n.id = dojo.dnd.getUniqueId(); + return {node: n, data: t.data, type: t.type}; + }; + }else{ + // move nodes + this._normalizedCreator = function(node, hint){ + var t = source.getItem(node.id); + source.delItem(node.id); + return {node: node, data: t.data, type: t.type}; + }; + } + } + this.selectNone(); + if(!copy && !this.creator){ + source.selectNone(); + } + this.insertNodes(true, nodes, this.before, this.current); + if(!copy && this.creator){ + source.deleteSelectedNodes(); + } + this._normalizedCreator = oldCreator; + }, + onDropInternal: function(nodes, copy){ + // summary: + // called only on the current target, when drop is performed + // from the same target/source + // nodes: Array + // the list of transferred items + // copy: Boolean + // copy items, if true, move items otherwise + + var oldCreator = this._normalizedCreator; + // transferring nodes within the single source + if(this.current && this.current.id in this.selection){ + // do nothing + return; + } + if(copy){ + if(this.creator){ + // create new copies of data items + this._normalizedCreator = function(node, hint){ + return oldCreator.call(this, this.getItem(node.id).data, hint); + }; + }else{ + // clone nodes + this._normalizedCreator = function(node, hint){ + var t = this.getItem(node.id); + var n = node.cloneNode(true); + n.id = dojo.dnd.getUniqueId(); + return {node: n, data: t.data, type: t.type}; + }; + } + }else{ + // move nodes + if(!this.current){ + // do nothing + return; + } + this._normalizedCreator = function(node, hint){ + var t = this.getItem(node.id); + return {node: node, data: t.data, type: t.type}; + }; + } + this._removeSelection(); + this.insertNodes(true, nodes, this.before, this.current); + this._normalizedCreator = oldCreator; + }, + onDraggingOver: function(){ + // summary: + // called during the active DnD operation, when items + // are dragged over this target, and it is not disabled + }, + onDraggingOut: function(){ + // summary: + // called during the active DnD operation, when items + // are dragged away from this target, and it is not disabled + }, + + // utilities + onOverEvent: function(){ + // summary: + // this function is called once, when mouse is over our container + dojo.dnd.Source.superclass.onOverEvent.call(this); + Manager.manager().overSource(this); + if(this.isDragging && this.targetState != "Disabled"){ + this.onDraggingOver(); + } + }, + onOutEvent: function(){ + // summary: + // this function is called once, when mouse is out of our container + dojo.dnd.Source.superclass.onOutEvent.call(this); + Manager.manager().outSource(this); + if(this.isDragging && this.targetState != "Disabled"){ + this.onDraggingOut(); + } + }, + _markTargetAnchor: function(before){ + // summary: + // assigns a class to the current target anchor based on "before" status + // before: Boolean + // insert before, if true, after otherwise + if(this.current == this.targetAnchor && this.before == before){ return; } + if(this.targetAnchor){ + this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After"); + } + this.targetAnchor = this.current; + this.targetBox = null; + this.before = before; + if(this.targetAnchor){ + this._addItemClass(this.targetAnchor, this.before ? "Before" : "After"); + } + }, + _unmarkTargetAnchor: function(){ + // summary: + // removes a class of the current target anchor based on "before" status + if(!this.targetAnchor){ return; } + this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After"); + this.targetAnchor = null; + this.targetBox = null; + this.before = true; + }, + _markDndStatus: function(copy){ + // summary: + // changes source's state based on "copy" status + this._changeState("Source", copy ? "Copied" : "Moved"); + }, + _legalMouseDown: function(e){ + // summary: + // checks if user clicked on "approved" items + // e: Event + // mouse event + + // accept only the left mouse button + if(!dojo.mouseButtons.isLeft(e)){ return false; } + + if(!this.withHandles){ return true; } + + // check for handles + for(var node = e.target; node && node !== this.node; node = node.parentNode){ + if(dojo.hasClass(node, "dojoDndHandle")){ return true; } + if(dojo.hasClass(node, "dojoDndItem") || dojo.hasClass(node, "dojoDndIgnore")){ break; } + } + return false; // Boolean + } +}); + +}); + +}, +'dojox/grid/cells/_base':function(){ +define("dojox/grid/cells/_base", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/event", + "dojo/_base/connect", + "dojo/_base/array", + "dojo/_base/sniff", + "dojo/dom", + "dojo/dom-attr", + "dojo/dom-construct", + "dijit/_Widget", + "../util" +], function(dojo, declare, lang, event, connect, array, has, dom, domAttr, domConstruct, _Widget, util){ + + var _DeferredTextWidget = declare("dojox.grid._DeferredTextWidget", _Widget, { + deferred: null, + _destroyOnRemove: true, + postCreate: function(){ + if(this.deferred){ + this.deferred.addBoth(lang.hitch(this, function(text){ + if(this.domNode){ + this.domNode.innerHTML = text; + } + })); + } + } + }); + + var focusSelectNode = function(inNode){ + try{ + util.fire(inNode, "focus"); + util.fire(inNode, "select"); + }catch(e){// IE sux bad + } + }; + + var whenIdle = function(/*inContext, inMethod, args ...*/){ + setTimeout(lang.hitch.apply(dojo, arguments), 0); + }; + + var BaseCell = declare("dojox.grid.cells._Base", null, { + // summary: + // Respresents a grid cell and contains information about column options and methods + // for retrieving cell related information. + // Each column in a grid layout has a cell object and most events and many methods + // provide access to these objects. + styles: '', + classes: '', + editable: false, + alwaysEditing: false, + formatter: null, + defaultValue: '...', + value: null, + hidden: false, + noresize: false, + draggable: true, + //private + _valueProp: "value", + _formatPending: false, + + constructor: function(inProps){ + this._props = inProps || {}; + lang.mixin(this, inProps); + if(this.draggable === undefined){ + this.draggable = true; + } + }, + + _defaultFormat: function(inValue, callArgs){ + var s = this.grid.formatterScope || this; + var f = this.formatter; + if(f && s && typeof f == "string"){ + f = this.formatter = s[f]; + } + var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue; + if(typeof v == "undefined"){ + return this.defaultValue; + } + if(v && v.addBoth){ + // Check if it's a deferred + v = new _DeferredTextWidget({deferred: v}, + domConstruct.create("span", {innerHTML: this.defaultValue})); + } + if(v && v.declaredClass && v.startup){ + return "<div class='dojoxGridStubNode' linkWidget='" + + v.id + + "' cellIdx='" + + this.index + + "'>" + + this.defaultValue + + "</div>"; + } + return v; + }, + + // data source + format: function(inRowIndex, inItem){ + // summary: + // provides the html for a given grid cell. + // inRowIndex: int + // grid row index + // returns: html for a given grid cell + var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue); + d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&').replace(/</g, '<') : d; + if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){ + return this.formatEditing(d, inRowIndex); + }else{ + return this._defaultFormat(d, [d, inRowIndex, this]); + } + }, + formatEditing: function(inDatum, inRowIndex){ + // summary: + // formats the cell for editing + // inDatum: anything + // cell data to edit + // inRowIndex: int + // grid row index + // returns: string of html to place in grid cell + }, + // utility + getNode: function(inRowIndex){ + // summary: + // gets the dom node for a given grid cell. + // inRowIndex: int + // grid row index + // returns: dom node for a given grid cell + return this.view.getCellNode(inRowIndex, this.index); + }, + getHeaderNode: function(){ + return this.view.getHeaderCellNode(this.index); + }, + getEditNode: function(inRowIndex){ + return (this.getNode(inRowIndex) || 0).firstChild || 0; + }, + canResize: function(){ + var uw = this.unitWidth; + return uw && (uw!=='auto'); + }, + isFlex: function(){ + var uw = this.unitWidth; + return uw && lang.isString(uw) && (uw=='auto' || uw.slice(-1)=='%'); + }, + // edit support + applyEdit: function(inValue, inRowIndex){ + this.grid.edit.applyCellEdit(inValue, this, inRowIndex); + }, + cancelEdit: function(inRowIndex){ + this.grid.doCancelEdit(inRowIndex); + }, + _onEditBlur: function(inRowIndex){ + if(this.grid.edit.isEditCell(inRowIndex, this.index)){ + //console.log('editor onblur', e); + this.grid.edit.apply(); + } + }, + registerOnBlur: function(inNode, inRowIndex){ + if(this.commitOnBlur){ + connect.connect(inNode, "onblur", function(e){ + // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid + setTimeout(lang.hitch(this, "_onEditBlur", inRowIndex), 250); + }); + } + }, + //protected + needFormatNode: function(inDatum, inRowIndex){ + this._formatPending = true; + whenIdle(this, "_formatNode", inDatum, inRowIndex); + }, + cancelFormatNode: function(){ + this._formatPending = false; + }, + //private + _formatNode: function(inDatum, inRowIndex){ + if(this._formatPending){ + this._formatPending = false; + // make cell selectable + if(!has("ie")){ + dom.setSelectable(this.grid.domNode, true); + } + this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex); + } + }, + //protected + formatNode: function(inNode, inDatum, inRowIndex){ + // summary: + // format the editing dom node. Use when editor is a widget. + // inNode: dom node + // dom node for the editor + // inDatum: anything + // cell data to edit + // inRowIndex: int + // grid row index + if(has("ie")){ + // IE sux bad + whenIdle(this, "focus", inRowIndex, inNode); + }else{ + this.focus(inRowIndex, inNode); + } + }, + dispatchEvent: function(m, e){ + if(m in this){ + return this[m](e); + } + }, + //public + getValue: function(inRowIndex){ + // summary: + // returns value entered into editor + // inRowIndex: int + // grid row index + // returns: + // value of editor + return this.getEditNode(inRowIndex)[this._valueProp]; + }, + setValue: function(inRowIndex, inValue){ + // summary: + // set the value of the grid editor + // inRowIndex: int + // grid row index + // inValue: anything + // value of editor + var n = this.getEditNode(inRowIndex); + if(n){ + n[this._valueProp] = inValue; + } + }, + focus: function(inRowIndex, inNode){ + // summary: + // focus the grid editor + // inRowIndex: int + // grid row index + // inNode: dom node + // editor node + focusSelectNode(inNode || this.getEditNode(inRowIndex)); + }, + save: function(inRowIndex){ + // summary: + // save editor state + // inRowIndex: int + // grid row index + this.value = this.value || this.getValue(inRowIndex); + //console.log("save", this.value, inCell.index, inRowIndex); + }, + restore: function(inRowIndex){ + // summary: + // restore editor state + // inRowIndex: int + // grid row index + this.setValue(inRowIndex, this.value); + //console.log("restore", this.value, inCell.index, inRowIndex); + }, + //protected + _finish: function(inRowIndex){ + // summary: + // called when editing is completed to clean up editor + // inRowIndex: int + // grid row index + dom.setSelectable(this.grid.domNode, false); + this.cancelFormatNode(); + }, + //public + apply: function(inRowIndex){ + // summary: + // apply edit from cell editor + // inRowIndex: int + // grid row index + this.applyEdit(this.getValue(inRowIndex), inRowIndex); + this._finish(inRowIndex); + }, + cancel: function(inRowIndex){ + // summary: + // cancel cell edit + // inRowIndex: int + // grid row index + this.cancelEdit(inRowIndex); + this._finish(inRowIndex); + } + }); + BaseCell.markupFactory = function(node, cellDef){ + var formatter = lang.trim(domAttr.get(node, "formatter")||""); + if(formatter){ + cellDef.formatter = lang.getObject(formatter)||formatter; + } + var get = lang.trim(domAttr.get(node, "get")||""); + if(get){ + cellDef.get = lang.getObject(get); + } + var getBoolAttr = function(attr, cell, cellAttr){ + var value = lang.trim(domAttr.get(node, attr)||""); + if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); } + }; + getBoolAttr("sortDesc", cellDef); + getBoolAttr("editable", cellDef); + getBoolAttr("alwaysEditing", cellDef); + getBoolAttr("noresize", cellDef); + getBoolAttr("draggable", cellDef); + + var value = lang.trim(domAttr.get(node, "loadingText")||domAttr.get(node, "defaultValue")||""); + if(value){ + cellDef.defaultValue = value; + } + + var getStrAttr = function(attr, cell, cellAttr){ + var value = lang.trim(domAttr.get(node, attr)||"")||undefined; + if(value){ cell[cellAttr||attr] = value; } + }; + getStrAttr("styles", cellDef); + getStrAttr("headerStyles", cellDef); + getStrAttr("cellStyles", cellDef); + getStrAttr("classes", cellDef); + getStrAttr("headerClasses", cellDef); + getStrAttr("cellClasses", cellDef); + }; + + var Cell = declare("dojox.grid.cells.Cell", BaseCell, { + // summary + // grid cell that provides a standard text input box upon editing + constructor: function(){ + this.keyFilter = this.keyFilter; + }, + // keyFilter: RegExp + // optional regex for disallowing keypresses + keyFilter: null, + formatEditing: function(inDatum, inRowIndex){ + this.needFormatNode(inDatum, inRowIndex); + return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">'; + }, + formatNode: function(inNode, inDatum, inRowIndex){ + this.inherited(arguments); + // FIXME: feels too specific for this interface + this.registerOnBlur(inNode, inRowIndex); + }, + doKey: function(e){ + if(this.keyFilter){ + var key = String.fromCharCode(e.charCode); + if(key.search(this.keyFilter) == -1){ + event.stop(e); + } + } + }, + _finish: function(inRowIndex){ + this.inherited(arguments); + var n = this.getEditNode(inRowIndex); + try{ + util.fire(n, "blur"); + }catch(e){} + } + }); + Cell.markupFactory = function(node, cellDef){ + BaseCell.markupFactory(node, cellDef); + var keyFilter = lang.trim(domAttr.get(node, "keyFilter")||""); + if(keyFilter){ + cellDef.keyFilter = new RegExp(keyFilter); + } + }; + + var RowIndex = declare("dojox.grid.cells.RowIndex", Cell, { + name: 'Row', + + postscript: function(){ + this.editable = false; + }, + get: function(inRowIndex){ + return inRowIndex + 1; + } + }); + RowIndex.markupFactory = function(node, cellDef){ + Cell.markupFactory(node, cellDef); + }; + + var Select = declare("dojox.grid.cells.Select", Cell, { + // summary: + // grid cell that provides a standard select for editing + + // options: Array + // text of each item + options: null, + + // values: Array + // value for each item + values: null, + + // returnIndex: Integer + // editor returns only the index of the selected option and not the value + returnIndex: -1, + + constructor: function(inCell){ + this.values = this.values || this.options; + }, + formatEditing: function(inDatum, inRowIndex){ + this.needFormatNode(inDatum, inRowIndex); + var h = [ '<select class="dojoxGridSelect">' ]; + for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){ + v = v.replace ? v.replace(/&/g, '&').replace(/</g, '<') : v; + o = o.replace ? o.replace(/&/g, '&').replace(/</g, '<') : o; + h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>"); + } + h.push('</select>'); + return h.join(''); + }, + _defaultFormat: function(inValue, callArgs){ + var v = this.inherited(arguments); + // when 'values' and 'options' both provided and there is no cutomized formatter, + // then we use 'options' as label in order to be consistent + if(!this.formatter && this.values && this.options){ + var i = array.indexOf(this.values, v); + if(i >= 0){ + v = this.options[i]; + } + } + return v; + }, + getValue: function(inRowIndex){ + var n = this.getEditNode(inRowIndex); + if(n){ + var i = n.selectedIndex, o = n.options[i]; + return this.returnIndex > -1 ? i : o.value || o.innerHTML; + } + } + }); + Select.markupFactory = function(node, cell){ + Cell.markupFactory(node, cell); + var options = lang.trim(domAttr.get(node, "options")||""); + if(options){ + var o = options.split(','); + if(o[0] != options){ + cell.options = o; + } + } + var values = lang.trim(domAttr.get(node, "values")||""); + if(values){ + var v = values.split(','); + if(v[0] != values){ + cell.values = v; + } + } + }; + + var AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, { + // summary: + // grid cell that is always in an editable state, regardless of grid editing state + alwaysEditing: true, + _formatNode: function(inDatum, inRowIndex){ + this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex); + }, + applyStaticValue: function(inRowIndex){ + var e = this.grid.edit; + e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex); + e.start(this, inRowIndex, true); + } + }); + AlwaysEdit.markupFactory = function(node, cell){ + Cell.markupFactory(node, cell); + }; + + var Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, { + // summary: + // grid cell that provides a standard checkbox that is always on for editing + _valueProp: "checked", + formatEditing: function(inDatum, inRowIndex){ + return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />'; + }, + doclick: function(e){ + if(e.target.tagName == 'INPUT'){ + this.applyStaticValue(e.rowIndex); + } + } + }); + Bool.markupFactory = function(node, cell){ + AlwaysEdit.markupFactory(node, cell); + }; + + return BaseCell; + +}); +}, +'dijit/_WidgetBase':function(){ +define("dijit/_WidgetBase", [ + "require", // require.toUrl + "dojo/_base/array", // array.forEach array.map + "dojo/aspect", + "dojo/_base/config", // config.blankGif + "dojo/_base/connect", // connect.connect + "dojo/_base/declare", // declare + "dojo/dom", // dom.byId + "dojo/dom-attr", // domAttr.set domAttr.remove + "dojo/dom-class", // domClass.add domClass.replace + "dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place + "dojo/dom-geometry", // isBodyLtr + "dojo/dom-style", // domStyle.set, domStyle.get + "dojo/_base/kernel", + "dojo/_base/lang", // mixin(), isArray(), etc. + "dojo/on", + "dojo/ready", + "dojo/Stateful", // Stateful + "dojo/topic", + "dojo/_base/window", // win.doc.createTextNode + "./registry" // registry.getUniqueId(), registry.findWidgets() +], function(require, array, aspect, config, connect, declare, + dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel, + lang, on, ready, Stateful, topic, win, registry){ + +/*===== +var Stateful = dojo.Stateful; +=====*/ + +// module: +// dijit/_WidgetBase +// summary: +// Future base class for all Dijit widgets. + +// For back-compat, remove in 2.0. +if(!kernel.isAsync){ + ready(0, function(){ + var requires = ["dijit/_base/manager"]; + require(requires); // use indirection so modules not rolled into a build + }); +} + +// Nested hash listing attributes for each tag, all strings in lowercase. +// ex: {"div": {"style": true, "tabindex" true}, "form": { ... +var tagAttrs = {}; +function getAttrs(obj){ + var ret = {}; + for(var attr in obj){ + ret[attr.toLowerCase()] = true; + } + return ret; +} + +function nonEmptyAttrToDom(attr){ + // summary: + // Returns a setter function that copies the attribute to this.domNode, + // or removes the attribute from this.domNode, depending on whether the + // value is defined or not. + return function(val){ + domAttr[val ? "set" : "remove"](this.domNode, attr, val); + this._set(attr, val); + }; +} + +return declare("dijit._WidgetBase", Stateful, { + // summary: + // Future base class for all Dijit widgets. + // description: + // Future base class for all Dijit widgets. + // _Widget extends this class adding support for various features needed by desktop. + // + // Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(), + // postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch(). + // + // Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value). + // For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr(). + // + // _setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes: + // + // - DOM node attribute + // | _setFocusAttr: {node: "focusNode", type: "attribute"} + // | _setFocusAttr: "focusNode" (shorthand) + // | _setFocusAttr: "" (shorthand, maps to this.domNode) + // Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus + // + // - DOM node innerHTML + // | _setTitleAttr: { node: "titleNode", type: "innerHTML" } + // Maps this.title to this.titleNode.innerHTML + // + // - DOM node innerText + // | _setTitleAttr: { node: "titleNode", type: "innerText" } + // Maps this.title to this.titleNode.innerText + // + // - DOM node CSS class + // | _setMyClassAttr: { node: "domNode", type: "class" } + // Maps this.myClass to this.domNode.className + // + // If the value of _setXXXAttr is an array, then each element in the array matches one of the + // formats of the above list. + // + // If the custom setter is null, no action is performed other than saving the new value + // in the widget (in this). + // + // If no custom setter is defined for an attribute, then it will be copied + // to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise. + // That's only done though for attributes that match DOMNode attributes (title, + // alt, aria-labelledby, etc.) + + // id: [const] String + // A unique, opaque ID string that can be assigned by users or by the + // system. If the developer passes an ID which is known not to be + // unique, the specified ID is ignored and the system-generated ID is + // used instead. + id: "", + _setIdAttr: "domNode", // to copy to this.domNode even for auto-generated id's + + // lang: [const] String + // Rarely used. Overrides the default Dojo locale used to render this widget, + // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute. + // Value must be among the list of locales specified during by the Dojo bootstrap, + // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us). + lang: "", + // set on domNode even when there's a focus node. but don't set lang="", since that's invalid. + _setLangAttr: nonEmptyAttrToDom("lang"), + + // dir: [const] String + // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir) + // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's + // default direction. + dir: "", + // set on domNode even when there's a focus node. but don't set dir="", since that's invalid. + _setDirAttr: nonEmptyAttrToDom("dir"), // to set on domNode even when there's a focus node + + // textDir: String + // Bi-directional support, the main variable which is responsible for the direction of the text. + // The text direction can be different than the GUI direction by using this parameter in creation + // of a widget. + // Allowed values: + // 1. "ltr" + // 2. "rtl" + // 3. "auto" - contextual the direction of a text defined by first strong letter. + // By default is as the page direction. + textDir: "", + + // class: String + // HTML class attribute + "class": "", + _setClassAttr: { node: "domNode", type: "class" }, + + // style: String||Object + // HTML style attributes as cssText string or name/value hash + style: "", + + // title: String + // HTML title attribute. + // + // For form widgets this specifies a tooltip to display when hovering over + // the widget (just like the native HTML title attribute). + // + // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer, + // etc., it's used to specify the tab label, accordion pane title, etc. + title: "", + + // tooltip: String + // When this widget's title attribute is used to for a tab label, accordion pane title, etc., + // this specifies the tooltip to appear when the mouse is hovered over that text. + tooltip: "", + + // baseClass: [protected] String + // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate + // widget state. + baseClass: "", + + // srcNodeRef: [readonly] DomNode + // pointer to original DOM node + srcNodeRef: null, + + // domNode: [readonly] DomNode + // This is our visible representation of the widget! Other DOM + // Nodes may by assigned to other properties, usually through the + // template system's data-dojo-attach-point syntax, but the domNode + // property is the canonical "top level" node in widget UI. + domNode: null, + + // containerNode: [readonly] DomNode + // Designates where children of the source DOM node will be placed. + // "Children" in this case refers to both DOM nodes and widgets. + // For example, for myWidget: + // + // | <div data-dojo-type=myWidget> + // | <b> here's a plain DOM node + // | <span data-dojo-type=subWidget>and a widget</span> + // | <i> and another plain DOM node </i> + // | </div> + // + // containerNode would point to: + // + // | <b> here's a plain DOM node + // | <span data-dojo-type=subWidget>and a widget</span> + // | <i> and another plain DOM node </i> + // + // In templated widgets, "containerNode" is set via a + // data-dojo-attach-point assignment. + // + // containerNode must be defined for any widget that accepts innerHTML + // (like ContentPane or BorderContainer or even Button), and conversely + // is null for widgets that don't, like TextBox. + containerNode: null, + +/*===== + // _started: Boolean + // startup() has completed. + _started: false, +=====*/ + + // attributeMap: [protected] Object + // Deprecated. Instead of attributeMap, widget should have a _setXXXAttr attribute + // for each XXX attribute to be mapped to the DOM. + // + // attributeMap sets up a "binding" between attributes (aka properties) + // of the widget and the widget's DOM. + // Changes to widget attributes listed in attributeMap will be + // reflected into the DOM. + // + // For example, calling set('title', 'hello') + // on a TitlePane will automatically cause the TitlePane's DOM to update + // with the new title. + // + // attributeMap is a hash where the key is an attribute of the widget, + // and the value reflects a binding to a: + // + // - DOM node attribute + // | focus: {node: "focusNode", type: "attribute"} + // Maps this.focus to this.focusNode.focus + // + // - DOM node innerHTML + // | title: { node: "titleNode", type: "innerHTML" } + // Maps this.title to this.titleNode.innerHTML + // + // - DOM node innerText + // | title: { node: "titleNode", type: "innerText" } + // Maps this.title to this.titleNode.innerText + // + // - DOM node CSS class + // | myClass: { node: "domNode", type: "class" } + // Maps this.myClass to this.domNode.className + // + // If the value is an array, then each element in the array matches one of the + // formats of the above list. + // + // There are also some shorthands for backwards compatibility: + // - string --> { node: string, type: "attribute" }, for example: + // | "focusNode" ---> { node: "focusNode", type: "attribute" } + // - "" --> { node: "domNode", type: "attribute" } + attributeMap: {}, + + // _blankGif: [protected] String + // Path to a blank 1x1 image. + // Used by <img> nodes in templates that really get their image via CSS background-image. + _blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"), + + //////////// INITIALIZATION METHODS /////////////////////////////////////// + + postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){ + // summary: + // Kicks off widget instantiation. See create() for details. + // tags: + // private + this.create(params, srcNodeRef); + }, + + create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){ + // summary: + // Kick off the life-cycle of a widget + // params: + // Hash of initialization parameters for widget, including + // scalar values (like title, duration etc.) and functions, + // typically callbacks like onClick. + // srcNodeRef: + // If a srcNodeRef (DOM node) is specified: + // - use srcNodeRef.innerHTML as my contents + // - if this is a behavioral widget then apply behavior + // to that srcNodeRef + // - otherwise, replace srcNodeRef with my generated DOM + // tree + // description: + // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate, + // etc.), some of which of you'll want to override. See http://dojotoolkit.org/reference-guide/dijit/_WidgetBase.html + // for a discussion of the widget creation lifecycle. + // + // Of course, adventurous developers could override create entirely, but this should + // only be done as a last resort. + // tags: + // private + + // store pointer to original DOM tree + this.srcNodeRef = dom.byId(srcNodeRef); + + // For garbage collection. An array of listener handles returned by this.connect() / this.subscribe() + this._connects = []; + + // For widgets internal to this widget, invisible to calling code + this._supportingWidgets = []; + + // this is here for back-compat, remove in 2.0 (but check NodeList-instantiate.html test) + if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; } + + // mix in our passed parameters + if(params){ + this.params = params; + lang.mixin(this, params); + } + this.postMixInProperties(); + + // generate an id for the widget if one wasn't specified + // (be sure to do this before buildRendering() because that function might + // expect the id to be there.) + if(!this.id){ + this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_")); + } + registry.add(this); + + this.buildRendering(); + + if(this.domNode){ + // Copy attributes listed in attributeMap into the [newly created] DOM for the widget. + // Also calls custom setters for all attributes with custom setters. + this._applyAttributes(); + + // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree. + // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the + // widget being attached to the DOM since it isn't when a widget is created programmatically like + // new MyWidget({}). See #11635. + var source = this.srcNodeRef; + if(source && source.parentNode && this.domNode !== source){ + source.parentNode.replaceChild(this.domNode, source); + } + } + + if(this.domNode){ + // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId", + // assuming that dojo._scopeName even exists in 2.0 + this.domNode.setAttribute("widgetId", this.id); + } + this.postCreate(); + + // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC. + if(this.srcNodeRef && !this.srcNodeRef.parentNode){ + delete this.srcNodeRef; + } + + this._created = true; + }, + + _applyAttributes: function(){ + // summary: + // Step during widget creation to copy widget attributes to the + // DOM according to attributeMap and _setXXXAttr objects, and also to call + // custom _setXXXAttr() methods. + // + // Skips over blank/false attribute values, unless they were explicitly specified + // as parameters to the widget, since those are the default anyway, + // and setting tabIndex="" is different than not setting tabIndex at all. + // + // For backwards-compatibility reasons attributeMap overrides _setXXXAttr when + // _setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap. + // tags: + // private + + // Get list of attributes where this.set(name, value) will do something beyond + // setting this[name] = value. Specifically, attributes that have: + // - associated _setXXXAttr() method/hash/string/array + // - entries in attributeMap. + var ctor = this.constructor, + list = ctor._setterAttrs; + if(!list){ + list = (ctor._setterAttrs = []); + for(var attr in this.attributeMap){ + list.push(attr); + } + + var proto = ctor.prototype; + for(var fxName in proto){ + if(fxName in this.attributeMap){ continue; } + var setterName = "_set" + fxName.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); }) + "Attr"; + if(setterName in proto){ + list.push(fxName); + } + } + } + + // Call this.set() for each attribute that was either specified as parameter to constructor, + // or was found above and has a default non-null value. For correlated attributes like value and displayedValue, the one + // specified as a parameter should take precedence, so apply attributes in this.params last. + // Particularly important for new DateTextBox({displayedValue: ...}) since DateTextBox's default value is + // NaN and thus is not ignored like a default value of "". + array.forEach(list, function(attr){ + if(this.params && attr in this.params){ + // skip this one, do it below + }else if(this[attr]){ + this.set(attr, this[attr]); + } + }, this); + for(var param in this.params){ + this.set(param, this[param]); + } + }, + + postMixInProperties: function(){ + // summary: + // Called after the parameters to the widget have been read-in, + // but before the widget template is instantiated. Especially + // useful to set properties that are referenced in the widget + // template. + // tags: + // protected + }, + + buildRendering: function(){ + // summary: + // Construct the UI for this widget, setting this.domNode. + // Most widgets will mixin `dijit._TemplatedMixin`, which implements this method. + // tags: + // protected + + if(!this.domNode){ + // Create root node if it wasn't created by _Templated + this.domNode = this.srcNodeRef || domConstruct.create('div'); + } + + // baseClass is a single class name or occasionally a space-separated list of names. + // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix. + // TODO: make baseClass custom setter + if(this.baseClass){ + var classes = this.baseClass.split(" "); + if(!this.isLeftToRight()){ + classes = classes.concat( array.map(classes, function(name){ return name+"Rtl"; })); + } + domClass.add(this.domNode, classes); + } + }, + + postCreate: function(){ + // summary: + // Processing after the DOM fragment is created + // description: + // Called after the DOM fragment has been created, but not necessarily + // added to the document. Do not include any operations which rely on + // node dimensions or placement. + // tags: + // protected + }, + + startup: function(){ + // summary: + // Processing after the DOM fragment is added to the document + // description: + // Called after a widget and its children have been created and added to the page, + // and all related widgets have finished their create() cycle, up through postCreate(). + // This is useful for composite widgets that need to control or layout sub-widgets. + // Many layout widgets can use this as a wiring phase. + if(this._started){ return; } + this._started = true; + array.forEach(this.getChildren(), function(obj){ + if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){ + obj.startup(); + obj._started = true; + } + }); + }, + + //////////// DESTROY FUNCTIONS //////////////////////////////// + + destroyRecursive: function(/*Boolean?*/ preserveDom){ + // summary: + // Destroy this widget and its descendants + // description: + // This is the generic "destructor" function that all widget users + // should call to cleanly discard with a widget. Once a widget is + // destroyed, it is removed from the manager object. + // preserveDom: + // If true, this method will leave the original DOM structure + // alone of descendant Widgets. Note: This will NOT work with + // dijit._Templated widgets. + + this._beingDestroyed = true; + this.destroyDescendants(preserveDom); + this.destroy(preserveDom); + }, + + destroy: function(/*Boolean*/ preserveDom){ + // summary: + // Destroy this widget, but not its descendants. + // This method will, however, destroy internal widgets such as those used within a template. + // preserveDom: Boolean + // If true, this method will leave the original DOM structure alone. + // Note: This will not yet work with _Templated widgets + + this._beingDestroyed = true; + this.uninitialize(); + + // remove this.connect() and this.subscribe() listeners + var c; + while(c = this._connects.pop()){ + c.remove(); + } + + // destroy widgets created as part of template, etc. + var w; + while(w = this._supportingWidgets.pop()){ + if(w.destroyRecursive){ + w.destroyRecursive(); + }else if(w.destroy){ + w.destroy(); + } + } + + this.destroyRendering(preserveDom); + registry.remove(this.id); + this._destroyed = true; + }, + + destroyRendering: function(/*Boolean?*/ preserveDom){ + // summary: + // Destroys the DOM nodes associated with this widget + // preserveDom: + // If true, this method will leave the original DOM structure alone + // during tear-down. Note: this will not work with _Templated + // widgets yet. + // tags: + // protected + + if(this.bgIframe){ + this.bgIframe.destroy(preserveDom); + delete this.bgIframe; + } + + if(this.domNode){ + if(preserveDom){ + domAttr.remove(this.domNode, "widgetId"); + }else{ + domConstruct.destroy(this.domNode); + } + delete this.domNode; + } + + if(this.srcNodeRef){ + if(!preserveDom){ + domConstruct.destroy(this.srcNodeRef); + } + delete this.srcNodeRef; + } + }, + + destroyDescendants: function(/*Boolean?*/ preserveDom){ + // summary: + // Recursively destroy the children of this widget and their + // descendants. + // preserveDom: + // If true, the preserveDom attribute is passed to all descendant + // widget's .destroy() method. Not for use with _Templated + // widgets. + + // get all direct descendants and destroy them recursively + array.forEach(this.getChildren(), function(widget){ + if(widget.destroyRecursive){ + widget.destroyRecursive(preserveDom); + } + }); + }, + + uninitialize: function(){ + // summary: + // Stub function. Override to implement custom widget tear-down + // behavior. + // tags: + // protected + return false; + }, + + ////////////////// GET/SET, CUSTOM SETTERS, ETC. /////////////////// + + _setStyleAttr: function(/*String||Object*/ value){ + // summary: + // Sets the style attribute of the widget according to value, + // which is either a hash like {height: "5px", width: "3px"} + // or a plain string + // description: + // Determines which node to set the style on based on style setting + // in attributeMap. + // tags: + // protected + + var mapNode = this.domNode; + + // Note: technically we should revert any style setting made in a previous call + // to his method, but that's difficult to keep track of. + + if(lang.isObject(value)){ + domStyle.set(mapNode, value); + }else{ + if(mapNode.style.cssText){ + mapNode.style.cssText += "; " + value; + }else{ + mapNode.style.cssText = value; + } + } + + this._set("style", value); + }, + + _attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){ + // summary: + // Reflect a widget attribute (title, tabIndex, duration etc.) to + // the widget DOM, as specified by commands parameter. + // If commands isn't specified then it's looked up from attributeMap. + // Note some attributes like "type" + // cannot be processed this way as they are not mutable. + // + // tags: + // private + + commands = arguments.length >= 3 ? commands : this.attributeMap[attr]; + + array.forEach(lang.isArray(commands) ? commands : [commands], function(command){ + + // Get target node and what we are doing to that node + var mapNode = this[command.node || command || "domNode"]; // DOM node + var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute + + switch(type){ + case "attribute": + if(lang.isFunction(value)){ // functions execute in the context of the widget + value = lang.hitch(this, value); + } + + // Get the name of the DOM node attribute; usually it's the same + // as the name of the attribute in the widget (attr), but can be overridden. + // Also maps handler names to lowercase, like onSubmit --> onsubmit + var attrName = command.attribute ? command.attribute : + (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr); + + domAttr.set(mapNode, attrName, value); + break; + case "innerText": + mapNode.innerHTML = ""; + mapNode.appendChild(win.doc.createTextNode(value)); + break; + case "innerHTML": + mapNode.innerHTML = value; + break; + case "class": + domClass.replace(mapNode, value, this[attr]); + break; + } + }, this); + }, + + get: function(name){ + // summary: + // Get a property from a widget. + // name: + // The property to get. + // description: + // Get a named property from a widget. The property may + // potentially be retrieved via a getter method. If no getter is defined, this + // just retrieves the object's property. + // + // For example, if the widget has properties `foo` and `bar` + // and a method named `_getFooAttr()`, calling: + // `myWidget.get("foo")` would be equivalent to calling + // `widget._getFooAttr()` and `myWidget.get("bar")` + // would be equivalent to the expression + // `widget.bar2` + var names = this._getAttrNames(name); + return this[names.g] ? this[names.g]() : this[name]; + }, + + set: function(name, value){ + // summary: + // Set a property on a widget + // name: + // The property to set. + // value: + // The value to set in the property. + // description: + // Sets named properties on a widget which may potentially be handled by a + // setter in the widget. + // + // For example, if the widget has properties `foo` and `bar` + // and a method named `_setFooAttr()`, calling + // `myWidget.set("foo", "Howdy!")` would be equivalent to calling + // `widget._setFooAttr("Howdy!")` and `myWidget.set("bar", 3)` + // would be equivalent to the statement `widget.bar = 3;` + // + // set() may also be called with a hash of name/value pairs, ex: + // + // | myWidget.set({ + // | foo: "Howdy", + // | bar: 3 + // | }); + // + // This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)` + + if(typeof name === "object"){ + for(var x in name){ + this.set(x, name[x]); + } + return this; + } + var names = this._getAttrNames(name), + setter = this[names.s]; + if(lang.isFunction(setter)){ + // use the explicit setter + var result = setter.apply(this, Array.prototype.slice.call(arguments, 1)); + }else{ + // Mapping from widget attribute to DOMNode attribute/value/etc. + // Map according to: + // 1. attributeMap setting, if one exists (TODO: attributeMap deprecated, remove in 2.0) + // 2. _setFooAttr: {...} type attribute in the widget (if one exists) + // 3. apply to focusNode or domNode if standard attribute name, excluding funcs like onClick. + // Checks if an attribute is a "standard attribute" by whether the DOMNode JS object has a similar + // attribute name (ex: accept-charset attribute matches jsObject.acceptCharset). + // Note also that Tree.focusNode() is a function not a DOMNode, so test for that. + var defaultNode = this.focusNode && !lang.isFunction(this.focusNode) ? "focusNode" : "domNode", + tag = this[defaultNode].tagName, + attrsForTag = tagAttrs[tag] || (tagAttrs[tag] = getAttrs(this[defaultNode])), + map = name in this.attributeMap ? this.attributeMap[name] : + names.s in this ? this[names.s] : + ((names.l in attrsForTag && typeof value != "function") || + /^aria-|^data-|^role$/.test(name)) ? defaultNode : null; + if(map != null){ + this._attrToDom(name, value, map); + } + this._set(name, value); + } + return result || this; + }, + + _attrPairNames: {}, // shared between all widgets + _getAttrNames: function(name){ + // summary: + // Helper function for get() and set(). + // Caches attribute name values so we don't do the string ops every time. + // tags: + // private + + var apn = this._attrPairNames; + if(apn[name]){ return apn[name]; } + var uc = name.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); }); + return (apn[name] = { + n: name+"Node", + s: "_set"+uc+"Attr", // converts dashes to camel case, ex: accept-charset --> _setAcceptCharsetAttr + g: "_get"+uc+"Attr", + l: uc.toLowerCase() // lowercase name w/out dashes, ex: acceptcharset + }); + }, + + _set: function(/*String*/ name, /*anything*/ value){ + // summary: + // Helper function to set new value for specified attribute, and call handlers + // registered with watch() if the value has changed. + var oldValue = this[name]; + this[name] = value; + if(this._watchCallbacks && this._created && value !== oldValue){ + this._watchCallbacks(name, oldValue, value); + } + }, + + on: function(/*String*/ type, /*Function*/ func){ + // summary: + // Call specified function when event occurs, ex: myWidget.on("click", function(){ ... }). + // description: + // Call specified function when event `type` occurs, ex: `myWidget.on("click", function(){ ... })`. + // Note that the function is not run in any particular scope, so if (for example) you want it to run in the + // widget's scope you must do `myWidget.on("click", lang.hitch(myWidget, func))`. + + return aspect.after(this, this._onMap(type), func, true); + }, + + _onMap: function(/*String*/ type){ + // summary: + // Maps on() type parameter (ex: "mousemove") to method name (ex: "onMouseMove") + var ctor = this.constructor, map = ctor._onMap; + if(!map){ + map = (ctor._onMap = {}); + for(var attr in ctor.prototype){ + if(/^on/.test(attr)){ + map[attr.replace(/^on/, "").toLowerCase()] = attr; + } + } + } + return map[type.toLowerCase()]; // String + }, + + toString: function(){ + // summary: + // Returns a string that represents the widget + // description: + // When a widget is cast to a string, this method will be used to generate the + // output. Currently, it does not implement any sort of reversible + // serialization. + return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String + }, + + getChildren: function(){ + // summary: + // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode. + // Does not return nested widgets, nor widgets that are part of this widget's template. + return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit._Widget[] + }, + + getParent: function(){ + // summary: + // Returns the parent widget of this widget + return registry.getEnclosingWidget(this.domNode.parentNode); + }, + + connect: function( + /*Object|null*/ obj, + /*String|Function*/ event, + /*String|Function*/ method){ + // summary: + // Connects specified obj/event to specified method of this object + // and registers for disconnect() on widget destroy. + // description: + // Provide widget-specific analog to dojo.connect, except with the + // implicit use of this widget as the target object. + // Events connected with `this.connect` are disconnected upon + // destruction. + // returns: + // A handle that can be passed to `disconnect` in order to disconnect before + // the widget is destroyed. + // example: + // | var btn = new dijit.form.Button(); + // | // when foo.bar() is called, call the listener we're going to + // | // provide in the scope of btn + // | btn.connect(foo, "bar", function(){ + // | console.debug(this.toString()); + // | }); + // tags: + // protected + + var handle = connect.connect(obj, event, this, method); + this._connects.push(handle); + return handle; // _Widget.Handle + }, + + disconnect: function(handle){ + // summary: + // Disconnects handle created by `connect`. + // Also removes handle from this widget's list of connects. + // tags: + // protected + var i = array.indexOf(this._connects, handle); + if(i != -1){ + handle.remove(); + this._connects.splice(i, 1); + } + }, + + subscribe: function(t, method){ + // summary: + // Subscribes to the specified topic and calls the specified method + // of this object and registers for unsubscribe() on widget destroy. + // description: + // Provide widget-specific analog to dojo.subscribe, except with the + // implicit use of this widget as the target object. + // t: String + // The topic + // method: Function + // The callback + // example: + // | var btn = new dijit.form.Button(); + // | // when /my/topic is published, this button changes its label to + // | // be the parameter of the topic. + // | btn.subscribe("/my/topic", function(v){ + // | this.set("label", v); + // | }); + // tags: + // protected + var handle = topic.subscribe(t, lang.hitch(this, method)); + this._connects.push(handle); + return handle; // _Widget.Handle + }, + + unsubscribe: function(/*Object*/ handle){ + // summary: + // Unsubscribes handle created by this.subscribe. + // Also removes handle from this widget's list of subscriptions + // tags: + // protected + this.disconnect(handle); + }, + + isLeftToRight: function(){ + // summary: + // Return this widget's explicit or implicit orientation (true for LTR, false for RTL) + // tags: + // protected + return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(); //Boolean + }, + + isFocusable: function(){ + // summary: + // Return true if this widget can currently be focused + // and false if not + return this.focus && (domStyle.get(this.domNode, "display") != "none"); + }, + + placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){ + // summary: + // Place this widget's domNode reference somewhere in the DOM based + // on standard domConstruct.place conventions, or passing a Widget reference that + // contains and addChild member. + // + // description: + // A convenience function provided in all _Widgets, providing a simple + // shorthand mechanism to put an existing (or newly created) Widget + // somewhere in the dom, and allow chaining. + // + // reference: + // The String id of a domNode, a domNode reference, or a reference to a Widget possessing + // an addChild method. + // + // position: + // If passed a string or domNode reference, the position argument + // accepts a string just as domConstruct.place does, one of: "first", "last", + // "before", or "after". + // + // If passed a _Widget reference, and that widget reference has an ".addChild" method, + // it will be called passing this widget instance into that method, supplying the optional + // position index passed. + // + // returns: + // dijit._Widget + // Provides a useful return of the newly created dijit._Widget instance so you + // can "chain" this function by instantiating, placing, then saving the return value + // to a variable. + // + // example: + // | // create a Button with no srcNodeRef, and place it in the body: + // | var button = new dijit.form.Button({ label:"click" }).placeAt(win.body()); + // | // now, 'button' is still the widget reference to the newly created button + // | button.on("click", function(e){ console.log('click'); })); + // + // example: + // | // create a button out of a node with id="src" and append it to id="wrapper": + // | var button = new dijit.form.Button({},"src").placeAt("wrapper"); + // + // example: + // | // place a new button as the first element of some div + // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first"); + // + // example: + // | // create a contentpane and add it to a TabContainer + // | var tc = dijit.byId("myTabs"); + // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc) + + if(reference.declaredClass && reference.addChild){ + reference.addChild(this, position); + }else{ + domConstruct.place(this.domNode, reference, position); + } + return this; + }, + + getTextDir: function(/*String*/ text,/*String*/ originalDir){ + // summary: + // Return direction of the text. + // The function overridden in the _BidiSupport module, + // its main purpose is to calculate the direction of the + // text, if was defined by the programmer through textDir. + // tags: + // protected. + return originalDir; + }, + + applyTextDir: function(/*===== element, text =====*/){ + // summary: + // The function overridden in the _BidiSupport module, + // originally used for setting element.dir according to this.textDir. + // In this case does nothing. + // element: DOMNode + // text: String + // tags: + // protected. + } +}); + +}); + +}, +'dojo/dnd/Moveable':function(){ +define(["../main", "../Evented", "../touch", "./Mover"], function(dojo, Evented, touch) { + // module: + // dojo/dnd/Moveable + // summary: + // TODOC + + +/*===== +dojo.declare("dojo.dnd.__MoveableArgs", [], { + // handle: Node||String + // A node (or node's id), which is used as a mouse handle. + // If omitted, the node itself is used as a handle. + handle: null, + + // delay: Number + // delay move by this number of pixels + delay: 0, + + // skip: Boolean + // skip move of form elements + skip: false, + + // mover: Object + // a constructor of custom Mover + mover: dojo.dnd.Mover +}); +=====*/ + +dojo.declare("dojo.dnd.Moveable", [Evented], { + // object attributes (for markup) + handle: "", + delay: 0, + skip: false, + + constructor: function(node, params){ + // summary: + // an object, which makes a node moveable + // node: Node + // a node (or node's id) to be moved + // params: dojo.dnd.__MoveableArgs? + // optional parameters + this.node = dojo.byId(node); + if(!params){ params = {}; } + this.handle = params.handle ? dojo.byId(params.handle) : null; + if(!this.handle){ this.handle = this.node; } + this.delay = params.delay > 0 ? params.delay : 0; + this.skip = params.skip; + this.mover = params.mover ? params.mover : dojo.dnd.Mover; + this.events = [ + dojo.connect(this.handle, touch.press, this, "onMouseDown"), + // cancel text selection and text dragging + dojo.connect(this.handle, "ondragstart", this, "onSelectStart"), + dojo.connect(this.handle, "onselectstart", this, "onSelectStart") + ]; + }, + + // markup methods + markupFactory: function(params, node, ctor){ + return new ctor(node, params); + }, + + // methods + destroy: function(){ + // summary: + // stops watching for possible move, deletes all references, so the object can be garbage-collected + dojo.forEach(this.events, dojo.disconnect); + this.events = this.node = this.handle = null; + }, + + // mouse event processors + onMouseDown: function(e){ + // summary: + // event processor for onmousedown/ontouchstart, creates a Mover for the node + // e: Event + // mouse/touch event + if(this.skip && dojo.dnd.isFormElement(e)){ return; } + if(this.delay){ + this.events.push( + dojo.connect(this.handle, touch.move, this, "onMouseMove"), + dojo.connect(this.handle, touch.release, this, "onMouseUp") + ); + this._lastX = e.pageX; + this._lastY = e.pageY; + }else{ + this.onDragDetected(e); + } + dojo.stopEvent(e); + }, + onMouseMove: function(e){ + // summary: + // event processor for onmousemove/ontouchmove, used only for delayed drags + // e: Event + // mouse/touch event + if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){ + this.onMouseUp(e); + this.onDragDetected(e); + } + dojo.stopEvent(e); + }, + onMouseUp: function(e){ + // summary: + // event processor for onmouseup, used only for delayed drags + // e: Event + // mouse event + for(var i = 0; i < 2; ++i){ + dojo.disconnect(this.events.pop()); + } + dojo.stopEvent(e); + }, + onSelectStart: function(e){ + // summary: + // event processor for onselectevent and ondragevent + // e: Event + // mouse event + if(!this.skip || !dojo.dnd.isFormElement(e)){ + dojo.stopEvent(e); + } + }, + + // local events + onDragDetected: function(/* Event */ e){ + // summary: + // called when the drag is detected; + // responsible for creation of the mover + new this.mover(this.node, e, this); + }, + onMoveStart: function(/* dojo.dnd.Mover */ mover){ + // summary: + // called before every move operation + dojo.publish("/dnd/move/start", [mover]); + dojo.addClass(dojo.body(), "dojoMove"); + dojo.addClass(this.node, "dojoMoveItem"); + }, + onMoveStop: function(/* dojo.dnd.Mover */ mover){ + // summary: + // called after every move operation + dojo.publish("/dnd/move/stop", [mover]); + dojo.removeClass(dojo.body(), "dojoMove"); + dojo.removeClass(this.node, "dojoMoveItem"); + }, + onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){ + // summary: + // called during the very first move notification; + // can be used to initialize coordinates, can be overwritten. + + // default implementation does nothing + }, + onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){ + // summary: + // called during every move notification; + // should actually move the node; can be overwritten. + this.onMoving(mover, leftTop); + var s = mover.node.style; + s.left = leftTop.l + "px"; + s.top = leftTop.t + "px"; + this.onMoved(mover, leftTop); + }, + onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){ + // summary: + // called before every incremental move; can be overwritten. + + // default implementation does nothing + }, + onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){ + // summary: + // called after every incremental move; can be overwritten. + + // default implementation does nothing + } +}); + +return dojo.dnd.Moveable; +}); + +}}}); + +require(["dojo/i18n"], function(i18n){ +i18n._preloadLocalizations("dojox/grid/nls/DataGrid", ["nl-nl","en-us","da","fi-fi","pt-pt","hu","sk","sl","pl","ca","sv","zh-tw","ar","en-gb","he-il","de-de","ko-kr","ja-jp","nb","ru","es-es","th","cs","it-it","pt-br","fr-fr","el","tr","zh-cn"]); +}); +define("dojox/grid/DataGrid", [ + "../main", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/json", + "dojo/_base/sniff", + "dojo/_base/declare", + "./_Grid", + "./DataSelection", + "dojo/_base/html" +], function(dojox, array, lang, json, has, declare, _Grid, DataSelection, html){ + +/*===== +declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, { + constructor: function(){ + // field: String? + // The attribute to read from the dojo.data item for the row. + // fields: String[]? + // An array of fields to grab the values of and pass as an array to the grid + // get: Function? + // function(rowIndex, item?){} rowIndex is of type Integer, item is of type + // Object. This function will be called when a cell requests data. Returns + // the unformatted data for the cell. + } +}); +=====*/ + +/*===== +declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, { + constructor: function(){ + // cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]? + // The structure of the cells within this grid. + // defaultCell: dojox.grid.__DataCellDef? + // A cell definition with default values for all cells in this view. If + // a property is defined in a cell definition in the "cells" array and + // this property, the cell definition's property will override this + // property's property. + } +}); +=====*/ + +var DataGrid = declare("dojox.grid.DataGrid", _Grid, { + store: null, + query: null, + queryOptions: null, + fetchText: '...', + sortFields: null, + + // updateDelay: int + // Time, in milliseconds, to delay updates automatically so that multiple + // calls to onSet/onNew/onDelete don't keep rerendering the grid. Set + // to 0 to immediately cause updates. A higher value will result in + // better performance at the expense of responsiveness of the grid. + updateDelay: 1, + +/*===== + // structure: dojox.grid.__DataViewDef|dojox.grid.__DataViewDef[]|dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]] + // View layout defintion. + structure: '', +=====*/ + + // You can specify items instead of a query, if you like. They do not need + // to be loaded - but the must be items in the store + items: null, + + _store_connects: null, + _by_idty: null, + _by_idx: null, + _cache: null, + _pages: null, + _pending_requests: null, + _bop: -1, + _eop: -1, + _requests: 0, + rowCount: 0, + + _isLoaded: false, + _isLoading: false, + + //keepSelection: Boolean + // Whether keep selection after sort, filter etc. + keepSelection: false, + + postCreate: function(){ + this._pages = []; + this._store_connects = []; + this._by_idty = {}; + this._by_idx = []; + this._cache = []; + this._pending_requests = {}; + + this._setStore(this.store); + this.inherited(arguments); + }, + + destroy: function(){ + this.selection.destroy(); + this.inherited(arguments); + }, + + createSelection: function(){ + this.selection = new DataSelection(this); + }, + + get: function(inRowIndex, inItem){ + // summary: Default data getter. + // description: + // Provides data to display in a grid cell. Called in grid cell context. + // So this.cell.index is the column index. + // inRowIndex: Integer + // Row for which to provide data + // returns: + // Data to display for a given grid cell. + + if(inItem && this.field == "_item" && !this.fields){ + return inItem; + }else if(inItem && this.fields){ + var ret = []; + var s = this.grid.store; + array.forEach(this.fields, function(f){ + ret = ret.concat(s.getValues(inItem, f)); + }); + return ret; + }else if(!inItem && typeof inRowIndex === "string"){ + return this.inherited(arguments); + } + return (!inItem ? this.defaultValue : (!this.field ? this.value : (this.field == "_item" ? inItem : this.grid.store.getValue(inItem, this.field)))); + }, + + _checkUpdateStatus: function(){ + if(this.updateDelay > 0){ + var iStarted = false; + if(this._endUpdateDelay){ + clearTimeout(this._endUpdateDelay); + delete this._endUpdateDelay; + iStarted = true; + } + if(!this.updating){ + this.beginUpdate(); + iStarted = true; + } + if(iStarted){ + var _this = this; + this._endUpdateDelay = setTimeout(function(){ + delete _this._endUpdateDelay; + _this.endUpdate(); + }, this.updateDelay); + } + } + }, + + _onSet: function(item, attribute, oldValue, newValue){ + this._checkUpdateStatus(); + var idx = this.getItemIndex(item); + if(idx>-1){ + this.updateRow(idx); + } + }, + + _createItem: function(item, index){ + var idty = this._hasIdentity ? this.store.getIdentity(item) : json.toJson(this.query) + ":idx:" + index + ":sort:" + json.toJson(this.getSortProps()); + var o = this._by_idty[idty] = { idty: idty, item: item }; + return o; + }, + + _addItem: function(item, index, noUpdate){ + this._by_idx[index] = this._createItem(item, index); + if(!noUpdate){ + this.updateRow(index); + } + }, + + _onNew: function(item, parentInfo){ + this._checkUpdateStatus(); + var rowCount = this.get('rowCount'); + this._addingItem = true; + this.updateRowCount(rowCount+1); + this._addingItem = false; + this._addItem(item, rowCount); + this.showMessage(); + }, + + _onDelete: function(item){ + this._checkUpdateStatus(); + var idx = this._getItemIndex(item, true); + + if(idx >= 0){ + // When a row is deleted, all rest rows are shifted down, + // and migrate from page to page. If some page is not + // loaded yet empty rows can migrate to initialized pages + // without refreshing. It causes empty rows in some pages, see: + // http://bugs.dojotoolkit.org/ticket/6818 + // this code fix this problem by reseting loaded page info + this._pages = []; + this._bop = -1; + this._eop = -1; + + var o = this._by_idx[idx]; + this._by_idx.splice(idx, 1); + delete this._by_idty[o.idty]; + this.updateRowCount(this.get('rowCount')-1); + if(this.get('rowCount') === 0){ + this.showMessage(this.noDataMessage); + } + } + if(this.selection.isSelected(idx)){ + this.selection.deselect(idx); + this.selection.selected.splice(idx, 1); + } + }, + + _onRevert: function(){ + this._refresh(); + }, + + setStore: function(store, query, queryOptions){ + if(this._requestsPending(0)){ + return; + } + this._setQuery(query, queryOptions); + this._setStore(store); + this._refresh(true); + }, + + setQuery: function(query, queryOptions){ + if(this._requestsPending(0)){ + return; + } + this._setQuery(query, queryOptions); + this._refresh(true); + }, + + setItems: function(items){ + this.items = items; + this._setStore(this.store); + this._refresh(true); + }, + + _setQuery: function(query, queryOptions){ + this.query = query; + this.queryOptions = queryOptions || this.queryOptions; + }, + + _setStore: function(store){ + if(this.store && this._store_connects){ + array.forEach(this._store_connects, this.disconnect, this); + } + this.store = store; + + if(this.store){ + var f = this.store.getFeatures(); + var h = []; + + this._canEdit = !!f["dojo.data.api.Write"] && !!f["dojo.data.api.Identity"]; + this._hasIdentity = !!f["dojo.data.api.Identity"]; + + if(!!f["dojo.data.api.Notification"] && !this.items){ + h.push(this.connect(this.store, "onSet", "_onSet")); + h.push(this.connect(this.store, "onNew", "_onNew")); + h.push(this.connect(this.store, "onDelete", "_onDelete")); + } + if(this._canEdit){ + h.push(this.connect(this.store, "revert", "_onRevert")); + } + + this._store_connects = h; + } + }, + + _onFetchBegin: function(size, req){ + if(!this.scroller){ return; } + if(this.rowCount != size){ + if(req.isRender){ + this.scroller.init(size, this.keepRows, this.rowsPerPage); + this.rowCount = size; + this._setAutoHeightAttr(this.autoHeight, true); + this._skipRowRenormalize = true; + this.prerender(); + this._skipRowRenormalize = false; + }else{ + this.updateRowCount(size); + } + } + if(!size){ + this.views.render(); + this._resize(); + this.showMessage(this.noDataMessage); + this.focus.initFocusView(); + }else{ + this.showMessage(); + } + }, + + _onFetchComplete: function(items, req){ + if(!this.scroller){ return; } + if(items && items.length > 0){ + //console.log(items); + array.forEach(items, function(item, idx){ + this._addItem(item, req.start+idx, true); + }, this); + this.updateRows(req.start, items.length); + if(req.isRender){ + this.setScrollTop(0); + this.postrender(); + }else if(this._lastScrollTop){ + this.setScrollTop(this._lastScrollTop); + } + if(has("ie")){ + html.setSelectable(this.domNode, this.selectable); + } + } + delete this._lastScrollTop; + if(!this._isLoaded){ + this._isLoading = false; + this._isLoaded = true; + } + this._pending_requests[req.start] = false; + }, + + _onFetchError: function(err, req){ + console.log(err); + delete this._lastScrollTop; + if(!this._isLoaded){ + this._isLoading = false; + this._isLoaded = true; + this.showMessage(this.errorMessage); + } + this._pending_requests[req.start] = false; + this.onFetchError(err, req); + }, + + onFetchError: function(err, req){ + }, + + _fetch: function(start, isRender){ + start = start || 0; + if(this.store && !this._pending_requests[start]){ + if(!this._isLoaded && !this._isLoading){ + this._isLoading = true; + this.showMessage(this.loadingMessage); + } + this._pending_requests[start] = true; + //console.log("fetch: ", start); + try{ + if(this.items){ + var items = this.items; + var store = this.store; + this.rowsPerPage = items.length; + var req = { + start: start, + count: this.rowsPerPage, + isRender: isRender + }; + this._onFetchBegin(items.length, req); + + // Load them if we need to + var waitCount = 0; + array.forEach(items, function(i){ + if(!store.isItemLoaded(i)){ waitCount++; } + }); + if(waitCount === 0){ + this._onFetchComplete(items, req); + }else{ + var onItem = function(item){ + waitCount--; + if(waitCount === 0){ + this._onFetchComplete(items, req); + } + }; + array.forEach(items, function(i){ + if(!store.isItemLoaded(i)){ + store.loadItem({item: i, onItem: onItem, scope: this}); + } + }, this); + } + }else{ + this.store.fetch({ + start: start, + count: this.rowsPerPage, + query: this.query, + sort: this.getSortProps(), + queryOptions: this.queryOptions, + isRender: isRender, + onBegin: lang.hitch(this, "_onFetchBegin"), + onComplete: lang.hitch(this, "_onFetchComplete"), + onError: lang.hitch(this, "_onFetchError") + }); + } + }catch(e){ + this._onFetchError(e, {start: start, count: this.rowsPerPage}); + } + } + }, + + _clearData: function(){ + this.updateRowCount(0); + this._by_idty = {}; + this._by_idx = []; + this._pages = []; + this._bop = this._eop = -1; + this._isLoaded = false; + this._isLoading = false; + }, + + getItem: function(idx){ + var data = this._by_idx[idx]; + if(!data||(data&&!data.item)){ + this._preparePage(idx); + return null; + } + return data.item; + }, + + getItemIndex: function(item){ + return this._getItemIndex(item, false); + }, + + _getItemIndex: function(item, isDeleted){ + if(!isDeleted && !this.store.isItem(item)){ + return -1; + } + + var idty = this._hasIdentity ? this.store.getIdentity(item) : null; + + for(var i=0, l=this._by_idx.length; i<l; i++){ + var d = this._by_idx[i]; + if(d && ((idty && d.idty == idty) || (d.item === item))){ + return i; + } + } + return -1; + }, + + filter: function(query, reRender){ + this.query = query; + if(reRender){ + this._clearData(); + } + this._fetch(); + }, + + _getItemAttr: function(idx, attr){ + var item = this.getItem(idx); + return (!item ? this.fetchText : this.store.getValue(item, attr)); + }, + + // rendering + _render: function(){ + if(this.domNode.parentNode){ + this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage); + this.prerender(); + this._fetch(0, true); + } + }, + + // paging + _requestsPending: function(inRowIndex){ + return this._pending_requests[inRowIndex]; + }, + + _rowToPage: function(inRowIndex){ + return (this.rowsPerPage ? Math.floor(inRowIndex / this.rowsPerPage) : inRowIndex); + }, + + _pageToRow: function(inPageIndex){ + return (this.rowsPerPage ? this.rowsPerPage * inPageIndex : inPageIndex); + }, + + _preparePage: function(inRowIndex){ + if((inRowIndex < this._bop || inRowIndex >= this._eop) && !this._addingItem){ + var pageIndex = this._rowToPage(inRowIndex); + this._needPage(pageIndex); + this._bop = pageIndex * this.rowsPerPage; + this._eop = this._bop + (this.rowsPerPage || this.get('rowCount')); + } + }, + + _needPage: function(inPageIndex){ + if(!this._pages[inPageIndex]){ + this._pages[inPageIndex] = true; + this._requestPage(inPageIndex); + } + }, + + _requestPage: function(inPageIndex){ + var row = this._pageToRow(inPageIndex); + var count = Math.min(this.rowsPerPage, this.get('rowCount') - row); + if(count > 0){ + this._requests++; + if(!this._requestsPending(row)){ + setTimeout(lang.hitch(this, "_fetch", row, false), 1); + //this.requestRows(row, count); + } + } + }, + + getCellName: function(inCell){ + return inCell.field; + //console.log(inCell); + }, + + _refresh: function(isRender){ + this._clearData(); + this._fetch(0, isRender); + }, + + sort: function(){ + this.edit.apply(); + this._lastScrollTop = this.scrollTop; + this._refresh(); + }, + + canSort: function(){ + return (!this._isLoading); + }, + + getSortProps: function(){ + var c = this.getCell(this.getSortIndex()); + if(!c){ + if(this.sortFields){ + return this.sortFields; + } + return null; + }else{ + var desc = c["sortDesc"]; + var si = !(this.sortInfo>0); + if(typeof desc == "undefined"){ + desc = si; + }else{ + desc = si ? !desc : desc; + } + return [{ attribute: c.field, descending: desc }]; + } + }, + + styleRowState: function(inRow){ + // summary: Perform row styling + if(this.store && this.store.getState){ + var states=this.store.getState(inRow.index), c=''; + for(var i=0, ss=["inflight", "error", "inserting"], s; s=ss[i]; i++){ + if(states[s]){ + c = ' dojoxGridRow-' + s; + break; + } + } + inRow.customClasses += c; + } + }, + + onStyleRow: function(inRow){ + this.styleRowState(inRow); + this.inherited(arguments); + }, + + // editing + canEdit: function(inCell, inRowIndex){ + return this._canEdit; + }, + + _copyAttr: function(idx, attr){ + var row = {}; + var backstop = {}; + var src = this.getItem(idx); + return this.store.getValue(src, attr); + }, + + doStartEdit: function(inCell, inRowIndex){ + if(!this._cache[inRowIndex]){ + this._cache[inRowIndex] = this._copyAttr(inRowIndex, inCell.field); + } + this.onStartEdit(inCell, inRowIndex); + }, + + doApplyCellEdit: function(inValue, inRowIndex, inAttrName){ + this.store.fetchItemByIdentity({ + identity: this._by_idx[inRowIndex].idty, + onItem: lang.hitch(this, function(item){ + var oldValue = this.store.getValue(item, inAttrName); + if(typeof oldValue == 'number'){ + inValue = isNaN(inValue) ? inValue : parseFloat(inValue); + }else if(typeof oldValue == 'boolean'){ + inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue; + }else if(oldValue instanceof Date){ + var asDate = new Date(inValue); + inValue = isNaN(asDate.getTime()) ? inValue : asDate; + } + this.store.setValue(item, inAttrName, inValue); + this.onApplyCellEdit(inValue, inRowIndex, inAttrName); + }) + }); + }, + + doCancelEdit: function(inRowIndex){ + var cache = this._cache[inRowIndex]; + if(cache){ + this.updateRow(inRowIndex); + delete this._cache[inRowIndex]; + } + this.onCancelEdit.apply(this, arguments); + }, + + doApplyEdit: function(inRowIndex, inDataAttr){ + var cache = this._cache[inRowIndex]; + /*if(cache){ + var data = this.getItem(inRowIndex); + if(this.store.getValue(data, inDataAttr) != cache){ + this.update(cache, data, inRowIndex); + } + delete this._cache[inRowIndex]; + }*/ + this.onApplyEdit(inRowIndex); + }, + + removeSelectedRows: function(){ + // summary: + // Remove the selected rows from the grid. + if(this._canEdit){ + this.edit.apply(); + var fx = lang.hitch(this, function(items){ + if(items.length){ + array.forEach(items, this.store.deleteItem, this.store); + this.selection.clear(); + } + }); + if(this.allItemsSelected){ + this.store.fetch({ + query: this.query, + queryOptions: this.queryOptions, + onComplete: fx}); + }else{ + fx(this.selection.getSelected()); + } + } + } +}); + +DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){ + var field = lang.trim(html.attr(node, "field")||""); + if(field){ + cellDef.field = field; + } + cellDef.field = cellDef.field||cellDef.name; + var fields = lang.trim(html.attr(node, "fields")||""); + if(fields){ + cellDef.fields = fields.split(","); + } + if(cellFunc){ + cellFunc(node, cellDef); + } +}; + +DataGrid.markupFactory = function(props, node, ctor, cellFunc){ + return _Grid.markupFactory(props, node, ctor, + lang.partial(DataGrid.cell_markupFactory, cellFunc)); +}; + +return DataGrid; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/DataSelection.js b/js/dojo-1.7.2/dojox/grid/DataSelection.js new file mode 100644 index 0000000..c3c630e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/DataSelection.js @@ -0,0 +1,82 @@ +//>>built +define("dojox/grid/DataSelection", [ + "dojo/_base/declare", + "./_SelectionPreserver", + "./Selection" +], function(declare, _SelectionPreserver, Selection){ + +return declare("dojox.grid.DataSelection", Selection, { + constructor: function(grid){ + if(grid.keepSelection){ + this.preserver = new _SelectionPreserver(this); + } + }, + + destroy: function(){ + if(this.preserver){ + this.preserver.destroy(); + } + }, + + getFirstSelected: function(){ + var idx = Selection.prototype.getFirstSelected.call(this); + + if(idx == -1){ return null; } + return this.grid.getItem(idx); + }, + + getNextSelected: function(inPrev){ + var old_idx = this.grid.getItemIndex(inPrev); + var idx = Selection.prototype.getNextSelected.call(this, old_idx); + + if(idx == -1){ return null; } + return this.grid.getItem(idx); + }, + + getSelected: function(){ + var result = []; + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + result.push(this.grid.getItem(i)); + } + } + return result; + }, + + addToSelection: function(inItemOrIndex){ + if(this.mode == 'none'){ return; } + var idx = null; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + Selection.prototype.addToSelection.call(this, idx); + }, + + deselect: function(inItemOrIndex){ + if(this.mode == 'none'){ return; } + var idx = null; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + Selection.prototype.deselect.call(this, idx); + }, + + deselectAll: function(inItemOrIndex){ + var idx = null; + if(inItemOrIndex || typeof inItemOrIndex == "number"){ + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + Selection.prototype.deselectAll.call(this, idx); + }else{ + this.inherited(arguments); + } + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/EnhancedGrid.js new file mode 100644 index 0000000..9852dba --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/EnhancedGrid.js @@ -0,0 +1,263 @@ +//>>built +define("dojox/grid/EnhancedGrid", [ + "dojo/_base/kernel", + "../main", + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/array", + "dojo/_base/sniff", + "dojo/dom", + "dojo/dom-geometry", + "dojo/i18n", + "./DataGrid", + "./DataSelection", + "./enhanced/_PluginManager", + "./enhanced/plugins/_SelectionPreserver",//default loaded plugin + "dojo/i18n!./enhanced/nls/EnhancedGrid" +], function(dojo, dojox, declare, lang, array, has, dom, domGeometry, i18n, + DataGrid, DataSelection, _PluginManager, _SelectionPreserver){ + +dojo.experimental("dojox.grid.EnhancedGrid"); + +var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, { + // summary: + // Provides enhanced features based on DataGrid + // + // description: + // EnhancedGrid features are implemented as plugins that could be loaded on demand. + // Explicit dojo.require() is needed to use these feature plugins. + // + // example: + // A quick sample to use EnhancedGrid features: + // + // Step 1. Load EnhancedGrid and required features + // | <script type="text/javascript"> + // | dojo.require("dojox.grid.EnhancedGrid"); + // | dojo.require("dojox.grid.enhanced.plugins.DnD"); + // | dojo.require("dojox.grid.enhanced.plugins.Menu"); + // | dojo.require("dojox.grid.enhanced.plugins.NestedSorting"); + // | dojo.require("dojox.grid.enhanced.plugins.IndirectSelection"); + // | </script> + // + // Step 2. Use EnhancedGrid + // - Via HTML markup + // | <div dojoType="dojox.grid.EnhancedGrid" ... + // | plugins="{nestedSorting: true, dnd: true, indirectSelection: true, + // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId", + // | selectedRegionMenu:"selectedRegionMenuId"}}"> + // | ... + // | </div> + // + // - Or via JavaScript + // | <script type="text/javascript"> + // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true, + // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}}, + // | ... }, dojo.byId('gridDiv')); + // | grid.startup(); + // | </script> + // + // + // Plugin Support + // [Note: Plugin support is still experimental] + // + // You can either customize the default plugins or add new ones, more details please see + // - dojox.grid.enhanced._PluginManager + // - dojox.grid.enhanced._Plugin + // - dojox.grid.enhanced.plugins.* + + //plugins: Object + // Plugin properties, e.g. {nestedSorting: true, dnd: true, ...} + plugins: null, + + //pluginMgr: Object + // Singleton plugin manager + pluginMgr: null, + + //_pluginMgrClass: Object + // Default plugin manager class + _pluginMgrClass: _PluginManager, + + postMixInProperties: function(){ + //load nls bundle + this._nls = i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang); + this.inherited(arguments); + }, + postCreate: function(){ + //create plugin manager + this.pluginMgr = new this._pluginMgrClass(this); + this.pluginMgr.preInit(); + this.inherited(arguments); + this.pluginMgr.postInit(); + }, + plugin: function(/*String*/name){ + // summary: + // An easier way for getting a plugin, e.g. grid.plugin('dnd') + return this.pluginMgr.getPlugin(name); + }, + startup: function(){ + this.inherited(arguments); + this.pluginMgr.startup(); + }, + createSelection: function(){ + this.selection = new dojox.grid.enhanced.DataSelection(this); + }, + canSort: function(colIndex, field){ + // summary: + // Overwritten + return true; + }, + doKeyEvent: function(e){ + // summary: + // Overwritten, see _Grid.doKeyEvent() + try{ + var view = this.focus.focusView; + view.content.decorateEvent(e); + if(!e.cell){ view.header.decorateEvent(e); } + }catch(e){} + this.inherited(arguments); + }, + doApplyCellEdit: function(inValue, inRowIndex, inAttrName){ + // summary: + // Overwritten, see DataGrid.doApplyCellEdit() + if(!inAttrName){ + this.invalidated[inRowIndex] = true; + return; + } + this.inherited(arguments); + }, + mixin: function(target, source){ + var props = {}; + for(var p in source){ + if(p == '_inherited' || p == 'declaredClass' || p == 'constructor' || + source['privates'] && source['privates'][p]){ + continue; + } + props[p] = source[p]; + } + lang.mixin(target, props); + }, + _copyAttr: function(idx, attr){ + // summary: + // Overwritten, see DataGrid._copyAttr() + // Fix cell TAB navigation for single click editing + if(!attr){ return; } + return this.inherited(arguments); + }, + _getHeaderHeight: function(){ + // summary: + // Overwritten, see _Grid._getHeaderHeight() + // Should include borders/margins of this.viewsHeaderNode + this.inherited(arguments); + return domGeometry.getMarginBox(this.viewsHeaderNode).h; + }, + _fetch: function(start, isRender){ + // summary: + // Overwritten, see DataGrid._fetch() + if(this.items){ + return this.inherited(arguments); + } + start = start || 0; + if(this.store && !this._pending_requests[start]){ + if(!this._isLoaded && !this._isLoading){ + this._isLoading = true; + this.showMessage(this.loadingMessage); + } + this._pending_requests[start] = true; + try{ + var req = { + start: start, + count: this.rowsPerPage, + query: this.query, + sort: this.getSortProps(), + queryOptions: this.queryOptions, + isRender: isRender, + onBegin: lang.hitch(this, "_onFetchBegin"), + onComplete: lang.hitch(this, "_onFetchComplete"), + onError: lang.hitch(this, "_onFetchError") + }; + this._storeLayerFetch(req); + }catch(e){ + this._onFetchError(e, {start: start, count: this.rowsPerPage}); + } + } + return 0; + }, + _storeLayerFetch: function(req){ + // summary: + // Extracted fetch specifically for store layer use + this.store.fetch(req); + }, + getCellByField: function(field){ + return array.filter(this.layout.cells, function(cell){ + return cell.field == field; + })[0]; + }, + onMouseUp: function(e){ }, + createView: function(){ + // summary + // Overwrite: rewrite getCellX of view.header + var view = this.inherited(arguments); + if(has("mozilla")){ + var ascendDom = function(inNode, inWhile){ + for(var n = inNode; n && inWhile(n); n = n.parentNode){} + return n; + };//copied from dojox.grid._Builder + var makeNotTagName = function(inTagName){ + var name = inTagName.toUpperCase(); + return function(node){ return node.tagName != name; }; + };//copied from dojox.grid._Builder + + var func = view.header.getCellX; + view.header.getCellX = function(e){ + var x = func.call(view.header, e); + var n = ascendDom(e.target, makeNotTagName("th")); + if(n && n !== e.target && dom.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; } + return x; + }; + } + return view; + }, + destroy: function(){ + // summary: + // Destroy all resources + delete this._nls; + this.pluginMgr.destroy(); + this.inherited(arguments); + } +}); + +declare("dojox.grid.enhanced.DataSelection", DataSelection, { + constructor: function(grid){ + if(grid.keepSelection){ + if(this.preserver){ + this.preserver.destroy(); + } + this.preserver = new _SelectionPreserver(this); + } + }, + _range: function(inFrom, inTo){ + this.grid._selectingRange = true; + this.inherited(arguments); + this.grid._selectingRange = false; + this.onChanged(); + }, + deselectAll: function(inItemOrIndex){ + this.grid._selectingRange = true; + this.inherited(arguments); + this.grid._selectingRange = false; + this.onChanged(); + } +}); + +EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){ + return dojox.grid._Grid.markupFactory(props, node, ctor, + lang.partial(DataGrid.cell_markupFactory, cellFunc)); +}; + +EnhancedGrid.registerPlugin = function(clazz, props){ + _PluginManager.registerPlugin(clazz, props); +}; + +return EnhancedGrid; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js b/js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js new file mode 100644 index 0000000..3ad3030 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js @@ -0,0 +1,837 @@ +//>>built +require({cache:{ +'url:dojox/grid/resources/Expando.html':"<div class=\"dojoxGridExpando\"\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\n\t></div\n></div>\n"}}); +define("dojox/grid/LazyTreeGrid", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/event", + "dojo/_base/array", + "dojo/query", + "dojo/parser", + "dojo/dom-construct", + "dojo/dom-class", + "dojo/dom-style", + "dojo/dom-geometry", + "dojo/dom", + "dojo/keys", + "dojo/text!./resources/Expando.html", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "./TreeGrid", + "./_Builder", + "./_View", + "./_Layout", + "./cells/tree", + "./_RowManager", + "./_FocusManager", + "./_EditManager", + "./DataSelection", + "./util" +], function(dojo, declare, lang, event, array, query, parser, domConstruct, + domClass, domStyle, domGeometry, dom, keys, template, _widget, _templatedMixin, + TreeGrid, _Builder, _View, _Layout, TreeCell, _RowManager, _FocusManager, _EditManager, DataSelection, util){ + +var _LazyExpando = declare("dojox.grid._LazyExpando", [_widget, _templatedMixin], { + grid: null, + view: null, + rowIdx: -1, + cellIdx: -1, + level: 0, + itemId: "", + templateString: template, + onToggle: function(evt){ + // summary: + // The onclick handler of expando, expand/collapse a tree node if has children. + if(this.grid._treeCache.items[this.rowIdx]){ + this.grid.focus.setFocusIndex(this.rowIdx, this.cellIdx); + this.setOpen(!this.grid._treeCache.items[this.rowIdx].opened); + try{ + event.stop(evt); + }catch(e){} + } + }, + setOpen: function(open){ + // summary: + // expand/collapse the row where the expando is in. + var g = this.grid, + item = g._by_idx[this.rowIdx].item; + if(item && g.treeModel.mayHaveChildren(item) && !g._loading && g._treeCache.items[this.rowIdx].opened !== open){ + g._treeCache.items[this.rowIdx].opened = open; + g.expandoFetch(this.rowIdx, open); + this._updateOpenState(item); + } + }, + _updateOpenState: function(item){ + var g = this.grid, state; + if(item && g.treeModel.mayHaveChildren(item)){ + state = g._treeCache.items[this.rowIdx].opened; + this.expandoInner.innerHTML = state ? "-" : "+"; + domClass.toggle(this.domNode, "dojoxGridExpandoOpened", state); + this.domNode.parentNode.setAttribute("aria-expanded", state); + }else{ + domClass.remove(this.domNode, "dojoxGridExpandoOpened"); + } + }, + setRowNode: function(rowIdx, rowNode, view){ + if(this.cellIdx < 0 || !this.itemId){ + return false; + } + this.view = view; + this.grid = view.grid; + this.rowIdx = rowIdx; + var marginPos = this.grid.isLeftToRight() ? "marginLeft" : "marginRight"; + domStyle.set(this.domNode.parentNode, marginPos, (this.level * 1.125) + "em"); + this._updateOpenState(this.grid._by_idx[this.rowIdx].item); + return true; + } +}); + +var _TreeGridContentBuilder = declare("dojox.grid._TreeGridContentBuilder", _Builder._ContentBuilder, { + generateHtml: function(inDataIndex, rowIndex){ + var html = this.getTableArray(), + grid = this.grid, + v = this.view, + cells = v.structure.cells, + item = grid.getItem(rowIndex), + level = 0, + toggleClass = "", + treePath = grid._treeCache.items[rowIndex] ? grid._treeCache.items[rowIndex].treePath : null; + util.fire(this.view, "onBeforeRow", [rowIndex, cells]); + if(item && lang.isArray(treePath)){ + level = treePath.length; + toggleClass = grid.treeModel.mayHaveChildren(item) ? "" : "dojoxGridNoChildren"; + } + var i = 0, j = 0, row, cell, + mergedCells, totalWidth = 0, totalWidthes = []; + for(; row = cells[j]; j++){ + if(row.hidden || row.header){ + continue; + } + html.push('<tr class="' + toggleClass + '">'); + // cell merge + mergedCells = this._getColSpans(level); + if(mergedCells){ + array.forEach(mergedCells, function(c){ + for(i = 0; cell = row[i]; i++){ + if(i >= c.start && i <= c.end){ + totalWidth += this._getCellWidth(row, i); + } + } + totalWidthes.push(totalWidth); + totalWidth = 0; + }, this); + } + var m, cc, cs, pbm, k = 0; + for(i = 0; cell = row[i]; i++){ + m = cell.markup; + cc = cell.customClasses = []; + cs = cell.customStyles = []; + if(mergedCells && mergedCells[k] && (i >= mergedCells[k].start && i <= mergedCells[k].end)){ + var primaryIdx = mergedCells[k].primary || mergedCells[k].start; + if(i == primaryIdx){ + m[5] = cell.formatAtLevel(item, level, rowIndex); + m[1] = cc.join(' '); + pbm = domGeometry.getMarginBox(cell.getHeaderNode()).w - domGeometry.getContentBox(cell.getHeaderNode()).w; + cs = cell.customStyles = ['width:' + (totalWidthes[k] - pbm) + "px"]; + m[3] = cs.join(';'); + html.push.apply(html, m); + }else if(i == mergedCells[k].end){ + k++; + continue; + }else{ + continue; + } + }else{ + m[5] = cell.formatAtLevel(item, level, rowIndex); + m[1] = cc.join(' '); + m[3] = cs.join(';'); + html.push.apply(html, m); + } + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); // String + }, + _getColSpans: function(level){ + var colSpans = this.grid.colSpans; + return colSpans && colSpans[level] ? colSpans[level] : null; + }, + _getCellWidth: function(cells, colIndex){ + var curCell = cells[colIndex], node = curCell.getHeaderNode(); + if(curCell.hidden){ + return 0; + } + if(colIndex == cells.length - 1 || array.every(cells.slice(colIndex + 1), function(cell){ + return cell.hidden; + })){ + var headerNodePos = domGeometry.position(cells[colIndex].view.headerContentNode.firstChild); + return headerNodePos.x + headerNodePos.w - domGeometry.position(node).x; + }else{ + var nextCell; + do{ + nextCell = cells[++colIndex]; + }while(nextCell.hidden); + return domGeometry.position(nextCell.getHeaderNode()).x - domGeometry.position(node).x; + } + } +}); + +declare("dojox.grid._TreeGridView", _View, { + _contentBuilderClass: _TreeGridContentBuilder, + postCreate: function(){ + this.inherited(arguments); + this._expandos = {}; + this.connect(this.grid, '_onCleanupExpandoCache', '_cleanupExpandoCache'); + }, + destroy: function(){ + this._cleanupExpandoCache(); + this.inherited(arguments); + }, + _cleanupExpandoCache: function(identity){ + if(identity && this._expandos[identity]){ + this._expandos[identity].destroy(); + delete this._expandos[identity]; + }else{ + var i; + for(i in this._expandos){ + this._expandos[i].destroy(); + } + this._expandos = {}; + } + }, + onAfterRow: function(rowIndex, cells, rowNode){ + query("span.dojoxGridExpando", rowNode).forEach(function(n){ + if(n && n.parentNode){ + var idty, expando, _byIdx = this.grid._by_idx; + if(_byIdx && _byIdx[rowIndex] && _byIdx[rowIndex].idty){ + idty = _byIdx[rowIndex].idty; + expando = this._expandos[idty]; + } + if(expando){ + domConstruct.place(expando.domNode, n, "replace"); + expando.itemId = n.getAttribute("itemId"); + expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10); + if(isNaN(expando.cellIdx)){ + expando.cellIdx = -1; + } + }else{ + expando = parser.parse(n.parentNode)[0]; + if(idty){ + this._expandos[idty] = expando; + } + } + if(!expando.setRowNode(rowIndex, rowNode, this)){ + expando.domNode.parentNode.removeChild(expando.domNode); + } + domConstruct.destroy(n); + } + }, this); + this.inherited(arguments); + }, + updateRow: function(rowIndex){ + var grid = this.grid, item; + if(grid.keepSelection){ + item = grid.getItem(rowIndex); + if(item){ + grid.selection.preserver._reSelectById(item, rowIndex); + } + } + this.inherited(arguments); + } +}); + +var LazyTreeCell = lang.mixin(lang.clone(TreeCell), { + formatAtLevel: function(item, level, rowIndex){ + if(!item){ + return this.formatIndexes(rowIndex, item, level); + } + var result = "", ret = "", content; + if(this.isCollapsable && this.grid.store.isItem(item)){ + ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._LazyExpando" level="' + level + '" class="dojoxGridExpando"' + + ' itemId="' + this.grid.store.getIdentity(item) + '" cellIdx="' + this.index + '"></span>'; + } + content = this.formatIndexes(rowIndex, item, level); + result = ret !== "" ? '<div>' + ret + content + '</div>' : content; + return result; + }, + formatIndexes: function(rowIndex, item, level){ + var info = this.grid.edit.info, + d = this.get ? this.get(rowIndex, item) : (this.value || this.defaultValue); + if(this.editable && (this.alwaysEditing || (info.rowIndex === rowIndex && info.cell === this))){ + return this.formatEditing(d, rowIndex); + }else{ + return this._defaultFormat(d, [d, rowIndex, level, this]); + } + } +}); + +var _LazyTreeLayout = declare("dojox.grid._LazyTreeLayout", _Layout, { + // summary: + // Override the dojox.grid._TreeLayout to modify the _TreeGridView and cell formatter + setStructure: function(structure){ + var g = this.grid, s = structure; + if(g && !array.every(s, function(i){ + return !!i.cells; + })){ + s = arguments[0] = [{cells:[s]}];//intentionally change arguments[0] + } + if(s.length === 1 && s[0].cells.length === 1){ + s[0].type = "dojox.grid._TreeGridView"; + this._isCollapsable = true; + s[0].cells[0][this.grid.expandoCell].isCollapsable = true; + } + this.inherited(arguments); + }, + addCellDef: function(rowIndex, cellIndex, def){ + var obj = this.inherited(arguments); + return lang.mixin(obj, LazyTreeCell); + } +}); + +var _LazyTreeGridCache = declare("dojox.grid._LazyTreeGridCache", null, { + // summary: + // An internal object used to cache the tree path and open state of each item. + // The form of the cache items would be an object array: + // [{opened: true/false, treePath: [level0 parent id, level1 parent id, ...]}] + // example: + // | [{opened: true, treePath: []}, + // | {opened: false, treePath: ["root0"]}, + // | {opened: false, treePath: ["root0"]}, + // | {opened: false, treePath: []}, + // | ...] + constructor: function(){ + this.items = []; + }, + getSiblingIndex: function(rowIndex, treePath){ + var i = rowIndex - 1, indexCount = 0, tp; + for(; i >=0; i--){ + tp = this.items[i] ? this.items[i].treePath : []; + if(tp.join('/') === treePath.join('/')){ + indexCount++; + }else if(tp.length < treePath.length){ + break; + } + } + return indexCount; + }, + removeChildren: function(rowIndex){ + // find next sibling index + var i = rowIndex + 1, count, tp, + treePath = this.items[rowIndex] ? this.items[rowIndex].treePath : []; + for(; i < this.items.length; i++){ + tp = this.items[i] ? this.items[i].treePath : []; + if(tp.join('/') === treePath.join('/') || tp.length <= treePath.length){ + break; + } + } + count = i - (rowIndex + 1); + this.items.splice(rowIndex + 1, count); + return count; + } +}); + +var LazyTreeGrid = declare("dojox.grid.LazyTreeGrid", TreeGrid, { + // summary: + // An enhanced TreeGrid widget which supports lazy-loading for nested children items + // + // description: + // LazyTreeGrid inherits from dojo.grid.TreeGrid and applies virtual scrolling mechanism + // to nested children rows so that it's possible to deal with complex tree structure data set + // with nested and huge children rows. It's also compatible with dijit.tree.ForestStoreModel + // + // Most methods and properties pertaining to dojox.grid.DataGrid + // and dojox.grid.TreeGrid also apply here + // + // LazyTreeGrid does not support summary row/items aggregate due to the lazy-loading rationale. + _layoutClass: _LazyTreeLayout, + _size: 0, + // treeModel: dijit.tree.ForestStoreModel | dojox.grid.LazyTreeGridStoreModel + // A tree store model object. + treeModel: null, + // defaultState: Object + // Used to restore the state of LazyTreeGrid. + // This object should ONLY be obtained from `LazyTreeGrid.getState()`. + defaultState: null, + // colSpans: Object + // a json object that defines column span of each level rows + // attributes: + // 0/1/..: which level need to colspan + // start: start column index of colspan + // end: end column index of colspan + // primary: index of column which content will be displayed (default is value of start). + // example: + // | colSpans = { + // | 0: [ + // | {start: 0, end: 1, primary: 0}, + // | {start: 2, end: 4, primary: 3} + // | ], + // | 1: [ + // | {start: 0, end: 3, primary: 1} + // | ] + // | }; + colSpans: null, + + postCreate: function(){ + this._setState(); + this.inherited(arguments); + if(!this._treeCache){ + this._treeCache = new _LazyTreeGridCache(); + } + if(!this.treeModel || !(this.treeModel instanceof dijit.tree.ForestStoreModel)){ + throw new Error("dojox.grid.LazyTreeGrid: must be used with a treeModel which is an instance of dijit.tree.ForestStoreModel"); + } + domClass.add(this.domNode, "dojoxGridTreeModel"); + dom.setSelectable(this.domNode, this.selectable); + }, + createManagers: function(){ + this.rows = new _RowManager(this); + this.focus = new _FocusManager(this); + this.edit = new _EditManager(this); + }, + createSelection: function(){ + this.selection = new DataSelection(this); + }, + setModel: function(treeModel){ + if(!treeModel){ + return; + } + this._setModel(treeModel); + this._cleanup(); + this._refresh(true); + }, + setStore: function(store, query, queryOptions){ + if(!store){ + return; + } + this._setQuery(query, queryOptions); + this.treeModel.query = query; + this.treeModel.store = store; + this.treeModel.root.children = []; + this.setModel(this.treeModel); + }, + onSetState: function(){ + // summary: + // Event fired when a default state being set. + }, + _setState: function(){ + if(this.defaultState){ + this._treeCache = this.defaultState.cache; + this.sortInfo = this.defaultState.sortInfo || 0; + this.query = this.defaultState.query || this.query; + this._lastScrollTop = this.defaultState.scrollTop; + if(this.keepSelection){ + this.selection.preserver._selectedById = this.defaultState.selection; + }else{ + this.selection.selected = this.defaultState.selection || []; + } + this.onSetState(); + } + }, + getState: function(){ + // summary: + // Get the current state of LazyTreeGrid including expanding, sorting, selection and scroll top state. + var _this = this, + selection = this.keepSelection ? this.selection.preserver._selectedById : this.selection.selected; + return { + cache: lang.clone(_this._treeCache), + query: lang.clone(_this.query), + sortInfo: lang.clone(_this.sortInfo), + scrollTop: lang.clone(_this.scrollTop), + selection: lang.clone(selection) + }; + }, + _setQuery: function(query, queryOptions){ + this.inherited(arguments); + this.treeModel.query = query; + }, + filter: function(query, reRender){ + this._cleanup(); + this.inherited(arguments); + }, + destroy: function(){ + this._cleanup(); + this.inherited(arguments); + }, + expand: function(itemId){ + // summary: + // Expand the row with the given itemId. + // id: string? + this._fold(itemId, true); + }, + collapse: function(itemId){ + // summary: + // Collapse the row with the given itemId. + // id: string? + this._fold(itemId, false); + }, + refresh: function(keepState){ + // summary: + // Refresh, and persist the expand/collapse state when keepState equals true + // keepState: boolean + if(!keepState){ + this._cleanup(); + } + this._refresh(true); + }, + _cleanup: function(){ + this._treeCache.items = []; + this._onCleanupExpandoCache(); + }, + setSortIndex: function(inIndex, inAsc){ + // Need to clean up the cache before sorting + if(this.canSort(inIndex + 1)){ + this._cleanup(); + } + this.inherited(arguments); + }, + _refresh: function(isRender){ + this._clearData(); + this.updateRowCount(this._size); + this._fetch(0, true); + }, + render: function(){ + this.inherited(arguments); + this.setScrollTop(this.scrollTop); + }, + _onNew: function(item, parentInfo){ + var addingChild = parentInfo && this.store.isItem(parentInfo.item) && array.some(this.treeModel.childrenAttrs, function(c){ + return c === parentInfo.attribute; + }); + var items = this._treeCache.items, byIdx = this._by_idx; + if(!addingChild){ + items.push({opened: false, treePath: []}); + this._size += 1; + this.inherited(arguments); + }else{ + var parentItem = parentInfo.item, + parentIdty = this.store.getIdentity(parentItem), + rowIndex = -1, i = 0; + for(; i < byIdx.length; i++){ + if(parentIdty === byIdx[i].idty){ + rowIndex = i; + break; + } + } + if(rowIndex >= 0){ + if(items[rowIndex] && items[rowIndex].opened){ + var parentTreePath = items[rowIndex].treePath, pos = rowIndex + 1; + for(; pos < items.length; pos++){ + if(items[pos].treePath.length <= parentTreePath.length){ + break; + } + } + var treePath = parentTreePath.slice(); + treePath.push(parentIdty); + this._treeCache.items.splice(pos, 0, {opened: false, treePath: treePath}); + // update grid._by_idx + var idty = this.store.getIdentity(item); + this._by_idty[idty] = { idty: idty, item: item }; + byIdx.splice(pos, 0, this._by_idty[idty]); + // update grid + this._size += 1; + this.updateRowCount(this._size); + this._updateRenderedRows(pos); + }else{ + this.updateRow(rowIndex); + } + } + } + }, + _onDelete: function(item){ + var i = 0, rowIndex = -1, idty = this.store.getIdentity(item); + for(; i < this._by_idx.length; i++){ + if(idty === this._by_idx[i].idty){ + rowIndex = i; + break; + } + } + if(rowIndex >= 0){ + var items = this._treeCache.items, treePath = items[rowIndex] ? items[rowIndex].treePath : [], tp, count = 1; + i = rowIndex + 1; + for(; i < this._size; i++, count++){ + tp = items[i] ? items[i].treePath : []; + if(items[i].treePath.length <= treePath.length){ + break; + } + } + items.splice(rowIndex, count); + this._onCleanupExpandoCache(idty); + this._by_idx.splice(rowIndex, count); + this._size -= count; + this.updateRowCount(this._size); + this._updateRenderedRows(rowIndex); + } + }, + _onCleanupExpandoCache: function(identity){}, + _fetch: function(start, isRender){ + if(!this._loading){ + this._loading = true; + } + start = start || 0; + var count = this._size - start > 0 ? Math.min(this.rowsPerPage, this._size - start) : this.rowsPerPage; + var i = 0; + var fetchedItems = []; + this._reqQueueLen = 0; + for(; i < count; i++){ + if(this._by_idx[start + i]){ + fetchedItems.push(this._by_idx[start + i].item); + }else{ + break; + } + } + if(fetchedItems.length === count){ + this._reqQueueLen = 1; + this._onFetchBegin(this._size, {startRowIdx: start, count: count}); + this._onFetchComplete(fetchedItems, {startRowIdx: start, count: count}); + }else{ + var level, nextLevel, len = 1, items = this._treeCache.items, + treePath = items[start] ? items[start].treePath : []; + for(i = 1; i < count; i++){ + level = items[start + len - 1] ? items[start + len - 1].treePath.length : 0; + nextLevel = items[start + len] ? items[start + len].treePath.length : 0; + if(level !== nextLevel){ + this._reqQueueLen++; + this._fetchItems({startRowIdx: start, count: len, treePath: treePath}); + start = start + len; + len = 1; + treePath = items[start] ? items[start].treePath : 0; + }else{ + len++; + } + } + this._reqQueueLen++; + this._fetchItems({startRowIdx: start, count: len, treePath: treePath}); + } + }, + _fetchItems: function(req){ + if(this._pending_requests[req.startRowIdx]){ + return; + } + this.showMessage(this.loadingMessage); + this._pending_requests[req.startRowIdx] = true; + var onError = lang.hitch(this, '_onFetchError'), + start = this._treeCache.getSiblingIndex(req.startRowIdx, req.treePath); + if(req.treePath.length === 0){ + this.store.fetch({ + start: start, + startRowIdx: req.startRowIdx, + treePath: req.treePath, + count: req.count, + query: this.query, + sort: this.getSortProps(), + queryOptions: this.queryOptions, + onBegin: lang.hitch(this, '_onFetchBegin'), + onComplete: lang.hitch(this, '_onFetchComplete'), + onError: lang.hitch(this, '_onFetchError') + }); + }else{ + var parentId = req.treePath[req.treePath.length - 1], parentItem; + var queryObj = { + start: start, + startRowIdx: req.startRowIdx, + treePath: req.treePath, + count: req.count, + parentId: parentId, + sort: this.getSortProps() + }; + var _this = this; + var onComplete = function(){ + var f = lang.hitch(_this, '_onFetchComplete'); + if(arguments.length == 1){ + f.apply(_this, [arguments[0], queryObj]); + }else{ + f.apply(_this, arguments); + } + }; + if(this._by_idty[parentId]){ + parentItem = this._by_idty[parentId].item; + this.treeModel.getChildren(parentItem, onComplete, onError, queryObj); + }else{ + this.store.fetchItemByIdentity({ + identity: parentId, + onItem: function(item){ + _this.treeModel.getChildren(item, onComplete, onError, queryObj); + }, + onError: onError + }); + } + } + }, + _onFetchBegin: function(size, request){ + if(this._treeCache.items.length === 0){ + this._size = parseInt(size, 10); + } + size = this._size; + // this._size = size = this._treeCache.items.length; + this.inherited(arguments); + }, + _onFetchComplete: function(items, request){ + var startRowIdx = request.startRowIdx, + count = request.count, + start = items.length <= count ? 0: request.start, + treePath = request.treePath || []; + if(lang.isArray(items) && items.length > 0){ + var i = 0, len = Math.min(count, items.length); + for(; i < len; i++){ + if(!this._treeCache.items[startRowIdx + i]){ + this._treeCache.items[startRowIdx + i] = {opened: false, treePath: treePath}; + } + if(!this._by_idx[startRowIdx + i]){ + this._addItem(items[start + i], startRowIdx + i, true); + } + // this._treeCache.items.splice(startRowIdx + i, 0, {opened: false, treePath: treePath}); + } + this.updateRows(startRowIdx, len); + } + if(this._size == 0){ + this.showMessage(this.noDataMessage); + }else{ + this.showMessage(); + } + this._pending_requests[startRowIdx] = false; + this._reqQueueLen--; + if(this._loading && this._reqQueueLen === 0){ + this._loading = false; + if(this._lastScrollTop){ + this.setScrollTop(this._lastScrollTop); + } + } + }, + expandoFetch: function(rowIndex, open){ + // summary: + // Function for fetch children of a given row + if(this._loading || !this._by_idx[rowIndex]){return;} + this._loading = true; + this._toggleLoadingClass(rowIndex, true); + this.expandoRowIndex = rowIndex; + var item = this._by_idx[rowIndex].item; + // this._pages = []; + if(open){ + var queryObj = { + start: 0, + count: this.rowsPerPage, + parentId: this.store.getIdentity(this._by_idx[rowIndex].item), + sort: this.getSortProps() + }; + this.treeModel.getChildren(item, lang.hitch(this, "_onExpandoComplete"), lang.hitch(this, "_onFetchError"), queryObj); + }else{ + // get the whole children number when clear the children from cache + var num = this._treeCache.removeChildren(rowIndex); + // remove the items from grid._by_idx + this._by_idx.splice(rowIndex + 1, num); + this._bop = this._eop = -1; + //update grid + this._size -= num; + this.updateRowCount(this._size); + this._updateRenderedRows(rowIndex + 1); + this._toggleLoadingClass(rowIndex, false); + if(this._loading){ + this._loading = false; + } + this.focus._delayedCellFocus(); + } + }, + _onExpandoComplete: function(childItems, request, size){ + size = isNaN(size) ? childItems.length : parseInt(size, 10); + var treePath = this._treeCache.items[this.expandoRowIndex].treePath.slice(0); + treePath.push(this.store.getIdentity(this._by_idx[this.expandoRowIndex].item)); + var i = 1, idty; + for(; i <= size; i++){ + this._treeCache.items.splice(this.expandoRowIndex + i, 0, {treePath: treePath, opened: false}); + } + this._size += size; + this.updateRowCount(this._size); + for(i = 0; i < size; i++){ + if(childItems[i]){ + idty = this.store.getIdentity(childItems[i]); + this._by_idty[idty] = { idty: idty, item: childItems[i] }; + this._by_idx.splice(this.expandoRowIndex + 1 + i, 0, this._by_idty[idty]); + }else{ + this._by_idx.splice(this.expandoRowIndex + 1 + i, 0, null); + } + } + this._updateRenderedRows(this.expandoRowIndex + 1); + this._toggleLoadingClass(this.expandoRowIndex, false); + this.stateChangeNode = null; + if(this._loading){ + this._loading = false; + } + if(this.autoHeight === true){ + this._resize(); + } + this.focus._delayedCellFocus(); + }, + styleRowNode: function(rowIndex, rowNode){ + if(rowNode){ + this.rows.styleRowNode(rowIndex, rowNode); + } + }, + onStyleRow: function(row){ + if(!this.layout._isCollapsable){ + this.inherited(arguments); + return; + } + row.customClasses = (row.odd ? " dojoxGridRowOdd" : "") + (row.selected ? " dojoxGridRowSelected" : "") + (row.over ? " dojoxGridRowOver" : ""); + this.focus.styleRow(row); + this.edit.styleRow(row); + }, + onKeyDown: function(e){ + if(e.altKey || e.metaKey){ + return; + } + var expando = dijit.findWidgets(e.target)[0]; + if(e.keyCode === keys.ENTER && expando instanceof _LazyExpando){ + expando.onToggle(); + } + this.inherited(arguments); + }, + _toggleLoadingClass: function(rowIndex, flag){ + var views = this.views.views, node, + rowNode = views[views.length - 1].getRowNode(rowIndex); + if(rowNode){ + node = query('.dojoxGridExpando', rowNode)[0]; + if(node){ + domClass.toggle(node, "dojoxGridExpandoLoading", flag); + } + } + }, + _updateRenderedRows: function(start){ + array.forEach(this.scroller.stack, function(p){ + if(p * this.rowsPerPage >= start){ + this.updateRows(p * this.rowsPerPage, this.rowsPerPage); + }else if((p + 1) * this.rowsPerPage >= start){ + this.updateRows(start, (p + 1) * this.rowsPerPage - start + 1); + } + }, this); + }, + _fold: function(itemId, open){ + var rowIndex = -1, i = 0, byIdx = this._by_idx, idty = this._by_idty[itemId]; + if(idty && idty.item && this.treeModel.mayHaveChildren(idty.item)){ + for(; i < byIdx.length; i++){ + if(byIdx[i] && byIdx[i].idty === itemId){ + rowIndex = i; + break; + } + } + if(rowIndex >= 0){ + var rowNode = this.views.views[this.views.views.length - 1].getRowNode(rowIndex); + if(rowNode){ + var expando = dijit.findWidgets(rowNode)[0]; + if(expando){ + expando.setOpen(open); + } + } + } + } + } +}); + +LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){ + return TreeGrid.markupFactory(props, node, ctor, cellFunc); +}; + +return LazyTreeGrid; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js b/js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js new file mode 100644 index 0000000..340fbe3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js @@ -0,0 +1,114 @@ +//>>built +define("dojox/grid/LazyTreeGridStoreModel", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dijit/tree/ForestStoreModel"], function(declare, array, lang, ForestStoreModel){ + +return declare("dojox.grid.LazyTreeGridStoreModel", ForestStoreModel, { + + // There are different approaches to get children for client-side + // DataStore (e.g. dojo.data.ItemFileReadStore) or server-side DataStore + // (e.g. dojox.data.QueryReadStore), so we need to be sure what kind of + // DataStore is being used + serverStore: false, // server side store + + constructor: function(/* Object */ args){ + this.serverStore = !!args.serverStore; + }, + + mayHaveChildren: function(/*dojo.data.Item*/ item){ + var children = null; + return array.some(this.childrenAttrs, function(attr){ + children = this.store.getValue(item, attr); + if(lang.isString(children)){ + return parseInt(children, 10) > 0 || children.toLowerCase() === "true" ? true : false; + }else if(typeof children == "number"){ + return children > 0; + }else if(typeof children == "boolean"){ + return children; + }else if(this.store.isItem(children)){ + children = this.store.getValues(item, attr); + return lang.isArray(children) ? children.length > 0 : false; + }else{ + return false; + } + }, this); + }, + + getChildren: function(/*dojo.data.Item*/parentItem, /*function(items, size)*/onComplete, /*function*/ onError, /*object*/queryObj){ + if(queryObj){ + var start = queryObj.start || 0, + count = queryObj.count, + parentId = queryObj.parentId, + sort = queryObj.sort; + if(parentItem === this.root){ + this.root.size = 0; + this.store.fetch({ + start: start, + count: count, + sort: sort, + query: this.query, + onBegin: lang.hitch(this, function(size){ + this.root.size = size; + }), + onComplete: lang.hitch(this, function(items){ + onComplete(items, queryObj, this.root.size); + }), + onError: onError + }); + }else{ + var store = this.store; + if(!store.isItemLoaded(parentItem)){ + var getChildren = lang.hitch(this, arguments.callee); + store.loadItem({ + item: parentItem, + onItem: function(parentItem){ + getChildren(parentItem, onComplete, onError, queryObj); + }, + onError: onError + }); + return; + } + if(this.serverStore && !this._isChildrenLoaded(parentItem)){ + this.childrenSize = 0; + this.store.fetch({ + start: start, + count: count, + sort: sort, + query: lang.mixin({parentId: parentId}, this.query || {}), + onBegin: lang.hitch(this, function(size){ + this.childrenSize = size; + }), + onComplete: lang.hitch(this, function(items){ + onComplete(items, queryObj, this.childrenSize); + }), + onError: onError + }); + }else{ + this.inherited(arguments); + } + } + }else{ + this.inherited(arguments); + } + }, + + _isChildrenLoaded: function(parentItem){ + // summary: + // Check if all children of the given item have been loaded + var children = null; + return array.every(this.childrenAttrs, function(attr){ + children = this.store.getValues(parentItem, attr); + return array.every(children, function(c){ + return this.store.isItemLoaded(c); + }, this); + }, this); + }, + + //overwritten + onNewItem: function(item, parentInfo){ }, + + onDeleteItem: function(item){ } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/README b/js/dojo-1.7.2/dojox/grid/README new file mode 100644 index 0000000..91b762c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/README @@ -0,0 +1,151 @@ +------------------------------------------------------------------------------- +dojox.grid +------------------------------------------------------------------------------- +Version 1.00 +Release date: 10/04/2007 +------------------------------------------------------------------------------- +Project state: +beta +------------------------------------------------------------------------------- +Credits + Scott J. Miles (sjmiles@activegrid.com) + Steve Orvell (sorvell@activegrid.com) + Bryan Forbes (bryan AT reigndropsfall.net) + Nathan Toone (toonetown AT dojotoolkit.org) +------------------------------------------------------------------------------- +Project description + +TurboGrid has been made available in Dojo and is now the dojox.grid! + +------------------------------------------------------------------------------- +Dependencies: + +Dojo Core +Dojo Base (dnd) +Dijit Templated Widget +dojox.html (metrics) +------------------------------------------------------------------------------- +Documentation + +None available for this version yet. + +See http://www.turboajax.com/products/turbogrid/ for legacy documentation. +------------------------------------------------------------------------------- +Installation instructions + +Grab the following from the Dojo SVN Repository: +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/grid/* +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/* + +Install into the following directory structure: +/dojox/grid/ +/dojox/html/ + +...which should be at the same level as your Dojo checkout. + +If you wish us use the old (compat / 1.2) grid, you can untar the +compatGrid.tar.gz archive. This version of the grid is no longer maintained +or updated - but should work with any newer version of the dojo library. + +dojox.grid.* is a11y enabled, please see the following doc page for more details +- http://dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html#accessibility-in-1-3-and-beyond +------------------------------------------------------------------------------- + + + +------------------------------------------------------------------------------- +Sub-projects: +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +1. dojox.grid.EnhancedGrid +------------------------------------------------------------------------------- +Version 0.9 +Release date: 12/11/2009 +------------------------------------------------------------------------------- +Project state + +alpha +------------------------------------------------------------------------------- +Credits + David Schwartz (drschwar@us.ibm.com, IBM, CCLA) - Author, UX design + Wei Huang (evan@dojotoolkit.org) - Author, IndirectSelection, Menus + Xiao Wen Zhu (xwzhu@cn.ibm.com, IBM, CCLA) + - Filter, Exporter, Printer, Selector, DnD, CellMerge, Cookie, Search + Qiang Wang (wangqsh@cn.ibm.com, IBM, CCLA) - Pagination + Pei Wang (wpei@cn.ibm.com, IBM, CCLA) - NestedSorting +------------------------------------------------------------------------------- +Project description + +Enhanced Grid inherits base DataGrid and provides the following enhanced features: + 1. Nested Sorting + 2. Built-in declarative Indirect Selection (radio buttons and check boxes) + 3. Context menu for header, row, column and selected region + 4. Advanced Selector: support selecting rows/columns/cells via swipe + 5. Drag-n-drop: columns,rows - MOVE, cells - MOVE/COPY + 6. Filter: filter grid content in various data types + 7. Exporter: export grid content to various formats + 8. Printer: provide convenient ways for printing grid + 9. Pagination: an alternative to deal with huge data set besides the default virtual scrolling way + 10.CellMerge: merge adjacent cells within a row + 11.Cookie: persist grid preferences including column width, column order, sorting order etc. + 12.Search: a handy way for searching grid content by regular expressions +------------------------------------------------------------------------------- +Dependencies + +Dojo Core, dojox.grid.DataGrid +------------------------------------------------------------------------------- +Documentation + +http://dojotoolkit.org/reference-guide/dojox/grid/EnhancedGrid.html +------------------------------------------------------------------------------- +Installation instructions + +Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/enhanced/*.html +------------------------------------------------------------------------------- +Known issues + + - 'Claro' is the major supported theme for EnhancedGrid features + - EnhancedGrid features are not fully compatible with complicated layouts (e.g. multiple rows in column header) and TreeGrid(SubGrid). + - Indirect Selection is not fully compatible with Advanced Selector(for selecting row/column/cells) and DnD + - RTL support is still in progress for Nested Sorting +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +2. dojox.grid.LazyTreeGrid +------------------------------------------------------------------------------- +Version 0.9 +Release date: +------------------------------------------------------------------------------- +Project state + +alpha +------------------------------------------------------------------------------- +Credits + Qiang Wang (wangqsh@cn.ibm.com, IBM, CCLA) + Wei Huang (evan@dojotoolkit.org) +------------------------------------------------------------------------------- +Project description + +LazyTreeGrid applies virtual scrolling mechanism to nested children rows so that it's possible to +deal with large data set specifically in tree structure with large number of children rows. +It's also compatible with dijit.tree.ForestStoreModel +------------------------------------------------------------------------------- +Dependencies + +Dojo Core, dojox.grid.TreeGrid +------------------------------------------------------------------------------- +Documentation + +http://dojotoolkit.org/reference-guide/dojox/grid/LazyTreeGrid.html +------------------------------------------------------------------------------- +Installation instructions + +Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/test_treegrid_lazyloading.html +------------------------------------------------------------------------------- +Known issues + +LazyTreeGrid is not compatible with: + - Most Enhanced Grid features + - Complicated layouts (e.g. multiple rows in column header) +------------------------------------------------------------------------------- diff --git a/js/dojo-1.7.2/dojox/grid/Selection.js b/js/dojo-1.7.2/dojox/grid/Selection.js new file mode 100644 index 0000000..56e6884 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/Selection.js @@ -0,0 +1,267 @@ +//>>built +define("dojox/grid/Selection", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/dom-attr" +], function(declare, array, lang, domAttr){ + +return declare("dojox.grid.Selection", null, { + // summary: + // Manages row selection for grid. Owned by grid and used internally + // for selection. Override to implement custom selection. + + constructor: function(inGrid){ + this.grid = inGrid; + this.selected = []; + + this.setMode(inGrid.selectionMode); + }, + + mode: 'extended', + + selected: null, + updating: 0, + selectedIndex: -1, + + setMode: function(mode){ + if(this.selected.length){ + this.deselectAll(); + } + if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){ + this.mode = 'extended'; + }else{ + this.mode = mode; + } + }, + + onCanSelect: function(inIndex){ + return this.grid.onCanSelect(inIndex); + }, + + onCanDeselect: function(inIndex){ + return this.grid.onCanDeselect(inIndex); + }, + + onSelected: function(inIndex){ + }, + + onDeselected: function(inIndex){ + }, + + //onSetSelected: function(inIndex, inSelect) { }; + onChanging: function(){ + }, + + onChanged: function(){ + }, + + isSelected: function(inIndex){ + if(this.mode == 'none'){ + return false; + } + return this.selected[inIndex]; + }, + + getFirstSelected: function(){ + if(!this.selected.length||this.mode == 'none'){ return -1; } + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + return i; + } + } + return -1; + }, + + getNextSelected: function(inPrev){ + if(this.mode == 'none'){ return -1; } + for(var i=inPrev+1, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + return i; + } + } + return -1; + }, + + getSelected: function(){ + var result = []; + for(var i=0, l=this.selected.length; i<l; i++){ + if(this.selected[i]){ + result.push(i); + } + } + return result; + }, + + getSelectedCount: function(){ + var c = 0; + for(var i=0; i<this.selected.length; i++){ + if(this.selected[i]){ + c++; + } + } + return c; + }, + + _beginUpdate: function(){ + if(this.updating === 0){ + this.onChanging(); + } + this.updating++; + }, + + _endUpdate: function(){ + this.updating--; + if(this.updating === 0){ + this.onChanged(); + } + }, + + select: function(inIndex){ + if(this.mode == 'none'){ return; } + if(this.mode != 'multiple'){ + this.deselectAll(inIndex); + this.addToSelection(inIndex); + }else{ + this.toggleSelect(inIndex); + } + }, + + addToSelection: function(inIndex){ + if(this.mode == 'none'){ return; } + if(lang.isArray(inIndex)){ + array.forEach(inIndex, this.addToSelection, this); + return; + } + inIndex = Number(inIndex); + if(this.selected[inIndex]){ + this.selectedIndex = inIndex; + }else{ + if(this.onCanSelect(inIndex) !== false){ + this.selectedIndex = inIndex; + var rowNode = this.grid.getRowNode(inIndex); + if(rowNode){ + domAttr.set(rowNode, "aria-selected", "true"); + } + this._beginUpdate(); + this.selected[inIndex] = true; + //this.grid.onSelected(inIndex); + this.onSelected(inIndex); + //this.onSetSelected(inIndex, true); + this._endUpdate(); + } + } + }, + + deselect: function(inIndex){ + if(this.mode == 'none'){ return; } + if(lang.isArray(inIndex)){ + array.forEach(inIndex, this.deselect, this); + return; + } + inIndex = Number(inIndex); + if(this.selectedIndex == inIndex){ + this.selectedIndex = -1; + } + if(this.selected[inIndex]){ + if(this.onCanDeselect(inIndex) === false){ + return; + } + var rowNode = this.grid.getRowNode(inIndex); + if(rowNode){ + domAttr.set(rowNode, "aria-selected", "false"); + } + this._beginUpdate(); + delete this.selected[inIndex]; + //this.grid.onDeselected(inIndex); + this.onDeselected(inIndex); + //this.onSetSelected(inIndex, false); + this._endUpdate(); + } + }, + + setSelected: function(inIndex, inSelect){ + this[(inSelect ? 'addToSelection' : 'deselect')](inIndex); + }, + + toggleSelect: function(inIndex){ + if(lang.isArray(inIndex)){ + array.forEach(inIndex, this.toggleSelect, this); + return; + } + this.setSelected(inIndex, !this.selected[inIndex]); + }, + + _range: function(inFrom, inTo, func){ + var s = (inFrom >= 0 ? inFrom : inTo), e = inTo; + if(s > e){ + e = s; + s = inTo; + } + for(var i=s; i<=e; i++){ + func(i); + } + }, + + selectRange: function(inFrom, inTo){ + this._range(inFrom, inTo, lang.hitch(this, "addToSelection")); + }, + + deselectRange: function(inFrom, inTo){ + this._range(inFrom, inTo, lang.hitch(this, "deselect")); + }, + + insert: function(inIndex){ + this.selected.splice(inIndex, 0, false); + if(this.selectedIndex >= inIndex){ + this.selectedIndex++; + } + }, + + remove: function(inIndex){ + this.selected.splice(inIndex, 1); + if(this.selectedIndex >= inIndex){ + this.selectedIndex--; + } + }, + + deselectAll: function(inExcept){ + for(var i in this.selected){ + if((i!=inExcept)&&(this.selected[i]===true)){ + this.deselect(i); + } + } + }, + + clickSelect: function(inIndex, inCtrlKey, inShiftKey){ + if(this.mode == 'none'){ return; } + this._beginUpdate(); + if(this.mode != 'extended'){ + this.select(inIndex); + }else{ + var lastSelected = this.selectedIndex; + if(!inCtrlKey){ + this.deselectAll(inIndex); + } + if(inShiftKey){ + this.selectRange(lastSelected, inIndex); + }else if(inCtrlKey){ + this.toggleSelect(inIndex); + }else{ + this.addToSelection(inIndex); + } + } + this._endUpdate(); + }, + + clickSelectEvent: function(e){ + this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey); + }, + + clear: function(){ + this._beginUpdate(); + this.deselectAll(); + this._endUpdate(); + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/TreeGrid.js b/js/dojo-1.7.2/dojox/grid/TreeGrid.js new file mode 100644 index 0000000..e80f78b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/TreeGrid.js @@ -0,0 +1,970 @@ +//>>built +define("dojox/grid/TreeGrid", [ + "dojo/_base/kernel", + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/event", + "dojo/dom-attr", + "dojo/dom-class", + "dojo/query", + "dojo/keys", + "dijit/tree/ForestStoreModel", + "./DataGrid", + "./_Layout", + "./_FocusManager", + "./_RowManager", + "./_EditManager", + "./TreeSelection", + "./cells/tree", + "./_TreeView" +], function(dojo, dojox, declare, array, lang, event, domAttr, domClass, query, keys, ForestStoreModel, + DataGrid, _Layout, _FocusManager, _RowManager, _EditManager, TreeSelection, TreeCell){ + +dojo.experimental("dojox.grid.TreeGrid"); + +var _TreeAggregator = declare("dojox.grid._TreeAggregator", null, { + cells: [], + grid: null, + childFields: [], + + constructor: function(kwArgs){ + this.cells = kwArgs.cells || []; + this.childFields = kwArgs.childFields || []; + this.grid = kwArgs.grid; + this.store = this.grid.store; + }, + _cacheValue: function(cache, id, value){ + cache[id] = value; + return value; + }, + clearSubtotalCache: function(){ + // summary: + // Clears the subtotal cache so that we are forced to recalc it + // (or reread it) again. This is needed, for example, when + // column order is changed. + if(this.store){ + delete this.store._cachedAggregates; + } + }, + + cnt: function(cell, level, item){ + // summary: + // calculates the count of the children of item at the given level + var total = 0; + var store = this.store; + var childFields = this.childFields; + if(childFields[level]){ + var children = store.getValues(item, childFields[level]); + if (cell.index <= level + 1){ + total = children.length; + }else{ + array.forEach(children, function(c){ + total += this.getForCell(cell, level + 1, c, "cnt"); + }, this); + } + }else{ + total = 1; + } + return total; + }, + sum: function(cell, level, item){ + // summary: + // calculates the sum of the children of item at the given level + var total = 0; + var store = this.store; + var childFields = this.childFields; + if(childFields[level]){ + array.forEach(store.getValues(item, childFields[level]), function(c){ + total += this.getForCell(cell, level + 1, c, "sum"); + }, this); + }else{ + total += store.getValue(item, cell.field); + } + return total; + }, + value: function(cell, level, item){ + // summary: + // Empty function so that we can set "aggregate='value'" to + // force loading from the data - and bypass calculating + }, + getForCell: function(cell, level, item, type){ + // summary: + // Gets the value of the given cell at the given level and type. + // type can be one of "sum", "cnt", or "value". If itemAggregates + // is set and can be used, it is used instead. Values are also + // cached to prevent calculating them too often. + var store = this.store; + if(!store || !item || !store.isItem(item)){ return ""; } + var storeCache = store._cachedAggregates = store._cachedAggregates || {}; + var id = store.getIdentity(item); + var itemCache = storeCache[id] = storeCache[id] || []; + if(!cell.getOpenState){ + cell = this.grid.getCell(cell.layoutIndex + level + 1); + } + var idx = cell.index; + var idxCache = itemCache[idx] = itemCache[idx] || {}; + type = (type || (cell.parentCell ? cell.parentCell.aggregate : "sum"))||"sum"; + var attr = cell.field; + if(attr == store.getLabelAttributes()[0]){ + // If our attribute is one of the label attributes, we should + // use cnt instead (since it makes no sense to do a sum of labels) + type = "cnt"; + } + var typeCache = idxCache[type] = idxCache[type] || []; + + // See if we have it in our cache immediately for easy returning + if(typeCache[level] != undefined){ + return typeCache[level]; + } + + // See if they have specified a valid field + var field = ((cell.parentCell && cell.parentCell.itemAggregates) ? + cell.parentCell.itemAggregates[cell.idxInParent] : "")||""; + if(field && store.hasAttribute(item, field)){ + return this._cacheValue(typeCache, level, store.getValue(item, field)); + }else if(field){ + return this._cacheValue(typeCache, level, 0); + } + + // Calculate it + return this._cacheValue(typeCache, level, this[type](cell, level, item)); + } +}); + +var _TreeLayout = declare("dojox.grid._TreeLayout", _Layout, { + // Whether or not we are collapsable - this is calculated when we + // set our structure. + _isCollapsable: false, + + _getInternalStructure: function(inStructure){ + // Create a "Tree View" with 1 row containing references for + // each column (recursively) + var g = this.grid; + + var s = inStructure; + var cells = s[0].cells[0]; + var tree = { + type: "dojox.grid._TreeView", + cells: [[]] + }; + var cFields = []; + var maxLevels = 0; + var getTreeCells = function(parentCell, level){ + var children = parentCell.children; + var cloneTreeCell = function(originalCell, idx){ + var k, n = {}; + for(k in originalCell){ + n[k] = originalCell[k]; + } + n = lang.mixin(n, { + level: level, + idxInParent: level > 0 ? idx : -1, + parentCell: level > 0 ? parentCell : null + }); + return n; + }; + var ret = []; + array.forEach(children, function(c, idx){ + if("children" in c){ + cFields.push(c.field); + var last = ret[ret.length - 1]; + last.isCollapsable = true; + c.level = level; + ret = ret.concat(getTreeCells(c, level + 1)); + }else{ + ret.push(cloneTreeCell(c, idx)); + } + }); + maxLevels = Math.max(maxLevels, level); + return ret; + }; + var tCell = {children: cells, itemAggregates: []}; + tree.cells[0] = getTreeCells(tCell, 0); + g.aggregator = new _TreeAggregator({cells: tree.cells[0], + grid: g, + childFields: cFields}); + if(g.scroller && g.defaultOpen){ + g.scroller.defaultRowHeight = g.scroller._origDefaultRowHeight * (2 * maxLevels + 1); + } + return [ tree ]; + }, + + setStructure: function(inStructure){ + // Mangle the structure a bit and make it work as desired + var s = inStructure; + var g = this.grid; + // Only supporting single-view, single row or else we + // are not collapsable + if(g && g.treeModel && !array.every(s, function(i){ + return ("cells" in i); + })){ + s = arguments[0] = [{cells:[s]}]; + } + if(s.length == 1 && s[0].cells.length == 1){ + if(g && g.treeModel){ + s[0].type = "dojox.grid._TreeView"; + this._isCollapsable = true; + s[0].cells[0][(this.grid.treeModel?this.grid.expandoCell:0)].isCollapsable = true; + }else{ + var childCells = array.filter(s[0].cells[0], function(c){ + return ("children" in c); + }); + if(childCells.length === 1){ + this._isCollapsable = true; + } + } + } + if(this._isCollapsable && (!g || !g.treeModel)){ + arguments[0] = this._getInternalStructure(s); + } + this.inherited(arguments); + }, + + addCellDef: function(inRowIndex, inCellIndex, inDef){ + var obj = this.inherited(arguments); + return lang.mixin(obj, TreeCell); + } +}); + +var TreePath = declare("dojox.grid.TreePath", null, { + level: 0, + _str: "", + _arr: null, + grid: null, + store: null, + cell: null, + item: null, + + constructor: function(/*String|Integer[]|Integer|dojox.grid.TreePath*/ path, /*dojox.grid.TreeGrid*/ grid){ + if(lang.isString(path)){ + this._str = path; + this._arr = array.map(path.split('/'), function(item){ return parseInt(item, 10); }); + }else if(lang.isArray(path)){ + this._str = path.join('/'); + this._arr = path.slice(0); + }else if(typeof path == "number"){ + this._str = String(path); + this._arr = [path]; + }else{ + this._str = path._str; + this._arr = path._arr.slice(0); + } + this.level = this._arr.length-1; + this.grid = grid; + this.store = this.grid.store; + if(grid.treeModel){ + this.cell = grid.layout.cells[grid.expandoCell]; + }else{ + this.cell = grid.layout.cells[this.level]; + } + }, + item: function(){ + // summary: + // gets the dojo.data item associated with this path + if(!this._item){ + this._item = this.grid.getItem(this._arr); + } + return this._item; + }, + compare: function(path /*dojox.grid.TreePath|String|Array*/){ + // summary: + // compares two paths + if(lang.isString(path) || lang.isArray(path)){ + if(this._str == path){ return 0; } + if(path.join && this._str == path.join('/')){ return 0; } + path = new TreePath(path, this.grid); + }else if(path instanceof TreePath){ + if(this._str == path._str){ return 0; } + } + for(var i=0, l=(this._arr.length < path._arr.length ? this._arr.length : path._arr.length); i<l; i++){ + if(this._arr[i]<path._arr[i]){ return -1; } + if(this._arr[i]>path._arr[i]){ return 1; } + } + if(this._arr.length<path._arr.length){ return -1; } + if(this._arr.length>path._arr.length){ return 1; } + return 0; + }, + isOpen: function(){ + // summary: + // Returns the open state of this cell. + return this.cell.openStates && this.cell.getOpenState(this.item()); + }, + previous: function(){ + // summary: + // Returns the path that is before this path in the + // grid. If no path is found, returns null. + var new_path = this._arr.slice(0); + + if(this._str == "0"){ + return null; + } + + var last = new_path.length-1; + + if(new_path[last] === 0){ + new_path.pop(); + return new TreePath(new_path, this.grid); + } + + new_path[last]--; + var path = new TreePath(new_path, this.grid); + return path.lastChild(true); + }, + next: function(){ + // summary: + // Returns the next path in the grid. If no path + // is found, returns null. + var new_path = this._arr.slice(0); + + if(this.isOpen()){ + new_path.push(0); + }else{ + new_path[new_path.length-1]++; + for(var i=this.level; i>=0; i--){ + var item = this.grid.getItem(new_path.slice(0, i+1)); + if(i>0){ + if(!item){ + new_path.pop(); + new_path[i-1]++; + } + }else{ + if(!item){ + return null; + } + } + } + } + + return new TreePath(new_path, this.grid); + }, + children: function(alwaysReturn){ + // summary: + // Returns the child data items of this row. If this + // row isn't open and alwaysReturn is falsey, returns null. + if(!this.isOpen()&&!alwaysReturn){ + return null; + } + var items = []; + var model = this.grid.treeModel; + if(model){ + var item = this.item(); + var store = model.store; + if(!model.mayHaveChildren(item)){ + return null; + } + array.forEach(model.childrenAttrs, function(attr){ + items = items.concat(store.getValues(item, attr)); + }); + }else{ + items = this.store.getValues(this.item(), this.grid.layout.cells[this.cell.level+1].parentCell.field); + if(items.length>1&&this.grid.sortChildItems){ + var sortProps = this.grid.getSortProps(); + if(sortProps&&sortProps.length){ + var attr = sortProps[0].attribute, + grid = this.grid; + if(attr&&items[0][attr]){ + var desc = !!sortProps[0].descending; + items = items.slice(0); // don't touch the array in the store, make a copy + items.sort(function(a, b){ + return grid._childItemSorter(a, b, attr, desc); + }); + } + } + } + } + return items; + }, + childPaths: function(){ + var childItems = this.children(); + if(!childItems){ + return []; + } + return array.map(childItems, function(item, index){ + return new TreePath(this._str + '/' + index, this.grid); + }, this); + }, + parent: function(){ + // summary: + // Returns the parent path of this path. If this is a + // top-level row, returns null. + if(this.level === 0){ + return null; + } + return new TreePath(this._arr.slice(0, this.level), this.grid); + }, + lastChild: function(/*Boolean?*/ traverse){ + // summary: + // Returns the last child row below this path. If traverse + // is true, will traverse down to find the last child row + // of this branch. If there are no children, returns itself. + var children = this.children(); + if(!children || !children.length){ + return this; + } + var path = new TreePath(this._str + "/" + String(children.length-1), this.grid); + if(!traverse){ + return path; + } + return path.lastChild(true); + }, + toString: function(){ + return this._str; + } +}); + +var _TreeFocusManager = declare("dojox.grid._TreeFocusManager", _FocusManager, { + setFocusCell: function(inCell, inRowIndex){ + if(inCell && inCell.getNode(inRowIndex)){ + this.inherited(arguments); + } + }, + isLastFocusCell: function(){ + if(this.cell && this.cell.index == this.grid.layout.cellCount-1){ + var path = new TreePath(this.grid.rowCount-1, this.grid); + path = path.lastChild(true); + return this.rowIndex == path._str; + } + return false; + }, + next: function(){ + // summary: + // focus next grid cell + if(this.cell){ + var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1; + var path = new TreePath(this.rowIndex, this.grid); + if(col > cc){ + var new_path = path.next(); + if(!new_path){ + col--; + }else{ + col = 0; + path = new_path; + } + } + if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells + var nextCell = this.grid.getCell(col); + if (!this.isLastFocusCell() && !nextCell.editable){ + this._focusifyCellNode(false); + this.cell=nextCell; + this.rowIndex=path._str; + this.next(); + return; + } + } + this.setFocusIndex(path._str, col); + } + }, + previous: function(){ + // summary: + // focus previous grid cell + if(this.cell){ + var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1; + var path = new TreePath(row, this.grid); + if(col < 0){ + var new_path = path.previous(); + if(!new_path){ + col = 0; + }else{ + col = this.grid.layout.cellCount-1; + path = new_path; + } + } + if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells + var prevCell = this.grid.getCell(col); + if (!this.isFirstFocusCell() && !prevCell.editable){ + this._focusifyCellNode(false); + this.cell=prevCell; + this.rowIndex=path._str; + this.previous(); + return; + } + } + this.setFocusIndex(path._str, col); + } + }, + move: function(inRowDelta, inColDelta){ + if(this.isNavHeader()){ + this.inherited(arguments); + return; + } + if(!this.cell){ return; } + // Handle grid proper. + var sc = this.grid.scroller, + r = this.rowIndex, + rc = this.grid.rowCount-1, + path = new TreePath(this.rowIndex, this.grid); + if(inRowDelta){ + var row; + if(inRowDelta>0){ + path = path.next(); + row = path._arr[0]; + if(row > sc.getLastPageRow(sc.page)){ + //need to load additional data, let scroller do that + this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r)); + } + }else if(inRowDelta<0){ + path = path.previous(); + row = path._arr[0]; + if(row <= sc.getPageRow(sc.page)){ + //need to load additional data, let scroller do that + this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row)); + } + } + } + var cc = this.grid.layout.cellCount-1, + i = this.cell.index, + col = Math.min(cc, Math.max(0, i+inColDelta)); + var cell = this.grid.getCell(col); + var colDir = inColDelta < 0 ? -1 : 1; + while(col>=0 && col < cc && cell && cell.hidden === true){ + // skip hidden cells + col += colDir; + cell = this.grid.getCell(col); + } + if (!cell || cell.hidden === true){ + // don't change col if would move to hidden + col = i; + } + if(inRowDelta){ + this.grid.updateRow(r); + } + this.setFocusIndex(path._str, col); + } +}); + +var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, { + // summary: + // A grid that supports nesting rows - it provides an expando function + // similar to dijit.Tree. It also provides mechanisms for aggregating + // the values of subrows + // + // description: + // TreeGrid currently only works on "simple" structures. That is, + // single-view structures with a single row in them. + // + // The TreeGrid works using the concept of "levels" - level 0 are the + // top-level items. + + // defaultOpen: Boolean + // Whether or not we default to open (all levels). This defaults to + // false for grids with a treeModel. + defaultOpen: true, + + // sortChildItems: Boolean + // If true, child items will be returned sorted according to the sorting + // properties of the grid. + sortChildItems: false, + + // openAtLevels: Array + // Which levels we are open at (overrides defaultOpen for the values + // that exist here). Its values can be a boolean (true/false) or an + // integer (for the # of children to be closed if there are more than + // that) + openAtLevels: [], + + // treeModel: dijit.tree.ForestStoreModel + // A dijit.Tree model that will be used instead of using aggregates. + // Setting this value will make the TreeGrid behave like a columnar + // tree. When setting this value, defaultOpen will default to false, + // and openAtLevels will be ignored. + treeModel: null, + + // expandoCell: Integer + // When used in conjunction with a treeModel (see above), this is a 0-based + // index of the cell in which to place the actual expando + expandoCell: 0, + + // private values + // aggregator: Object + // The aggregator class - it will be populated automatically if we + // are a collapsable grid + aggregator: null, + + + // Override this to get our "magic" layout + _layoutClass: _TreeLayout, + + createSelection: function(){ + this.selection = new TreeSelection(this); + }, + + _childItemSorter: function(a, b, attribute, descending){ + var av = this.store.getValue(a, attribute); + var bv = this.store.getValue(b, attribute); + if(av != bv){ + return av < bv == descending ? 1 : -1; + } + return 0; + }, + + _onNew: function(item, parentInfo){ + if(!parentInfo || !parentInfo.item){ + this.inherited(arguments); + }else{ + var idx = this.getItemIndex(parentInfo.item); + if(typeof idx == "string"){ + this.updateRow(idx.split('/')[0]); + }else if(idx > -1){ + this.updateRow(idx); + } + } + }, + + _onSet: function(item, attribute, oldValue, newValue){ + this._checkUpdateStatus(); + if(this.aggregator){ + this.aggregator.clearSubtotalCache(); + } + var idx = this.getItemIndex(item); + if(typeof idx == "string"){ + this.updateRow(idx.split('/')[0]); + }else if(idx > -1){ + this.updateRow(idx); + } + }, + + _onDelete: function(item){ + this._cleanupExpandoCache(this._getItemIndex(item, true), this.store.getIdentity(item), item); + this.inherited(arguments); + }, + + _cleanupExpandoCache: function(index, identity, item){}, + + _addItem: function(item, index, noUpdate, dontUpdateRoot){ + // add our root items to the root of the model's children + // list since we don't query the model + if(!dontUpdateRoot && this.model && array.indexOf(this.model.root.children, item) == -1){ + this.model.root.children[index] = item; + } + this.inherited(arguments); + }, + + getItem: function(/*integer|Array|String*/ idx){ + // summary: + // overridden so that you can pass in a '/' delimited string of indexes to get the + // item based off its path...that is, passing in "1/3/2" will get the + // 3rd (0-based) child from the 4th child of the 2nd top-level item. + var isArray = lang.isArray(idx); + if(lang.isString(idx) && idx.indexOf('/')){ + idx = idx.split('/'); + isArray = true; + } + if(isArray && idx.length == 1){ + idx = idx[0]; + isArray = false; + } + if(!isArray){ + return DataGrid.prototype.getItem.call(this, idx); + } + var s = this.store; + var itm = DataGrid.prototype.getItem.call(this, idx[0]); + var cf, i, j; + if(this.aggregator){ + cf = this.aggregator.childFields||[]; + if(cf){ + for(i = 0; i < idx.length - 1 && itm; i++){ + if(cf[i]){ + itm = (s.getValues(itm, cf[i])||[])[idx[i + 1]]; + }else{ + itm = null; + } + } + } + }else if(this.treeModel){ + cf = this.treeModel.childrenAttrs||[]; + if(cf&&itm){ + for(i=1, il=idx.length; (i<il) && itm; i++) { + for(j=0, jl=cf.length; j<jl; j++) { + if(cf[j]){ + itm = (s.getValues(itm, cf[j])||[])[idx[i]]; + }else{ + itm = null; + } + if(itm){ break; } + } + } + } + } + return itm || null; + }, + + _getItemIndex: function(item, isDeleted){ + if(!isDeleted && !this.store.isItem(item)){ + return -1; + } + var idx = this.inherited(arguments); + if(idx == -1){ + var idty = this.store.getIdentity(item); + return this._by_idty_paths[idty] || -1; + } + return idx; + }, + + postMixInProperties: function(){ + if(this.treeModel && !("defaultOpen" in this.params)){ + // Default open to false for tree models, true for other tree + // grids. + this.defaultOpen = false; + } + var def = this.defaultOpen; + this.openAtLevels = array.map(this.openAtLevels, function(l){ + if(typeof l == "string"){ + switch(l.toLowerCase()){ + case "true": + return true; + break; + case "false": + return false; + break; + default: + var r = parseInt(l, 10); + if(isNaN(r)){ + return def; + } + return r; + break; + } + } + return l; + }); + this._by_idty_paths = {}; + this.inherited(arguments); + }, + + postCreate: function(){ + this.inherited(arguments); + if(this.treeModel){ + this._setModel(this.treeModel); + } + }, + + setModel: function(treeModel){ + this._setModel(treeModel); + this._refresh(true); + }, + + _setModel: function(treeModel){ + if(treeModel && (!ForestStoreModel || !(treeModel instanceof ForestStoreModel))){ + throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.ForestStoreModel"); + } + this.treeModel = treeModel; + domClass.toggle(this.domNode, "dojoxGridTreeModel", this.treeModel ? true : false); + this._setQuery(treeModel ? treeModel.query : null); + this._setStore(treeModel ? treeModel.store : null); + }, + + createScroller: function(){ + this.inherited(arguments); + this.scroller._origDefaultRowHeight = this.scroller.defaultRowHeight; + }, + + createManagers: function(){ + // summary: + // create grid managers for various tasks including rows, focus, selection, editing + + // row manager + this.rows = new _RowManager(this); + // focus manager + this.focus = new _TreeFocusManager(this); + // edit manager + this.edit = new _EditManager(this); + }, + + _setStore: function(store){ + this.inherited(arguments); + if(this.treeModel&&!this.treeModel.root.children){ + this.treeModel.root.children = []; + } + if(this.aggregator){ + this.aggregator.store = store; + } + }, + + getDefaultOpenState: function(cellDef, item){ + // summary: + // Returns the default open state for the given definition and item + // It reads from the openAtLevels and defaultOpen values of the + // grid to calculate if the given item should default to open or + // not. + var cf; + var store = this.store; + if(this.treeModel){ return this.defaultOpen; } + if(!cellDef || !store || !store.isItem(item) || + !(cf = this.aggregator.childFields[cellDef.level])){ + return this.defaultOpen; + } + if(this.openAtLevels.length > cellDef.level){ + var dVal = this.openAtLevels[cellDef.level]; + if(typeof dVal == "boolean"){ + return dVal; + }else if(typeof dVal == "number"){ + return (store.getValues(item, cf).length <= dVal); + } + } + return this.defaultOpen; + }, + onStyleRow: function(row){ + if(!this.layout._isCollapsable){ + this.inherited(arguments); + return; + } + var base = domAttr.get(row.node, 'dojoxTreeGridBaseClasses'); + if(base){ + row.customClasses = base; + } + var i = row; + var tagName = i.node.tagName.toLowerCase(); + i.customClasses += (i.odd?" dojoxGridRowOdd":"") + + (i.selected&&tagName=='tr'?" dojoxGridRowSelected":"") + + (i.over&&tagName=='tr'?" dojoxGridRowOver":""); + this.focus.styleRow(i); + this.edit.styleRow(i); + }, + styleRowNode: function(inRowIndex, inRowNode){ + if(inRowNode){ + if(inRowNode.tagName.toLowerCase() == 'div' && this.aggregator){ + query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(rowNode){ + this.rows.styleRowNode(domAttr.get(rowNode, 'dojoxTreeGridPath'), rowNode); + },this); + } + this.rows.styleRowNode(inRowIndex, inRowNode); + } + }, + onCanSelect: function(inRowIndex){ + var nodes = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode); + if(nodes.length){ + if(domClass.contains(nodes[0], 'dojoxGridSummaryRow')){ + return false; + } + } + return this.inherited(arguments); + }, + onKeyDown: function(e){ + if(e.altKey || e.metaKey){ + return; + } + switch(e.keyCode){ + case keys.UP_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex != "0"){ + event.stop(e); + this.focus.move(-1, 0); + } + break; + case keys.DOWN_ARROW: + var currPath = new TreePath(this.focus.rowIndex, this); + var lastPath = new TreePath(this.rowCount-1, this); + lastPath = lastPath.lastChild(true); + if(!this.edit.isEditing() && currPath.toString() != lastPath.toString()){ + event.stop(e); + this.focus.move(1, 0); + } + break; + default: + this.inherited(arguments); + break; + } + }, + canEdit: function(inCell, inRowIndex){ + var node = inCell.getNode(inRowIndex); + return node && this._canEdit; + }, + doApplyCellEdit: function(inValue, inRowIndex, inAttrName){ + var item = this.getItem(inRowIndex); + var oldValue = this.store.getValue(item, inAttrName); + if(typeof oldValue == 'number'){ + inValue = isNaN(inValue) ? inValue : parseFloat(inValue); + }else if(typeof oldValue == 'boolean'){ + inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue; + }else if(oldValue instanceof Date){ + var asDate = new Date(inValue); + inValue = isNaN(asDate.getTime()) ? inValue : asDate; + } + this.store.setValue(item, inAttrName, inValue); + this.onApplyCellEdit(inValue, inRowIndex, inAttrName); + } +}); +TreeGrid.markupFactory = function(props, node, ctor, cellFunc){ + var widthFromAttr = function(n){ + var w = domAttr.get(n, "width")||"auto"; + if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){ + w = parseInt(w, 10)+"px"; + } + return w; + }; + + var cellsFromMarkup = function(table){ + var rows; + // Don't support colgroup on our grid - single view, single row only + if(table.nodeName.toLowerCase() == "table" && + query("> colgroup", table).length === 0 && + (rows = query("> thead > tr", table)).length == 1){ + var tr = rows[0]; + return query("> th", rows[0]).map(function(th){ + // Grab type and field (the only ones that are shared + var cell = { + type: lang.trim(domAttr.get(th, "cellType")||""), + field: lang.trim(domAttr.get(th, "field")||"") + }; + if(cell.type){ + cell.type = lang.getObject(cell.type); + } + + var subTable = query("> table", th)[0]; + if(subTable){ + // If we have a subtable, we are an aggregate and a summary cell + cell.name = ""; + cell.children = cellsFromMarkup(subTable); + if(domAttr.has(th, "itemAggregates")){ + cell.itemAggregates = array.map(domAttr.get(th, "itemAggregates").split(","), function(v){ + return lang.trim(v); + }); + }else{ + cell.itemAggregates = []; + } + if(domAttr.has(th, "aggregate")){ + cell.aggregate = domAttr.get(th, "aggregate"); + } + cell.type = cell.type || dojox.grid.cells.SubtableCell; + }else{ + // Grab our other stuff we need (mostly what's in the normal + // Grid) + cell.name = lang.trim(domAttr.get(th, "name")||th.innerHTML); + if(domAttr.has(th, "width")){ + cell.width = widthFromAttr(th); + } + if(domAttr.has(th, "relWidth")){ + cell.relWidth = window.parseInt(domAttr.get(th, "relWidth"), 10); + } + if(domAttr.has(th, "hidden")){ + cell.hidden = domAttr.get(th, "hidden") == "true"; + } + cell.field = cell.field||cell.name; + DataGrid.cell_markupFactory(cellFunc, th, cell); + cell.type = cell.type || dojox.grid.cells.Cell; + } + if(cell.type && cell.type.markupFactory){ + cell.type.markupFactory(th, cell); + } + return cell; + }); + } + return []; + }; + + var rows; + if( !props.structure ){ + var row = cellsFromMarkup(node); + if(row.length){ + // Set our structure here - so that we don't try and set it in the + // markup factory + props.structure = [{__span: Infinity, cells:[row]}]; + } + } + return DataGrid.markupFactory(props, node, ctor, cellFunc); +}; + +return TreeGrid; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/TreeSelection.js b/js/dojo-1.7.2/dojox/grid/TreeSelection.js new file mode 100644 index 0000000..84e4b74 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/TreeSelection.js @@ -0,0 +1,216 @@ +//>>built +define("dojox/grid/TreeSelection", [ + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/dom-attr", + "dojo/query", + "./DataSelection" +], function(dojox, declare, array, lang, domAttr, query, DataSelection){ + +return declare("dojox.grid.TreeSelection", DataSelection, { + setMode: function(mode){ + this.selected = {}; + this.sorted_sel = []; + this.sorted_ltos = {}; + this.sorted_stol = {}; + DataSelection.prototype.setMode.call(this, mode); + }, + addToSelection: function(inItemOrIndex){ + if(this.mode == 'none'){ return; } + var idx = null; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + if(this.selected[idx]){ + this.selectedIndex = idx; + }else{ + if(this.onCanSelect(idx) !== false){ + this.selectedIndex = idx; + var rowNodes = query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode); + if(rowNodes.length){ + domAttr.set(rowNodes[0], "aria-selected", "true"); + } + this._beginUpdate(); + this.selected[idx] = true; + this._insertSortedSelection(idx); + //this.grid.onSelected(idx); + this.onSelected(idx); + //this.onSetSelected(idx, true); + this._endUpdate(); + } + } + }, + deselect: function(inItemOrIndex){ + if(this.mode == 'none'){ return; } + var idx = null; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + idx = inItemOrIndex; + }else{ + idx = this.grid.getItemIndex(inItemOrIndex); + } + if(this.selectedIndex == idx){ + this.selectedIndex = -1; + } + if(this.selected[idx]){ + if(this.onCanDeselect(idx) === false){ + return; + } + var rowNodes = query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode); + if(rowNodes.length){ + domAttr.set(rowNodes[0], "aria-selected", "false"); + } + this._beginUpdate(); + delete this.selected[idx]; + this._removeSortedSelection(idx); + //this.grid.onDeselected(idx); + this.onDeselected(idx); + //this.onSetSelected(idx, false); + this._endUpdate(); + } + }, + getSelected: function(){ + var result = []; + for(var i in this.selected){ + if(this.selected[i]){ + result.push(this.grid.getItem(i)); + } + } + return result; + }, + getSelectedCount: function(){ + var c = 0; + for(var i in this.selected){ + if(this.selected[i]){ + c++; + } + } + return c; + }, + _bsearch: function(v){ + var o = this.sorted_sel; + var h = o.length - 1, l = 0, m; + while(l<=h){ + var cmp = this._comparePaths(o[m = (l + h) >> 1], v); + if(cmp < 0){ l = m + 1; continue; } + if(cmp > 0){ h = m - 1; continue; } + return m; + } + return cmp < 0 ? m - cmp : m; + }, + _comparePaths: function(a, b){ + for(var i=0, l=(a.length < b.length ? a.length : b.length); i<l; i++){ + if(a[i]<b[i]){ return -1; } + if(a[i]>b[i]){ return 1; } + } + if(a.length<b.length){ return -1; } + if(a.length>b.length){ return 1; } + return 0; + }, + _insertSortedSelection: function(index){ + index = String(index); + var s = this.sorted_sel; + var sl = this.sorted_ltos; + var ss = this.sorted_stol; + + var lpath = index.split('/'); + lpath = array.map(lpath, function(item){ return parseInt(item, 10); }); + sl[lpath] = index; + ss[index] = lpath; + + if(s.length === 0){ + s.push(lpath); + return; + } + if(s.length==1){ + var cmp = this._comparePaths(s[0], lpath); + if(cmp==1){ s.unshift(lpath); } + else{ s.push(lpath); } + return; + } + + var idx = this._bsearch(lpath); + this.sorted_sel.splice(idx, 0, lpath); + }, + _removeSortedSelection: function(index){ + index = String(index); + var s = this.sorted_sel; + var sl = this.sorted_ltos; + var ss = this.sorted_stol; + + if(s.length === 0){ + return; + } + + var lpath = ss[index]; + if(!lpath){ return; } + + var idx = this._bsearch(lpath); + if(idx > -1){ + delete sl[lpath]; + delete ss[index]; + s.splice(idx, 1); + } + }, + getFirstSelected: function(){ + if(!this.sorted_sel.length||this.mode == 'none'){ return -1; } + var fpath = this.sorted_sel[0]; + if(!fpath){ + return -1; + } + fpath = this.sorted_ltos[fpath]; + if(!fpath){ + return -1; + } + return fpath; + }, + getNextSelected: function(inPrev){ + if(!this.sorted_sel.length||this.mode == 'none'){ return -1; } + inPrev = String(inPrev); + var prevPath = this.sorted_stol[inPrev]; + if(!prevPath){ return -1; } + + var idx = this._bsearch(prevPath); + var lpath = this.sorted_sel[idx+1]; + if(!lpath){ + return -1; + } + return this.sorted_ltos[lpath]; + }, + _range: function(inFrom, inTo, func){ + if(!lang.isString(inFrom) && inFrom < 0){ + inFrom = inTo; + } + var cells = this.grid.layout.cells, + store = this.grid.store, + grid = this.grid; + inFrom = new dojox.grid.TreePath(String(inFrom), grid); + inTo = new dojox.grid.TreePath(String(inTo), grid); + + if(inFrom.compare(inTo) > 0){ + var tmp = inFrom; + inFrom = inTo; + inTo = tmp; + } + + var inFromStr = inFrom._str, inToStr = inTo._str; + + // select/deselect the first + func(inFromStr); + + var p = inFrom; + while((p = p.next())){ + if(p._str == inToStr){ + break; + } + func(p._str); + } + + // select/deselect the last + func(inToStr); + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_Builder.js b/js/dojo-1.7.2/dojox/grid/_Builder.js new file mode 100644 index 0000000..6cc1ea6 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_Builder.js @@ -0,0 +1,760 @@ +//>>built +define("dojox/grid/_Builder", [ + "../main", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/window", + "dojo/_base/event", + "dojo/_base/sniff", + "dojo/_base/connect", + "dojo/dnd/Moveable", + "dojox/html/metrics", + "./util", + "dojo/_base/html" +], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html){ + + var dg = dojox.grid; + + var getTdIndex = function(td){ + return td.cellIndex >=0 ? td.cellIndex : array.indexOf(td.parentNode.cells, td); + }; + + var getTrIndex = function(tr){ + return tr.rowIndex >=0 ? tr.rowIndex : array.indexOf(tr.parentNode.childNodes, tr); + }; + + var getTr = function(rowOwner, index){ + return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]); + }; + + var findTable = function(node){ + for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){} + return n; + }; + + var ascendDom = function(inNode, inWhile){ + for(var n=inNode; n && inWhile(n); n=n.parentNode){} + return n; + }; + + var makeNotTagName = function(inTagName){ + var name = inTagName.toUpperCase(); + return function(node){ return node.tagName != name; }; + }; + + var rowIndexTag = util.rowIndexTag; + var gridViewTag = util.gridViewTag; + + // base class for generating markup for the views + var _Builder = dg._Builder = lang.extend(function(view){ + if(view){ + this.view = view; + this.grid = view.grid; + } + },{ + view: null, + // boilerplate HTML + _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"', + + // Returns the table variable as an array - and with the view width, if specified + getTableArray: function(){ + var html = [this._table]; + if(this.view.viewWidth){ + html.push([' style="width:', this.view.viewWidth, ';"'].join('')); + } + html.push('>'); + return html; + }, + + // generate starting tags for a cell + generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){ + var result = [], html; + if(isHeader){ + var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"'; + if (!inCell.id){ + inCell.id = this.grid.id + "Hdr" + inCell.index; + } + // column headers are not editable, mark as aria-readonly=true + html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"']; + }else{ + // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable) + // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true + // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit + var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : ""; + html = ['<td tabIndex="-1" role="gridcell"', editInfo]; + } + if(inCell.colSpan){ + html.push(' colspan="', inCell.colSpan, '"'); + } + if(inCell.rowSpan){ + html.push(' rowspan="', inCell.rowSpan, '"'); + } + html.push(' class="dojoxGridCell '); + if(inCell.classes){ + html.push(inCell.classes, ' '); + } + if(inMoreClasses){ + html.push(inMoreClasses, ' '); + } + // result[0] => td opener, style + result.push(html.join('')); + // SLOT: result[1] => td classes + result.push(''); + html = ['" idx="', inCell.index, '" style="']; + if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){ + inMoreStyles += ';'; + } + html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':''); + if(inCell.unitWidth){ + html.push('width:', inCell.unitWidth, ';'); + } + // result[2] => markup + result.push(html.join('')); + // SLOT: result[3] => td style + result.push(''); + html = [ '"' ]; + if(inCell.attrs){ + html.push(" ", inCell.attrs); + } + html.push('>'); + // result[4] => td postfix + result.push(html.join('')); + // SLOT: result[5] => content + result.push(''); + // result[6] => td closes + result.push(isHeader?'</th>':'</td>'); + return result; // Array + }, + + // cell finding + isCellNode: function(inNode){ + return Boolean(inNode && inNode!=win.doc && html.attr(inNode, "idx")); + }, + + getCellNodeIndex: function(inCellNode){ + return inCellNode ? Number(html.attr(inCellNode, "idx")) : -1; + }, + + getCellNode: function(inRowNode, inCellIndex){ + for(var i=0, row; ((row = getTr(inRowNode.firstChild, i)) && row.cells); i++){ + for(var j=0, cell; (cell = row.cells[j]); j++){ + if(this.getCellNodeIndex(cell) == inCellIndex){ + return cell; + } + } + } + return null; + }, + + findCellTarget: function(inSourceNode, inTopNode){ + var n = inSourceNode; + while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){ + n = n.parentNode; + } + return n!=inTopNode ? n : null; + }, + + // event decoration + baseDecorateEvent: function(e){ + e.dispatch = 'do' + e.type; + e.grid = this.grid; + e.sourceView = this.view; + e.cellNode = this.findCellTarget(e.target, e.rowNode); + e.cellIndex = this.getCellNodeIndex(e.cellNode); + e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null); + }, + + // event dispatch + findTarget: function(inSource, inTag){ + var n = inSource; + while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){ + n = n.parentNode; + } + return (n != this.domNode) ? n : null; + }, + + findRowTarget: function(inSource){ + return this.findTarget(inSource, rowIndexTag); + }, + + isIntraNodeEvent: function(e){ + try{ + return (e.cellNode && e.relatedTarget && html.isDescendant(e.relatedTarget, e.cellNode)); + }catch(x){ + // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + return false; + } + }, + + isIntraRowEvent: function(e){ + try{ + var row = e.relatedTarget && this.findRowTarget(e.relatedTarget); + return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex); + }catch(x){ + // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 + return false; + } + }, + + dispatchEvent: function(e){ + if(e.dispatch in this){ + return this[e.dispatch](e); + } + return false; + }, + + // dispatched event handlers + domouseover: function(e){ + if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){ + this.lastOverCellNode = e.cellNode; + this.grid.onMouseOver(e); + } + this.grid.onMouseOverRow(e); + }, + + domouseout: function(e){ + if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){ + this.lastOverCellNode = null; + this.grid.onMouseOut(e); + if(!this.isIntraRowEvent(e)){ + this.grid.onMouseOutRow(e); + } + } + }, + + domousedown: function(e){ + if (e.cellNode) + this.grid.onMouseDown(e); + this.grid.onMouseDownRow(e); + } + }); + + // Produces html for grid data content. Owned by grid and used internally + // for rendering data. Override to implement custom rendering. + var _ContentBuilder = dg._ContentBuilder = lang.extend(function(view){ + _Builder.call(this, view); + },_Builder.prototype,{ + update: function(){ + this.prepareHtml(); + }, + + // cache html for rendering data rows + prepareHtml: function(){ + var defaultGet=this.grid.get, cells=this.view.structure.cells; + for(var j=0, row; (row=cells[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + cell.get = cell.get || (cell.value == undefined) && defaultGet; + cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false); + if (!this.grid.editable && cell.editable){ + this.grid.editable = true; + } + } + } + }, + + // time critical: generate html using cache and data source + generateHtml: function(inDataIndex, inRowIndex){ + var + html = this.getTableArray(), + v = this.view, + cells = v.structure.cells, + item = this.grid.getItem(inRowIndex); + + util.fire(this.view, "onBeforeRow", [inRowIndex, cells]); + for(var j=0, row; (row=cells[j]); j++){ + if(row.hidden || row.header){ + continue; + } + html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">'); + for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){ + m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = []; + // content (format can fill in cc and cs as side-effects) + m[5] = cell.format(inRowIndex, item); + if(has("ie") < 8 && (m[5] === null || m[5] === '' || /^\s+$/.test(m[5]))){ + //fix IE 6/7 quirks - border style not effective for empty td + m[5] = ' ' + } + // classes + m[1] = cc.join(' '); + // styles + m[3] = cs.join(';'); + // in-place concat + html.push.apply(html, m); + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); // String + }, + + decorateEvent: function(e){ + e.rowNode = this.findRowTarget(e.target); + if(!e.rowNode){return false;} + e.rowIndex = e.rowNode[rowIndexTag]; + this.baseDecorateEvent(e); + e.cell = this.grid.getCell(e.cellIndex); + return true; // Boolean + } + }); + + // Produces html for grid header content. Owned by grid and used internally + // for rendering data. Override to implement custom rendering. + var _HeaderBuilder = dg._HeaderBuilder = lang.extend(function(view){ + this.moveable = null; + _Builder.call(this, view); + },_Builder.prototype,{ + _skipBogusClicks: false, + overResizeWidth: 4, + minColWidth: 1, + + update: function(){ + if(this.tableMap){ + this.tableMap.mapRows(this.view.structure.cells); + }else{ + this.tableMap = new dg._TableMap(this.view.structure.cells); + } + }, + + generateHtml: function(inGetValue, inValue){ + var html = this.getTableArray(), cells = this.view.structure.cells; + + util.fire(this.view, "onBeforeRow", [-1, cells]); + for(var j=0, row; (row=cells[j]); j++){ + if(row.hidden){ + continue; + } + html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">'); + for(var i=0, cell, markup; (cell=row[i]); i++){ + cell.customClasses = []; + cell.customStyles = []; + if(this.view.simpleStructure){ + if(cell.draggable){ + if(cell.headerClasses){ + if(cell.headerClasses.indexOf('dojoDndItem') == -1){ + cell.headerClasses += ' dojoDndItem'; + } + }else{ + cell.headerClasses = 'dojoDndItem'; + } + } + if(cell.attrs){ + if(cell.attrs.indexOf("dndType='gridColumn_") == -1){ + cell.attrs += " dndType='gridColumn_" + this.grid.id + "'"; + } + }else{ + cell.attrs = "dndType='gridColumn_" + this.grid.id + "'"; + } + } + markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true); + // content + markup[5] = (inValue != undefined ? inValue : inGetValue(cell)); + // styles + markup[3] = cell.customStyles.join(';'); + // classes + markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : ''); + html.push(markup.join('')); + } + html.push('</tr>'); + } + html.push('</table>'); + return html.join(''); + }, + + // event helpers + getCellX: function(e){ + var n, x = e.layerX; + if(has("mozilla") || has("ie") >= 9){ + n = ascendDom(e.target, makeNotTagName("th")); + x -= (n && n.offsetLeft) || 0; + var t = e.sourceView.getScrollbarWidth(); + if(!this.grid.isLeftToRight()/*&& e.sourceView.headerNode.scrollLeft < t*/){ + //fix #11253 + table = ascendDom(n,makeNotTagName("table")); + x -= (table && table.offsetLeft) || 0; + } + //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0; + } + n = ascendDom(e.target, function(){ + if(!n || n == e.cellNode){ + return false; + } + // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width + // when parent has border, overflow: hidden, and is positioned + // handle this problem here ... not a general solution! + x += (n.offsetLeft < 0 ? 0 : n.offsetLeft); + return true; + }); + return x; + }, + + // event decoration + decorateEvent: function(e){ + this.baseDecorateEvent(e); + e.rowIndex = -1; + e.cellX = this.getCellX(e); + return true; + }, + + // event handlers + // resizing + prepareResize: function(e, mod){ + do{ + var i = e.cellIndex; + e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null); + e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1); + }while(e.cellNode && e.cellNode.style.display == "none"); + return Boolean(e.cellNode); + }, + + canResize: function(e){ + if(!e.cellNode || e.cellNode.colSpan > 1){ + return false; + } + var cell = this.grid.getCell(e.cellIndex); + return !cell.noresize && cell.canResize(); + }, + + overLeftResizeArea: function(e){ + // We are never over a resize area if we are in the process of moving + if(html.hasClass(win.body(), "dojoDndMove")){ + return false; + } + //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs + //as if they were still on the left instead of returning the position they were 'float: right' to. + //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over + //the image or text nodes, then just ignored them/treat them not in scale range. + if(has("ie")){ + var tN = e.target; + if(html.hasClass(tN, "dojoxGridArrowButtonNode") || + html.hasClass(tN, "dojoxGridArrowButtonChar") || + html.hasClass(tN, "dojoxGridColCaption")){ + return false; + } + } + + if(this.grid.isLeftToRight()){ + return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1); + } + var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth); + return t; + }, + + overRightResizeArea: function(e){ + // We are never over a resize area if we are in the process of moving + if(html.hasClass(win.body(), "dojoDndMove")){ + return false; + } + //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs + //as if they were still on the left instead of returning the position they were 'float: right' to. + //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over + //the image or text nodes, then just ignored them/treat them not in scale range. + if(has("ie")){ + var tN = e.target; + if(html.hasClass(tN, "dojoxGridArrowButtonNode") || + html.hasClass(tN, "dojoxGridArrowButtonChar") || + html.hasClass(tN, "dojoxGridColCaption")){ + return false; + } + } + + if(this.grid.isLeftToRight()){ + return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth); + } + return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1); + }, + + domousemove: function(e){ + //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth); + if(!this.moveable){ + var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : '')); + if(c && !this.canResize(e)){ + c = 'dojoxGridColNoResize'; + } + html.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize")); + html.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize")); + if(c){ + event.stop(e); + } + } + }, + + domousedown: function(e){ + if(!this.moveable){ + if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){ + this.beginColumnResize(e); + }else{ + this.grid.onMouseDown(e); + this.grid.onMouseOverRow(e); + } + //else{ + // this.beginMoveColumn(e); + //} + } + }, + + doclick: function(e) { + if(this._skipBogusClicks){ + event.stop(e); + return true; + } + return false; + }, + + // column resizing + colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){ + //Set up the drag object for column resizing + // Called with mouse event in case of drag and drop, + // Also called from keyboard shift-arrow event when focus is on a header + var headContentBox = html.contentBox(e.sourceView.headerNode); + + if(isMouse){ //IE draws line even with no mouse down so separate from keyboard + this.lineDiv = document.createElement('div'); + + var vw = html.position(e.sourceView.headerNode, true); + var bodyContentBox = html.contentBox(e.sourceView.domNode); + //fix #11340 + var l = e.pageX; + if(!this.grid.isLeftToRight() && has("ie") < 8){ + l -= metrics.getScrollbar().w; + } + html.style(this.lineDiv, { + top: vw.y + "px", + left: l + "px", + height: (bodyContentBox.h + headContentBox.h) + "px" + }); + html.addClass(this.lineDiv, "dojoxGridResizeColLine"); + this.lineDiv._origLeft = l; + win.body().appendChild(this.lineDiv); + } + var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode); + for(var i=0, cell; (cell=nodes[i]); i++){ + spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth }); + //console.log("spanner: " + this.getCellNodeIndex(cell)); + } + + var view = e.sourceView; + var adj = this.grid.isLeftToRight() ? 1 : -1; + var views = e.grid.views.views; + var followers = []; + for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){ + followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) }); + } + var table = view.headerContentNode.firstChild; + var drag = { + scrollLeft: e.sourceView.headerNode.scrollLeft, + view: view, + node: e.cellNode, + index: e.cellIndex, + w: html.contentBox(e.cellNode).w, + vw: headContentBox.w, + table: table, + tw: html.contentBox(table).w, + spanners: spanners, + followers: followers + }; + return drag; + }, + beginColumnResize: function(e){ + this.moverDiv = document.createElement("div"); + html.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl + win.body().appendChild(this.moverDiv); + html.addClass(this.grid.domNode, "dojoxGridColumnResizing"); + var m = (this.moveable = new Moveable(this.moverDiv)); + + var drag = this.colResizeSetup(e,true); + + m.onMove = lang.hitch(this, "doResizeColumn", drag); + + connect.connect(m, "onMoveStop", lang.hitch(this, function(){ + this.endResizeColumn(drag); + if(drag.node.releaseCapture){ + drag.node.releaseCapture(); + } + this.moveable.destroy(); + delete this.moveable; + this.moveable = null; + html.removeClass(this.grid.domNode, "dojoxGridColumnResizing"); + })); + + if(e.cellNode.setCapture){ + e.cellNode.setCapture(); + } + m.onMouseDown(e); + }, + + doResizeColumn: function(inDrag, mover, leftTop){ + var changeX = leftTop.l; + var data = { + deltaX: changeX, + w: inDrag.w + (this.grid.isLeftToRight() ? changeX : -changeX),//fix #11341 + vw: inDrag.vw + changeX, + tw: inDrag.tw + changeX + }; + + this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop}; + + if(data.w >= this.minColWidth){ + if (!mover) { // we are using keyboard do immediate resize + this.doResizeNow(inDrag, data); + } + else{ + html.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px"); + } + } + }, + + endResizeColumn: function(inDrag){ + if(this.dragRecord){ + var leftTop = this.dragRecord.leftTop; + var changeX = this.grid.isLeftToRight() ? leftTop.l : -leftTop.l; + // Make sure we are not under our minimum + // http://bugs.dojotoolkit.org/ticket/9390 + changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX); + if(has("webkit") && inDrag.spanners.length){ + // Webkit needs the pad border extents back in + changeX += html._getPadBorderExtents(inDrag.spanners[0].node).w; + } + var data = { + deltaX: changeX, + w: inDrag.w + changeX, + vw: inDrag.vw + changeX, + tw: inDrag.tw + changeX + }; + // Only resize the columns when the drag has finished + this.doResizeNow(inDrag, data); + delete this.dragRecord; + } + + html.destroy(this.lineDiv); + html.destroy(this.moverDiv); + html.destroy(this.moverDiv); + delete this.moverDiv; + this._skipBogusClicks = true; + inDrag.view.update(); + this._skipBogusClicks = false; + this.grid.onResizeColumn(inDrag.index); + }, + doResizeNow: function(inDrag, data){ + inDrag.view.convertColPctToFixed(); + if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){ + var t = findTable(inDrag.node); + if(t){ + (t.style.width = ''); + } + } + var i, s, sw, f, fl; + for(i=0; (s=inDrag.spanners[i]); i++){ + sw = s.width + data.deltaX; + if(sw > 0){ + s.node.style.width = sw + 'px'; + inDrag.view.setColWidth(s.index, sw); + } + } + if(this.grid.isLeftToRight() || !has("ie")){//fix #11339 + for(i=0; (f=inDrag.followers[i]); i++){ + fl = f.left + data.deltaX; + f.node.style.left = fl + 'px'; + } + } + inDrag.node.style.width = data.w + 'px'; + inDrag.view.setColWidth(inDrag.index, data.w); + inDrag.view.headerNode.style.width = data.vw + 'px'; + inDrag.view.setColumnsWidth(data.tw); + if(!this.grid.isLeftToRight()){ + inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX; + } + } + }); + + // Maps an html table into a structure parsable for information about cell row and col spanning. + // Used by HeaderBuilder. + dg._TableMap = lang.extend(function(rows){ + this.mapRows(rows); + },{ + map: null, + + mapRows: function(inRows){ + // summary: Map table topography + + //console.log('mapRows'); + // # of rows + var rowCount = inRows.length; + if(!rowCount){ + return; + } + // map which columns and rows fill which cells + this.map = []; + var row; + for(var k=0; (row=inRows[k]); k++){ + this.map[k] = []; + } + for(var j=0; (row=inRows[j]); j++){ + for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){ + while(this.map[j][x]){x++;} + this.map[j][x] = { c: i, r: j }; + rowSpan = cell.rowSpan || 1; + colSpan = cell.colSpan || 1; + for(var y=0; y<rowSpan; y++){ + for(var s=0; s<colSpan; s++){ + this.map[j+y][x+s] = this.map[j][x]; + } + } + x += colSpan; + } + } + //this.dumMap(); + }, + + dumpMap: function(){ + for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){ + for(var i=0, cell; (cell=row[i]); i++){ + h += cell.r + ',' + cell.c + ' '; + } + } + }, + + getMapCoords: function(inRow, inCol){ + // summary: Find node's map coords by it's structure coords + for(var j=0, row; (row=this.map[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + if(cell.c==inCol && cell.r == inRow){ + return { j: j, i: i }; + } + //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); }; + } + } + return { j: -1, i: -1 }; + }, + + getNode: function(inTable, inRow, inCol){ + // summary: Find a node in inNode's table with the given structure coords + var row = inTable && inTable.rows[inRow]; + return row && row.cells[inCol]; + }, + + _findOverlappingNodes: function(inTable, inRow, inCol){ + var nodes = []; + var m = this.getMapCoords(inRow, inCol); + //console.log("node j: %d, i: %d", m.j, m.i); + for(var j=0, row; (row=this.map[j]); j++){ + if(j == m.j){ continue; } + var rw = row[m.i]; + //console.log("overlaps: r: %d, c: %d", rw.r, rw.c); + var n = (rw?this.getNode(inTable, rw.r, rw.c):null); + if(n){ nodes.push(n); } + } + //console.log(nodes); + return nodes; + }, + + findOverlappingNodes: function(inNode){ + return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode)); + } + }); + + return { + _Builder: _Builder, + _HeaderBuilder: _HeaderBuilder, + _ContentBuilder: _ContentBuilder + }; +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js b/js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js new file mode 100644 index 0000000..56434fe --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js @@ -0,0 +1,4 @@ +//>>built +define("dojox/grid/_CheckBoxSelector", ["../main", "./_Selector"], function(dojox){ + return dojox.grid._CheckBoxSelector; +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_EditManager.js b/js/dojo-1.7.2/dojox/grid/_EditManager.js new file mode 100644 index 0000000..bc3f2b9 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_EditManager.js @@ -0,0 +1,259 @@ +//>>built +define("dojox/grid/_EditManager", [ + "dojo/_base/lang", + "dojo/_base/array", + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/sniff", + "./util" +], function(lang, array, declare, connect, has, util){ + +return declare("dojox.grid._EditManager", null, { + // summary: + // Controls grid cell editing process. Owned by grid and used internally for editing. + constructor: function(inGrid){ + // inGrid: dojox.Grid + // The dojox.Grid this editor should be attached to + this.grid = inGrid; + if(has("ie")){ + this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))]; + }else{ + this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')]; + } + }, + + info: {}, + + destroy: function(){ + array.forEach(this.connections, connect.disconnect); + }, + + cellFocus: function(inCell, inRowIndex){ + // summary: + // Invoke editing when cell is focused + // inCell: cell object + // Grid cell object + // inRowIndex: Integer + // Grid row index + if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){ + // if same row or quick editing, edit + this.setEditCell(inCell, inRowIndex); + }else{ + // otherwise, apply any pending row edits + this.apply(); + } + // if dynamic or static editing... + if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){ + // let the editor focus itself as needed + this._focusEditor(inCell, inRowIndex); + } + }, + + rowClick: function(e){ + if(this.isEditing() && !this.isEditRow(e.rowIndex)){ + this.apply(); + } + }, + + styleRow: function(inRow){ + if(inRow.index == this.info.rowIndex){ + inRow.customClasses += ' dojoxGridRowEditing'; + } + }, + + dispatchEvent: function(e){ + var c = e.cell, ed = (c && c["editable"]) ? c : 0; + return ed && ed.dispatchEvent(e.dispatch, e); + }, + + // Editing + isEditing: function(){ + // summary: + // Indicates editing state of the grid. + // returns: Boolean + // True if grid is actively editing + return this.info.rowIndex !== undefined; + }, + + isEditCell: function(inRowIndex, inCellIndex){ + // summary: + // Indicates if the given cell is being edited. + // inRowIndex: Integer + // Grid row index + // inCellIndex: Integer + // Grid cell index + // returns: Boolean + // True if given cell is being edited + return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex); + }, + + isEditRow: function(inRowIndex){ + // summary: + // Indicates if the given row is being edited. + // inRowIndex: Integer + // Grid row index + // returns: Boolean + // True if given row is being edited + return this.info.rowIndex === inRowIndex; + }, + + setEditCell: function(inCell, inRowIndex){ + // summary: + // Set the given cell to be edited + // inRowIndex: Integer + // Grid row index + // inCell: Object + // Grid cell object + if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){ + this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable); + } + }, + + _focusEditor: function(inCell, inRowIndex){ + util.fire(inCell, "focus", [inRowIndex]); + }, + + focusEditor: function(){ + if(this.isEditing()){ + this._focusEditor(this.info.cell, this.info.rowIndex); + } + }, + + // implement fix for focus boomerang effect on IE + _boomerangWindow: 500, + _shouldCatchBoomerang: function(){ + return this._catchBoomerang > new Date().getTime(); + }, + _boomerangFocus: function(){ + //console.log("_boomerangFocus"); + if(this._shouldCatchBoomerang()){ + // make sure we don't utterly lose focus + this.grid.focus.focusGrid(); + // let the editor focus itself as needed + this.focusEditor(); + // only catch once + this._catchBoomerang = 0; + } + }, + _doCatchBoomerang: function(){ + // give ourselves a few ms to boomerang IE focus effects + if(has("ie")){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;} + }, + // end boomerang fix API + + start: function(inCell, inRowIndex, inEditing){ + if(!this._isValidInput()){ + return; + } + this.grid.beginUpdate(); + this.editorApply(); + if(this.isEditing() && !this.isEditRow(inRowIndex)){ + this.applyRowEdit(); + this.grid.updateRow(inRowIndex); + } + if(inEditing){ + this.info = { cell: inCell, rowIndex: inRowIndex }; + this.grid.doStartEdit(inCell, inRowIndex); + this.grid.updateRow(inRowIndex); + }else{ + this.info = {}; + } + this.grid.endUpdate(); + // make sure we don't utterly lose focus + this.grid.focus.focusGrid(); + // let the editor focus itself as needed + this._focusEditor(inCell, inRowIndex); + // give ourselves a few ms to boomerang IE focus effects + this._doCatchBoomerang(); + }, + + _editorDo: function(inMethod){ + var c = this.info.cell; + //c && c.editor && c.editor[inMethod](c, this.info.rowIndex); + if(c && c.editable){ + c[inMethod](this.info.rowIndex); + } + }, + + editorApply: function(){ + this._editorDo("apply"); + }, + + editorCancel: function(){ + this._editorDo("cancel"); + }, + + applyCellEdit: function(inValue, inCell, inRowIndex){ + if(this.grid.canEdit(inCell, inRowIndex)){ + this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field); + } + }, + + applyRowEdit: function(){ + this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field); + }, + + apply: function(){ + // summary: + // Apply a grid edit + if(this.isEditing() && this._isValidInput()){ + this.grid.beginUpdate(); + this.editorApply(); + this.applyRowEdit(); + this.info = {}; + this.grid.endUpdate(); + this.grid.focus.focusGrid(); + this._doCatchBoomerang(); + } + }, + + cancel: function(){ + // summary: + // Cancel a grid edit + if(this.isEditing()){ + this.grid.beginUpdate(); + this.editorCancel(); + this.info = {}; + this.grid.endUpdate(); + this.grid.focus.focusGrid(); + this._doCatchBoomerang(); + } + }, + + save: function(inRowIndex, inView){ + // summary: + // Save the grid editing state + // inRowIndex: Integer + // Grid row index + // inView: Object + // Grid view + var c = this.info.cell; + if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){ + c.save(c, this.info.rowIndex); + } + }, + + restore: function(inView, inRowIndex){ + // summary: + // Restores the grid editing state + // inRowIndex: Integer + // Grid row index + // inView: Object + // Grid view + var c = this.info.cell; + if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){ + c.restore(this.info.rowIndex); + } + }, + + _isValidInput: function(){ + var w = (this.info.cell || {}).widget; + if(!w || !w.isValid){ + //no validation needed + return true; + } + w.focused = true; + return w.isValid(true); + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_Events.js b/js/dojo-1.7.2/dojox/grid/_Events.js new file mode 100644 index 0000000..0156a86 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_Events.js @@ -0,0 +1,508 @@ +//>>built +define("dojox/grid/_Events", [ + "dojo/keys", + "dojo/dom-class", + "dojo/_base/declare", + "dojo/_base/event", + "dojo/_base/sniff" +], function(keys, domClass, declare, event, has){ + +return declare("dojox.grid._Events", null, { + // summary: + // _Grid mixin that provides default implementations for grid events. + // description: + // Default synthetic events dispatched for _Grid. dojo.connect to events to + // retain default implementation or override them for custom handling. + + // cellOverClass: String + // css class to apply to grid cells over which the cursor is placed. + cellOverClass: "dojoxGridCellOver", + + onKeyEvent: function(e){ + // summary: top level handler for Key Events + this.dispatchKeyEvent(e); + }, + + onContentEvent: function(e){ + // summary: Top level handler for Content events + this.dispatchContentEvent(e); + }, + + onHeaderEvent: function(e){ + // summary: Top level handler for header events + this.dispatchHeaderEvent(e); + }, + + onStyleRow: function(inRow){ + // summary: + // Perform row styling on a given row. Called whenever row styling is updated. + // + // inRow: Object + // Object containing row state information: selected, true if the row is selcted; over: + // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and + // customStyles to control row css classes and styles; both properties are strings. + // + // example: onStyleRow({ selected: true, over:true, odd:false }) + var i = inRow; + i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":""); + this.focus.styleRow(inRow); + this.edit.styleRow(inRow); + }, + + onKeyDown: function(e){ + // summary: + // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit, + // tab, shift-tab, and arrow keys move grid cell focus. + if(e.altKey || e.metaKey){ + return; + } + var colIdx; + switch(e.keyCode){ + case keys.ESCAPE: + this.edit.cancel(); + break; + case keys.ENTER: + if(!this.edit.isEditing()){ + colIdx = this.focus.getHeaderIndex(); + if(colIdx >= 0) { + this.setSortIndex(colIdx); + break; + }else { + this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey); + } + event.stop(e); + } + if(!e.shiftKey){ + var isEditing = this.edit.isEditing(); + this.edit.apply(); + if(!isEditing){ + this.edit.setEditCell(this.focus.cell, this.focus.rowIndex); + } + } + if (!this.edit.isEditing()){ + var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view + curView.content.decorateEvent(e); + this.onRowClick(e); + event.stop(e); + } + break; + case keys.SPACE: + if(!this.edit.isEditing()){ + colIdx = this.focus.getHeaderIndex(); + if(colIdx >= 0) { + this.setSortIndex(colIdx); + break; + }else { + this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey); + } + event.stop(e); + } + break; + case keys.TAB: + this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e); + break; + case keys.LEFT_ARROW: + case keys.RIGHT_ARROW: + if(!this.edit.isEditing()){ + var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys + event.stop(e); + colIdx = this.focus.getHeaderIndex(); + if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){ + this.focus.colSizeAdjust(e, colIdx, (keyCode == keys.LEFT_ARROW ? -1 : 1)*5); + } + else{ + var offset = (keyCode == keys.LEFT_ARROW) ? 1 : -1; + if(this.isLeftToRight()){ offset *= -1; } + this.focus.move(0, offset); + } + } + break; + case keys.UP_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex !== 0){ + event.stop(e); + this.focus.move(-1, 0); + } + break; + case keys.DOWN_ARROW: + if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){ + event.stop(e); + this.focus.move(1, 0); + } + break; + case keys.PAGE_UP: + if(!this.edit.isEditing() && this.focus.rowIndex !== 0){ + event.stop(e); + if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){ + this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0); + }else{ + this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1)); + this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0); + } + } + break; + case keys.PAGE_DOWN: + if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){ + event.stop(e); + if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){ + this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0); + }else{ + this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1)); + this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0); + } + } + break; + default: + break; + } + }, + + onMouseOver: function(e){ + // summary: + // Event fired when mouse is over the grid. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e); + }, + + onMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of the grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e); + }, + + onMouseDown: function(e){ + // summary: + // Event fired when mouse is down inside grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e); + }, + + onMouseOverRow: function(e){ + // summary: + // Event fired when mouse is over any row (data or header). + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(!this.rows.isOver(e.rowIndex)){ + this.rows.setOverRow(e.rowIndex); + e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e); + } + }, + onMouseOutRow: function(e){ + // summary: + // Event fired when mouse moves out of any row (data or header). + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(this.rows.isOver(-1)){ + this.onHeaderMouseOut(e); + }else if(!this.rows.isOver(-2)){ + this.rows.setOverRow(-2); + this.onRowMouseOut(e); + } + }, + + onMouseDownRow: function(e){ + // summary: + // Event fired when mouse is down inside grid row + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + if(e.rowIndex != -1) + this.onRowMouseDown(e); + }, + + // cell events + onCellMouseOver: function(e){ + // summary: + // Event fired when mouse is over a cell. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.add(e.cellNode, this.cellOverClass); + } + }, + + onCellMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.remove(e.cellNode, this.cellOverClass); + } + }, + + onCellMouseDown: function(e){ + // summary: + // Event fired when mouse is down in a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onCellClick: function(e){ + // summary: + // Event fired when a cell is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this._click[0] = this._click[1]; + this._click[1] = e; + if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){ + this.focus.setFocusCell(e.cell, e.rowIndex); + } + // in some cases click[0] is null which causes false doubeClicks. Fixes #100703 + if(this._click.length > 1 && this._click[0] == null){ + this._click.shift(); + } + this.onRowClick(e); + }, + + onCellDblClick: function(e){ + // summary: + // Event fired when a cell is double-clicked. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + var event; + if(this._click.length > 1 && has("ie")){ + event = this._click[1]; + }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){ + event = this._click[0]; + }else{ + event = e; + } + this.focus.setFocusCell(event.cell, event.rowIndex); + this.onRowClick(event); + this.edit.setEditCell(event.cell, event.rowIndex); + this.onRowDblClick(e); + }, + + onCellContextMenu: function(e){ + // summary: + // Event fired when a cell context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onRowContextMenu(e); + }, + + onCellFocus: function(inCell, inRowIndex){ + // summary: + // Event fired when a cell receives focus. + // inCell: Object + // Cell object containing properties of the grid column. + // inRowIndex: Integer + // Index of the grid row + this.edit.cellFocus(inCell, inRowIndex); + }, + + // row events + onRowClick: function(e){ + // summary: + // Event fired when a row is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.edit.rowClick(e); + this.selection.clickSelectEvent(e); + }, + + onRowDblClick: function(e){ + // summary: + // Event fired when a row is double clicked. + // e: Event + // decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a data row. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a data row. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + }, + + onRowMouseDown: function(e){ + // summary: + // Event fired when mouse is down in a row. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onRowContextMenu: function(e){ + // summary: + // Event fired when a row context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + event.stop(e); + }, + + // header events + onHeaderMouseOver: function(e){ + // summary: + // Event fired when mouse moves over the grid header. + // e: Event + // Decorated event object contains reference to grid, cell, and rowIndex + }, + + onHeaderMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of the grid header. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.add(e.cellNode, this.cellOverClass); + } + }, + + onHeaderCellMouseOut: function(e){ + // summary: + // Event fired when mouse moves out of a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(e.cellNode){ + domClass.remove(e.cellNode, this.cellOverClass); + } + }, + + onHeaderCellMouseDown: function(e) { + // summary: + // Event fired when mouse is down in a header cell. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderClick: function(e){ + // summary: + // Event fired when the grid header is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellClick: function(e){ + // summary: + // Event fired when a header cell is clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.setSortIndex(e.cell.index); + this.onHeaderClick(e); + }, + + onHeaderDblClick: function(e){ + // summary: + // Event fired when the grid header is double clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + }, + + onHeaderCellDblClick: function(e){ + // summary: + // Event fired when a header cell is double clicked. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onHeaderDblClick(e); + }, + + onHeaderCellContextMenu: function(e){ + // summary: + // Event fired when a header cell context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this.onHeaderContextMenu(e); + }, + + onHeaderContextMenu: function(e){ + // summary: + // Event fired when the grid header context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + if(!this.headerMenu){ + event.stop(e); + } + }, + + // editing + onStartEdit: function(inCell, inRowIndex){ + // summary: + // Event fired when editing is started for a given grid cell + // inCell: Object + // Cell object containing properties of the grid column. + // inRowIndex: Integer + // Index of the grid row + }, + + onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){ + // summary: + // Event fired when editing is applied for a given grid cell + // inValue: String + // Value from cell editor + // inRowIndex: Integer + // Index of the grid row + // inFieldIndex: Integer + // Index in the grid's data store + }, + + onCancelEdit: function(inRowIndex){ + // summary: + // Event fired when editing is cancelled for a given grid cell + // inRowIndex: Integer + // Index of the grid row + }, + + onApplyEdit: function(inRowIndex){ + // summary: + // Event fired when editing is applied for a given grid row + // inRowIndex: Integer + // Index of the grid row + }, + + onCanSelect: function(inRowIndex){ + // summary: + // Event to determine if a grid row may be selected + // inRowIndex: Integer + // Index of the grid row + // returns: Boolean + // true if the row can be selected + return true; + }, + + onCanDeselect: function(inRowIndex){ + // summary: + // Event to determine if a grid row may be deselected + // inRowIndex: Integer + // Index of the grid row + // returns: Boolean + // true if the row can be deselected + return true; + }, + + onSelected: function(inRowIndex){ + // summary: + // Event fired when a grid row is selected + // inRowIndex: Integer + // Index of the grid row + this.updateRowStyles(inRowIndex); + }, + + onDeselected: function(inRowIndex){ + // summary: + // Event fired when a grid row is deselected + // inRowIndex: Integer + // Index of the grid row + this.updateRowStyles(inRowIndex); + }, + + onSelectionChanged: function(){ + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_FocusManager.js b/js/dojo-1.7.2/dojox/grid/_FocusManager.js new file mode 100644 index 0000000..76d5784 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_FocusManager.js @@ -0,0 +1,642 @@ +//>>built +define("dojox/grid/_FocusManager", [ + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/event", + "dojo/_base/sniff", + "dojo/query", + "./util", + "dojo/_base/html" +], function(array, lang, declare, connect, event, has, query, util, html){ + +// focus management +return declare("dojox.grid._FocusManager", null, { + // summary: + // Controls grid cell focus. Owned by grid and used internally for focusing. + // Note: grid cell actually receives keyboard input only when cell is being edited. + constructor: function(inGrid){ + this.grid = inGrid; + this.cell = null; + this.rowIndex = -1; + this._connects = []; + this._headerConnects = []; + this.headerMenu = this.grid.headerMenu; + this._connects.push(connect.connect(this.grid.domNode, "onfocus", this, "doFocus")); + this._connects.push(connect.connect(this.grid.domNode, "onblur", this, "doBlur")); + this._connects.push(connect.connect(this.grid.domNode, "mousedown", this, "_mouseDown")); + this._connects.push(connect.connect(this.grid.domNode, "mouseup", this, "_mouseUp")); + this._connects.push(connect.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu")); + this._connects.push(connect.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus")); + this._connects.push(connect.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur")); + this._connects.push(connect.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus")); + this._connects.push(connect.connect(this.grid,"postrender", this, "_delayedHeaderFocus")); + }, + destroy: function(){ + array.forEach(this._connects, connect.disconnect); + array.forEach(this._headerConnects, connect.disconnect); + delete this.grid; + delete this.cell; + }, + _colHeadNode: null, + _colHeadFocusIdx: null, + _contextMenuBindNode: null, + tabbingOut: false, + focusClass: "dojoxGridCellFocus", + focusView: null, + initFocusView: function(){ + this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0]; + this._initColumnHeaders(); + }, + isFocusCell: function(inCell, inRowIndex){ + // summary: + // states if the given cell is focused + // inCell: object + // grid cell object + // inRowIndex: int + // grid row index + // returns: + // true of the given grid cell is focused + return (this.cell == inCell) && (this.rowIndex == inRowIndex); + }, + isLastFocusCell: function(){ + if(this.cell){ + return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1); + } + return false; + }, + isFirstFocusCell: function(){ + if(this.cell){ + return (this.rowIndex === 0) && (this.cell.index === 0); + } + return false; + }, + isNoFocusCell: function(){ + return (this.rowIndex < 0) || !this.cell; + }, + isNavHeader: function(){ + // summary: + // states whether currently navigating among column headers. + // returns: + // true if focus is on a column header; false otherwise. + return (!!this._colHeadNode); + }, + getHeaderIndex: function(){ + // summary: + // if one of the column headers currently has focus, return its index. + // returns: + // index of the focused column header, or -1 if none have focus. + if(this._colHeadNode){ + return array.indexOf(this._findHeaderCells(), this._colHeadNode); + }else{ + return -1; + } + }, + _focusifyCellNode: function(inBork){ + var n = this.cell && this.cell.getNode(this.rowIndex); + if(n){ + html.toggleClass(n, this.focusClass, inBork); + if(inBork){ + var sl = this.scrollIntoView(); + try{ + if(!this.grid.edit.isEditing()){ + util.fire(n, "focus"); + if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; } + } + }catch(e){} + } + } + }, + _delayedCellFocus: function(){ + if(this.isNavHeader()||!this.grid.focused){ + return; + } + var n = this.cell && this.cell.getNode(this.rowIndex); + if(n){ + try{ + if(!this.grid.edit.isEditing()){ + html.toggleClass(n, this.focusClass, true); + if(this._colHeadNode){ + this.blurHeader(); + } + util.fire(n, "focus"); + } + } + catch(e){} + } + }, + _delayedHeaderFocus: function(){ + if(this.isNavHeader()){ + this.focusHeader(); + this.grid.domNode.focus(); + } + }, + _initColumnHeaders: function(){ + array.forEach(this._headerConnects, connect.disconnect); + this._headerConnects = []; + var headers = this._findHeaderCells(); + for(var i = 0; i < headers.length; i++){ + this._headerConnects.push(connect.connect(headers[i], "onfocus", this, "doColHeaderFocus")); + this._headerConnects.push(connect.connect(headers[i], "onblur", this, "doColHeaderBlur")); + } + }, + _findHeaderCells: function(){ + // This should be a one liner: + // query("th[tabindex=-1]", this.grid.viewsHeaderNode); + // But there is a bug in query() for IE -- see trac #7037. + var allHeads = query("th", this.grid.viewsHeaderNode); + var headers = []; + for (var i = 0; i < allHeads.length; i++){ + var aHead = allHeads[i]; + var hasTabIdx = html.hasAttr(aHead, "tabIndex"); + var tabindex = html.attr(aHead, "tabIndex"); + if (hasTabIdx && tabindex < 0) { + headers.push(aHead); + } + } + return headers; + }, + _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){ + //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx); + this.grid.domNode.setAttribute("aria-activedescendant",colHeaderNode.id); + if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){ + html.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false); + } + html.toggleClass(colHeaderNode,this.focusClass, true); + this._colHeadNode = colHeaderNode; + this._colHeadFocusIdx = colFocusIdx; + this._scrollHeader(this._colHeadFocusIdx); + }, + scrollIntoView: function(){ + var info = (this.cell ? this._scrollInfo(this.cell) : null); + if(!info || !info.s){ + return null; + } + var rt = this.grid.scroller.findScrollTop(this.rowIndex); + // place cell within horizontal view + if(info.n && info.sr){ + if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){ + info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w; + }else if(info.n.offsetLeft < info.sr.l){ + info.s.scrollLeft = info.n.offsetLeft; + } + } + // place cell within vertical view + if(info.r && info.sr){ + if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){ + this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h); + }else if(rt < info.sr.t){ + this.grid.setScrollTop(rt); + } + } + + return info.s.scrollLeft; + }, + _scrollInfo: function(cell, domNode){ + if(cell){ + var cl = cell, + sbn = cl.view.scrollboxNode, + sbnr = { + w: sbn.clientWidth, + l: sbn.scrollLeft, + t: sbn.scrollTop, + h: sbn.clientHeight + }, + rn = cl.view.getRowNode(this.rowIndex); + return { + c: cl, + s: sbn, + sr: sbnr, + n: (domNode ? domNode : cell.getNode(this.rowIndex)), + r: rn + }; + } + return null; + }, + _scrollHeader: function(currentIdx){ + var info = null; + if(this._colHeadNode){ + var cell = this.grid.getCell(currentIdx); + if(!cell){ return; } + info = this._scrollInfo(cell, cell.getNode(0)); + } + if(info && info.s && info.sr && info.n){ + // scroll horizontally as needed. + var scroll = info.sr.l + info.sr.w; + if(info.n.offsetLeft + info.n.offsetWidth > scroll){ + info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w; + }else if(info.n.offsetLeft < info.sr.l){ + info.s.scrollLeft = info.n.offsetLeft; + }else if(has("ie") <= 7 && cell && cell.view.headerNode){ + // Trac 7158: scroll dojoxGridHeader for IE7 and lower + cell.view.headerNode.scrollLeft = info.s.scrollLeft; + } + } + }, + _isHeaderHidden: function(){ + // summary: + // determine if the grid headers are hidden + // relies on documented technique of setting .dojoxGridHeader { display:none; } + // returns: Boolean + // true if headers are hidden + // false if headers are not hidden + + var curView = this.focusView; + if (!curView){ + // find one so we can determine if headers are hidden + // there is no focusView after adding items to empty grid (test_data_grid_empty.html) + for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) { + if(cView.headerNode ){ + curView=cView; + break; + } + } + } + return (curView && html.getComputedStyle(curView.headerNode).display == "none"); + }, + colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px + var headers = this._findHeaderCells(); + var view = this.focusView; + if (!view) { + for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) { + // find first view with a tableMap in order to work with empty grid + if(cView.header.tableMap.map ){ + view=cView; + break; + } + } + } + var curHeader = headers[colIdx]; + if (!view || (colIdx == headers.length-1 && colIdx === 0)){ + return; // can't adjust single col. grid + } + view.content.baseDecorateEvent(e); + // need to adjust event with header cell info since focus is no longer on header cell + e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode); + e.cellIndex = view.content.getCellNodeIndex(e.cellNode); + e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null); + if (view.header.canResize(e)){ + var deltaObj = { + l: delta + }; + var drag = view.header.colResizeSetup(e,false); + view.header.doResizeColumn(drag, null, deltaObj); + view.update(); + } + }, + styleRow: function(inRow){ + return; + }, + setFocusIndex: function(inRowIndex, inCellIndex){ + // summary: + // focuses the given grid cell + // inRowIndex: int + // grid row index + // inCellIndex: int + // grid cell index + this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex); + }, + setFocusCell: function(inCell, inRowIndex){ + // summary: + // focuses the given grid cell + // inCell: object + // grid cell object + // inRowIndex: int + // grid row index + if(inCell && !this.isFocusCell(inCell, inRowIndex)){ + this.tabbingOut = false; + if (this._colHeadNode){ + this.blurHeader(); + } + this._colHeadNode = this._colHeadFocusIdx = null; + this.focusGridView(); + this._focusifyCellNode(false); + this.cell = inCell; + this.rowIndex = inRowIndex; + this._focusifyCellNode(true); + } + // even if this cell isFocusCell, the document focus may need to be rejiggered + // call opera on delay to prevent keypress from altering focus + if(has("opera")){ + setTimeout(lang.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1); + }else{ + this.grid.onCellFocus(this.cell, this.rowIndex); + } + }, + next: function(){ + // summary: + // focus next grid cell + if(this.cell){ + var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1; + if(col > cc){ + col = 0; + row++; + } + if(row > rc){ + col = cc; + row = rc; + } + if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells + var nextCell = this.grid.getCell(col); + if (!this.isLastFocusCell() && (!nextCell.editable || + this.grid.canEdit && !this.grid.canEdit(nextCell, row))){ + this.cell=nextCell; + this.rowIndex=row; + this.next(); + return; + } + } + this.setFocusIndex(row, col); + } + }, + previous: function(){ + // summary: + // focus previous grid cell + if(this.cell){ + var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1; + if(col < 0){ + col = this.grid.layout.cellCount-1; + row--; + } + if(row < 0){ + row = 0; + col = 0; + } + if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells + var prevCell = this.grid.getCell(col); + if (!this.isFirstFocusCell() && !prevCell.editable){ + this.cell=prevCell; + this.rowIndex=row; + this.previous(); + return; + } + } + this.setFocusIndex(row, col); + } + }, + move: function(inRowDelta, inColDelta) { + // summary: + // focus grid cell or simulate focus to column header based on position relative to current focus + // inRowDelta: int + // vertical distance from current focus + // inColDelta: int + // horizontal distance from current focus + + var colDir = inColDelta < 0 ? -1 : 1; + // Handle column headers. + if(this.isNavHeader()){ + var headers = this._findHeaderCells(); + var savedIdx = currentIdx = array.indexOf(headers, this._colHeadNode); + currentIdx += inColDelta; + while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){ + // skip over hidden column headers + currentIdx += colDir; + } + if((currentIdx >= 0) && (currentIdx < headers.length)){ + this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx); + } + }else{ + if(this.cell){ + // Handle grid proper. + var sc = this.grid.scroller, + r = this.rowIndex, + rc = this.grid.rowCount-1, + row = Math.min(rc, Math.max(0, r+inRowDelta)); + if(inRowDelta){ + if(inRowDelta>0){ + if(row > sc.getLastPageRow(sc.page)){ + //need to load additional data, let scroller do that + this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r)); + } + }else if(inRowDelta<0){ + if(row <= sc.getPageRow(sc.page)){ + //need to load additional data, let scroller do that + this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row)); + } + } + } + var cc = this.grid.layout.cellCount-1, + i = this.cell.index, + col = Math.min(cc, Math.max(0, i+inColDelta)); + var cell = this.grid.getCell(col); + while(col>=0 && col < cc && cell && cell.hidden === true){ + // skip hidden cells + col += colDir; + cell = this.grid.getCell(col); + } + if (!cell || cell.hidden === true){ + // don't change col if would move to hidden + col = i; + } + //skip hidden row|cell + var n = cell.getNode(row); + if(!n && inRowDelta){ + if((row + inRowDelta) >= 0 && (row + inRowDelta) <= rc){ + this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta); + } + return; + }else if((!n || html.style(n, "display") === "none") && inColDelta){ + if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){ + this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta); + } + return; + } + this.setFocusIndex(row, col); + if(inRowDelta){ + this.grid.updateRow(r); + } + } + } + }, + previousKey: function(e){ + if(this.grid.edit.isEditing()){ + event.stop(e); + this.previous(); + }else if(!this.isNavHeader() && !this._isHeaderHidden()) { + this.grid.domNode.focus(); // will call doFocus and set focus into header. + event.stop(e); + }else{ + this.tabOut(this.grid.domNode); + if (this._colHeadFocusIdx != null) { // clear grid header focus + html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false); + this._colHeadFocusIdx = null; + } + this._focusifyCellNode(false); + } + }, + nextKey: function(e) { + var isEmpty = (this.grid.rowCount === 0); + if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){ + this.focusHeader(); + event.stop(e); + }else if(this.isNavHeader()){ + // if tabbing from col header, then go to grid proper. + this.blurHeader(); + if(!this.findAndFocusGridCell()){ + this.tabOut(this.grid.lastFocusNode); + } + this._colHeadNode = this._colHeadFocusIdx= null; + }else if(this.grid.edit.isEditing()){ + event.stop(e); + this.next(); + }else{ + this.tabOut(this.grid.lastFocusNode); + } + }, + tabOut: function(inFocusNode){ + this.tabbingOut = true; + inFocusNode.focus(); + }, + focusGridView: function(){ + util.fire(this.focusView, "focus"); + }, + focusGrid: function(inSkipFocusCell){ + this.focusGridView(); + this._focusifyCellNode(true); + }, + findAndFocusGridCell: function(){ + // summary: + // find the first focusable grid cell + // returns: Boolean + // true if focus was set to a cell + // false if no cell found to set focus onto + + var didFocus = true; + var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0 + if (this.isNoFocusCell() && !isEmpty){ + var cellIdx = 0; + var cell = this.grid.getCell(cellIdx); + if (cell.hidden) { + // if first cell isn't visible, use _colHeadFocusIdx + // could also use a while loop to find first visible cell - not sure that is worth it + cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0; + } + this.setFocusIndex(0, cellIdx); + } + else if (this.cell && !isEmpty){ + if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){ + // if rowNode for current index is undefined (likely as a result of a sort and because of #7304) + // scroll to that row + this.grid.scrollToRow(this.rowIndex); + } + this.focusGrid(); + }else { + didFocus = false; + } + this._colHeadNode = this._colHeadFocusIdx= null; + return didFocus; + }, + focusHeader: function(){ + var headerNodes = this._findHeaderCells(); + var saveColHeadFocusIdx = this._colHeadFocusIdx; + if (this._isHeaderHidden()){ + // grid header is hidden, focus a cell + this.findAndFocusGridCell(); + } + else if (!this._colHeadFocusIdx) { + if (this.isNoFocusCell()) { + this._colHeadFocusIdx = 0; + } + else { + this._colHeadFocusIdx = this.cell.index; + } + } + this._colHeadNode = headerNodes[this._colHeadFocusIdx]; + while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length && + this._colHeadNode.style.display == "none"){ + // skip over hidden column headers + this._colHeadFocusIdx++; + this._colHeadNode = headerNodes[this._colHeadFocusIdx]; + } + if(this._colHeadNode && this._colHeadNode.style.display != "none"){ + // Column header cells know longer receive actual focus. So, for keyboard invocation of + // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode. + // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset + // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483 + if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){ + this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode); + this.headerMenu.bindDomNode(this.grid.domNode); + this._contextMenuBindNode = this.grid.domNode; + } + this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx); + this._scrollHeader(this._colHeadFocusIdx); + this._focusifyCellNode(false); + }else { + // all col head nodes are hidden - focus the grid + this.findAndFocusGridCell(); + } + }, + blurHeader: function(){ + html.removeClass(this._colHeadNode, this.focusClass); + html.removeAttr(this.grid.domNode,"aria-activedescendant"); + // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader) + if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) { + var viewsHeader = this.grid.viewsHeaderNode; + this.headerMenu.unBindDomNode(this.grid.domNode); + this.headerMenu.bindDomNode(viewsHeader); + this._contextMenuBindNode = viewsHeader; + } + }, + doFocus: function(e){ + // trap focus only for grid dom node + if(e && e.target != e.currentTarget){ + event.stop(e); + return; + } + // don't change focus if clicking on scroller bar + if(this._clickFocus){ + return; + } + // do not focus for scrolling if grid is about to blur + if(!this.tabbingOut){ + this.focusHeader(); + } + this.tabbingOut = false; + event.stop(e); + }, + doBlur: function(e){ + event.stop(e); // FF2 + }, + doContextMenu: function(e){ + //stop contextMenu event if no header Menu to prevent default/browser contextMenu + if (!this.headerMenu){ + event.stop(e); + } + }, + doLastNodeFocus: function(e){ + if (this.tabbingOut){ + this._focusifyCellNode(false); + }else if(this.grid.rowCount >0){ + if (this.isNoFocusCell()){ + this.setFocusIndex(0,0); + } + this._focusifyCellNode(true); + }else { + this.focusHeader(); + } + this.tabbingOut = false; + event.stop(e); // FF2 + }, + doLastNodeBlur: function(e){ + event.stop(e); // FF2 + }, + doColHeaderFocus: function(e){ + this._setActiveColHeader(e.target,html.attr(e.target, "idx"),this._colHeadFocusIdx); + this._scrollHeader(this.getHeaderIndex()); + event.stop(e); + }, + doColHeaderBlur: function(e){ + html.toggleClass(e.target, this.focusClass, false); + }, + _mouseDown: function(e){ + // a flag indicating grid is being focused by clicking + this._clickFocus = dojo.some(this.grid.views.views, function(v){ + return v.scrollboxNode === e.target; + }); + }, + _mouseUp: function(e){ + this._clickFocus = false; + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_Grid.js b/js/dojo-1.7.2/dojox/grid/_Grid.js new file mode 100644 index 0000000..8c677b5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_Grid.js @@ -0,0 +1,1402 @@ +//>>built +require({cache:{ +'url:dojox/grid/resources/_Grid.html':"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n"}}); +define("dojox/grid/_Grid", [ + "dojo/_base/kernel", + "../main", + "dojo/_base/declare", + "./_Events", + "./_Scroller", + "./_Layout", + "./_View", + "./_ViewManager", + "./_RowManager", + "./_FocusManager", + "./_EditManager", + "./Selection", + "./_RowSelector", + "./util", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/CheckedMenuItem", + "dojo/text!./resources/_Grid.html", + "dojo/string", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/sniff", + "dojox/html/metrics", + "dojo/_base/html", + "dojo/query", + "dojo/dnd/common", + "dojo/i18n!dijit/nls/loading" +], function(dojo, dojox, declare, _Events, _Scroller, _Layout, _View, _ViewManager, + _RowManager, _FocusManager, _EditManager, Selection, _RowSelector, util, _Widget, + _TemplatedMixin, CheckedMenuItem, template, string, array, lang, has, metrics, html, query){ + + // NOTE: this is for backwards compatibility with Dojo 1.3 + if(!dojo.isCopyKey){ + dojo.isCopyKey = dojo.dnd.getCopyKeyState; + } + /*===== + dojox.grid.__CellDef = function(){ + // name: String? + // The text to use in the header of the grid for this cell. + // get: Function? + // function(rowIndex){} rowIndex is of type Integer. This + // function will be called when a cell requests data. Returns the + // unformatted data for the cell. + // value: String? + // If "get" is not specified, this is used as the data for the cell. + // defaultValue: String? + // If "get" and "value" aren't specified or if "get" returns an undefined + // value, this is used as the data for the cell. "formatter" is not run + // on this if "get" returns an undefined value. + // formatter: Function? + // function(data, rowIndex){} data is of type anything, rowIndex + // is of type Integer. This function will be called after the cell + // has its data but before it passes it back to the grid to render. + // Returns the formatted version of the cell's data. + // type: dojox.grid.cells._Base|Function? + // TODO + // editable: Boolean? + // Whether this cell should be editable or not. + // hidden: Boolean? + // If true, the cell will not be displayed. + // noresize: Boolean? + // If true, the cell will not be able to be resized. + // width: Integer|String? + // A CSS size. If it's an Integer, the width will be in em's. + // colSpan: Integer? + // How many columns to span this cell. Will not work in the first + // sub-row of cells. + // rowSpan: Integer? + // How many sub-rows to span this cell. + // styles: String? + // A string of styles to apply to both the header cell and main + // grid cells. Must end in a ';'. + // headerStyles: String? + // A string of styles to apply to just the header cell. Must end + // in a ';' + // cellStyles: String? + // A string of styles to apply to just the main grid cells. Must + // end in a ';' + // classes: String? + // A space separated list of classes to apply to both the header + // cell and the main grid cells. + // headerClasses: String? + // A space separated list of classes to apply to just the header + // cell. + // cellClasses: String? + // A space separated list of classes to apply to just the main + // grid cells. + // attrs: String? + // A space separated string of attribute='value' pairs to add to + // the header cell element and main grid cell elements. + this.name = name; + this.value = value; + this.get = get; + this.formatter = formatter; + this.type = type; + this.editable = editable; + this.hidden = hidden; + this.width = width; + this.colSpan = colSpan; + this.rowSpan = rowSpan; + this.styles = styles; + this.headerStyles = headerStyles; + this.cellStyles = cellStyles; + this.classes = classes; + this.headerClasses = headerClasses; + this.cellClasses = cellClasses; + this.attrs = attrs; + } + =====*/ + + /*===== + dojox.grid.__ViewDef = function(){ + // noscroll: Boolean? + // If true, no scrollbars will be rendered without scrollbars. + // width: Integer|String? + // A CSS size. If it's an Integer, the width will be in em's. If + // "noscroll" is true, this value is ignored. + // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]? + // The structure of the cells within this grid. + // type: String? + // A string containing the constructor of a subclass of + // dojox.grid._View. If this is not specified, dojox.grid._View + // is used. + // defaultCell: dojox.grid.__CellDef? + // A cell definition with default values for all cells in this view. If + // a property is defined in a cell definition in the "cells" array and + // this property, the cell definition's property will override this + // property's property. + // onBeforeRow: Function? + // function(rowIndex, cells){} rowIndex is of type Integer, cells + // is of type Array[dojox.grid.__CellDef[]]. This function is called + // before each row of data is rendered. Before the header is + // rendered, rowIndex will be -1. "cells" is a reference to the + // internal structure of this view's cells so any changes you make to + // it will persist between calls. + // onAfterRow: Function? + // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells + // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode. + // This function is called after each row of data is rendered. After the + // header is rendered, rowIndex will be -1. "cells" is a reference to the + // internal structure of this view's cells so any changes you make to + // it will persist between calls. + this.noscroll = noscroll; + this.width = width; + this.cells = cells; + this.type = type; + this.defaultCell = defaultCell; + this.onBeforeRow = onBeforeRow; + this.onAfterRow = onAfterRow; + } + =====*/ + + var _Grid = declare('dojox.grid._Grid', + [ _Widget, _TemplatedMixin, _Events ], + { + // summary: + // A grid widget with virtual scrolling, cell editing, complex rows, + // sorting, fixed columns, sizeable columns, etc. + // + // description: + // _Grid provides the full set of grid features without any + // direct connection to a data store. + // + // The grid exposes a get function for the grid, or optionally + // individual columns, to populate cell contents. + // + // The grid is rendered based on its structure, an object describing + // column and cell layout. + // + // example: + // A quick sample: + // + // define a get function + // | function get(inRowIndex){ // called in cell context + // | return [this.index, inRowIndex].join(', '); + // | } + // + // define the grid structure: + // | var structure = [ // array of view objects + // | { cells: [// array of rows, a row is an array of cells + // | [ + // | { name: "Alpha", width: 6 }, + // | { name: "Beta" }, + // | { name: "Gamma", get: get }] + // | ]} + // | ]; + // + // | <div id="grid" + // | rowCount="100" get="get" + // | structure="structure" + // | dojoType="dojox.grid._Grid"></div> + + templateString: template, + + // classTag: String + // CSS class applied to the grid's domNode + classTag: 'dojoxGrid', + + // settings + // rowCount: Integer + // Number of rows to display. + rowCount: 5, + + // keepRows: Integer + // Number of rows to keep in the rendering cache. + keepRows: 75, + + // rowsPerPage: Integer + // Number of rows to render at a time. + rowsPerPage: 25, + + // autoWidth: Boolean + // If autoWidth is true, grid width is automatically set to fit the data. + autoWidth: false, + + // initialWidth: String + // A css string to use to set our initial width (only used if autoWidth + // is true). The first rendering of the grid will be this width, any + // resizing of columns, etc will result in the grid switching to + // autoWidth mode. Note, this width will override any styling in a + // stylesheet or directly on the node. + initialWidth: "", + + // autoHeight: Boolean|Integer + // If autoHeight is true, grid height is automatically set to fit the data. + // If it is an integer, the height will be automatically set to fit the data + // if there are fewer than that many rows - and the height will be set to show + // that many rows if there are more + autoHeight: '', + + // rowHeight: Integer + // If rowHeight is set to a positive number, it will define the height of the rows + // in pixels. This can provide a significant performance advantage, since it + // eliminates the need to measure row sizes during rendering, which is one + // the primary bottlenecks in the DataGrid's performance. + rowHeight: 0, + + // autoRender: Boolean + // If autoRender is true, grid will render itself after initialization. + autoRender: true, + + // defaultHeight: String + // default height of the grid, measured in any valid css unit. + defaultHeight: '15em', + + // height: String + // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden) + // if the height: css attribute exists on the source node. + height: '', + + // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] + // View layout defintion. + structure: null, + + // elasticView: Integer + // Override defaults and make the indexed grid view elastic, thus filling available horizontal space. + elasticView: -1, + + // singleClickEdit: boolean + // Single-click starts editing. Default is double-click + singleClickEdit: false, + + // selectionMode: String + // Set the selection mode of grid's Selection. Value must be 'single', 'multiple', + // or 'extended'. Default is 'extended'. + selectionMode: 'extended', + + // rowSelector: Boolean|String + // If set to true, will add a row selector view to this grid. If set to a CSS width, will add + // a row selector of that width to this grid. + rowSelector: '', + + // columnReordering: Boolean + // If set to true, will add drag and drop reordering to views with one row of columns. + columnReordering: false, + + // headerMenu: dijit.Menu + // If set to a dijit.Menu, will use this as a context menu for the grid headers. + headerMenu: null, + + // placeholderLabel: String + // Label of placeholders to search for in the header menu to replace with column toggling + // menu items. + placeholderLabel: "GridColumns", + + // selectable: Boolean + // Set to true if you want to be able to select the text within the grid. + selectable: false, + + // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row + _click: null, + + // loadingMessage: String + // Message that shows while the grid is loading + loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>", + + // errorMessage: String + // Message that shows when the grid encounters an error loading + errorMessage: "<span class='dojoxGridError'>${errorState}</span>", + + // noDataMessage: String + // Message that shows if the grid has no data - wrap it in a + // span with class 'dojoxGridNoData' if you want it to be + // styled similar to the loading and error messages + noDataMessage: "", + + // escapeHTMLInData: Boolean + // This will escape HTML brackets from the data to prevent HTML from + // user-inputted data being rendered with may contain JavaScript and result in + // XSS attacks. This is true by default, and it is recommended that it remain + // true. Setting this to false will allow data to be displayed in the grid without + // filtering, and should be only used if it is known that the data won't contain + // malicious scripts. If HTML is needed in grid cells, it is recommended that + // you use the formatter function to generate the HTML (the output of + // formatter functions is not filtered, even with escapeHTMLInData set to true). + escapeHTMLInData: true, + + // formatterScope: Object + // An object to execute format functions within. If not set, the + // format functions will execute within the scope of the cell that + // has a format function. + formatterScope: null, + + // editable: boolean + // indicates if the grid contains editable cells, default is false + // set to true if editable cell encountered during rendering + editable: false, + + // private + sortInfo: 0, + themeable: true, + _placeholders: null, + + // _layoutClass: Object + // The class to use for our layout - can be overridden by grid subclasses + _layoutClass: _Layout, + + // initialization + buildRendering: function(){ + this.inherited(arguments); + if(!this.domNode.getAttribute('tabIndex')){ + this.domNode.tabIndex = "0"; + } + this.createScroller(); + this.createLayout(); + this.createViews(); + this.createManagers(); + + this.createSelection(); + + this.connect(this.selection, "onSelected", "onSelected"); + this.connect(this.selection, "onDeselected", "onDeselected"); + this.connect(this.selection, "onChanged", "onSelectionChanged"); + + metrics.initOnFontResize(); + this.connect(metrics, "onFontResize", "textSizeChanged"); + util.funnelEvents(this.domNode, this, 'doKeyEvent', util.keyEvents); + if (this.selectionMode != "none") { + this.domNode.setAttribute("aria-multiselectable", this.selectionMode == "single" ? "false" : "true"); + } + + html.addClass(this.domNode, this.classTag); + if(!this.isLeftToRight()){ + html.addClass(this.domNode, this.classTag+"Rtl"); + } + }, + + postMixInProperties: function(){ + this.inherited(arguments); + var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang); + this.loadingMessage = string.substitute(this.loadingMessage, messages); + this.errorMessage = string.substitute(this.errorMessage, messages); + if(this.srcNodeRef && this.srcNodeRef.style.height){ + this.height = this.srcNodeRef.style.height; + } + // Call this to update our autoheight to start out + this._setAutoHeightAttr(this.autoHeight, true); + this.lastScrollTop = this.scrollTop = 0; + }, + + postCreate: function(){ + this._placeholders = []; + this._setHeaderMenuAttr(this.headerMenu); + this._setStructureAttr(this.structure); + this._click = []; + this.inherited(arguments); + if(this.domNode && this.autoWidth && this.initialWidth){ + this.domNode.style.width = this.initialWidth; + } + if (this.domNode && !this.editable){ + // default value for aria-readonly is false, set to true if grid is not editable + html.attr(this.domNode,"aria-readonly", "true"); + } + }, + + destroy: function(){ + this.domNode.onReveal = null; + this.domNode.onSizeChange = null; + + // Fixes IE domNode leak + delete this._click; + + if(this.scroller){ + this.scroller.destroy(); + delete this.scroller; + } + this.edit.destroy(); + delete this.edit; + this.views.destroyViews(); + if(this.focus){ + this.focus.destroy(); + delete this.focus; + } + if(this.headerMenu&&this._placeholders.length){ + array.forEach(this._placeholders, function(p){ p.unReplace(true); }); + this.headerMenu.unBindDomNode(this.viewsHeaderNode); + } + this.inherited(arguments); + }, + + _setAutoHeightAttr: function(ah, skipRender){ + // Calculate our autoheight - turn it into a boolean or an integer + if(typeof ah == "string"){ + if(!ah || ah == "false"){ + ah = false; + }else if (ah == "true"){ + ah = true; + }else{ + ah = window.parseInt(ah, 10); + } + } + if(typeof ah == "number"){ + if(isNaN(ah)){ + ah = false; + } + // Autoheight must be at least 1, if it's a number. If it's + // less than 0, we'll take that to mean "all" rows (same as + // autoHeight=true - if it is equal to zero, we'll take that + // to mean autoHeight=false + if(ah < 0){ + ah = true; + }else if (ah === 0){ + ah = false; + } + } + this.autoHeight = ah; + if(typeof ah == "boolean"){ + this._autoHeight = ah; + }else if(typeof ah == "number"){ + this._autoHeight = (ah >= this.get('rowCount')); + }else{ + this._autoHeight = false; + } + if(this._started && !skipRender){ + this.render(); + } + }, + + _getRowCountAttr: function(){ + return this.updating && this.invalidated && this.invalidated.rowCount != undefined ? + this.invalidated.rowCount : this.rowCount; + }, + + textSizeChanged: function(){ + this.render(); + }, + + sizeChange: function(){ + this.update(); + }, + + createManagers: function(){ + // summary: + // create grid managers for various tasks including rows, focus, selection, editing + + // row manager + this.rows = new _RowManager(this); + // focus manager + this.focus = new _FocusManager(this); + // edit manager + this.edit = new _EditManager(this); + }, + + createSelection: function(){ + // summary: Creates a new Grid selection manager. + + // selection manager + this.selection = new Selection(this); + }, + + createScroller: function(){ + // summary: Creates a new virtual scroller + this.scroller = new _Scroller(); + this.scroller.grid = this; + this.scroller.renderRow = lang.hitch(this, "renderRow"); + this.scroller.removeRow = lang.hitch(this, "rowRemoved"); + }, + + createLayout: function(){ + // summary: Creates a new Grid layout + this.layout = new this._layoutClass(this); + this.connect(this.layout, "moveColumn", "onMoveColumn"); + }, + + onMoveColumn: function(){ + this.render(); + }, + + onResizeColumn: function(/*int*/ cellIdx){ + // Called when a column is resized. + }, + + // views + createViews: function(){ + this.views = new _ViewManager(this); + this.views.createView = lang.hitch(this, "createView"); + }, + + createView: function(inClass, idx){ + var c = lang.getObject(inClass); + var view = new c({ grid: this, index: idx }); + this.viewsNode.appendChild(view.domNode); + this.viewsHeaderNode.appendChild(view.headerNode); + this.views.addView(view); + html.attr(this.domNode, "align", this.isLeftToRight() ? 'left' : 'right'); + return view; + }, + + buildViews: function(){ + for(var i=0, vs; (vs=this.layout.structure[i]); i++){ + this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs); + } + this.scroller.setContentNodes(this.views.getContentNodes()); + }, + + _setStructureAttr: function(structure){ + var s = structure; + if(s && lang.isString(s)){ + dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0"); + s=lang.getObject(s); + } + this.structure = s; + if(!s){ + if(this.layout.structure){ + s = this.layout.structure; + }else{ + return; + } + } + this.views.destroyViews(); + this.focus.focusView = null; + if(s !== this.layout.structure){ + this.layout.setStructure(s); + } + this._structureChanged(); + }, + + setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){ + // summary: + // Install a new structure and rebuild the grid. + dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0"); + this._setStructureAttr(inStructure); + }, + + getColumnTogglingItems: function(){ + // Summary: returns an array of dijit.CheckedMenuItem widgets that can be + // added to a menu for toggling columns on and off. + var items, checkedItems = []; + items = array.map(this.layout.cells, function(cell){ + if(!cell.menuItems){ cell.menuItems = []; } + + var self = this; + var item = new CheckedMenuItem({ + label: cell.name, + checked: !cell.hidden, + _gridCell: cell, + onChange: function(checked){ + if(self.layout.setColumnVisibility(this._gridCell.index, checked)){ + var items = this._gridCell.menuItems; + if(items.length > 1){ + array.forEach(items, function(item){ + if(item !== this){ + item.setAttribute("checked", checked); + } + }, this); + } + checked = array.filter(self.layout.cells, function(c){ + if(c.menuItems.length > 1){ + array.forEach(c.menuItems, "item.set('disabled', false);"); + }else{ + c.menuItems[0].set('disabled', false); + } + return !c.hidden; + }); + if(checked.length == 1){ + array.forEach(checked[0].menuItems, "item.set('disabled', true);"); + } + } + }, + destroy: function(){ + var index = array.indexOf(this._gridCell.menuItems, this); + this._gridCell.menuItems.splice(index, 1); + delete this._gridCell; + CheckedMenuItem.prototype.destroy.apply(this, arguments); + } + }); + cell.menuItems.push(item); + if(!cell.hidden) { + checkedItems.push(item); + } + return item; + }, this); // dijit.CheckedMenuItem[] + if(checkedItems.length == 1) { + checkedItems[0].set('disabled', true); + } + return items; + }, + + _setHeaderMenuAttr: function(menu){ + if(this._placeholders && this._placeholders.length){ + array.forEach(this._placeholders, function(p){ + p.unReplace(true); + }); + this._placeholders = []; + } + if(this.headerMenu){ + this.headerMenu.unBindDomNode(this.viewsHeaderNode); + } + this.headerMenu = menu; + if(!menu){ return; } + + this.headerMenu.bindDomNode(this.viewsHeaderNode); + if(this.headerMenu.getPlaceholders){ + this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel); + } + }, + + setHeaderMenu: function(/* dijit.Menu */ menu){ + dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0"); + this._setHeaderMenuAttr(menu); + }, + + setupHeaderMenu: function(){ + if(this._placeholders && this._placeholders.length){ + array.forEach(this._placeholders, function(p){ + if(p._replaced){ + p.unReplace(true); + } + p.replace(this.getColumnTogglingItems()); + }, this); + } + }, + + _fetch: function(start){ + this.setScrollTop(0); + }, + + getItem: function(inRowIndex){ + return null; + }, + + showMessage: function(message){ + if(message){ + this.messagesNode.innerHTML = message; + this.messagesNode.style.display = ""; + }else{ + this.messagesNode.innerHTML = ""; + this.messagesNode.style.display = "none"; + } + }, + + _structureChanged: function() { + this.buildViews(); + if(this.autoRender && this._started){ + this.render(); + } + }, + + hasLayout: function() { + return this.layout.cells.length; + }, + + // sizing + resize: function(changeSize, resultSize){ + // summary: + // Update the grid's rendering dimensions and resize it + + // Calling sizeChange calls update() which calls _resize...so let's + // save our input values, if any, and use them there when it gets + // called. This saves us an extra call to _resize(), which can + // get kind of heavy. + + // fixes #11101, should ignore resize when in autoheight mode(IE) to avoid a deadlock + // e.g when an autoheight editable grid put in dijit.form.Form or other similar containers, + // grid switch to editing mode --> grid height change --> From height change + // ---> Form call grid.resize() ---> grid height change --> deaklock + if(dojo.isIE && !changeSize && !resultSize && this._autoHeight){ + return; + } + this._pendingChangeSize = changeSize; + this._pendingResultSize = resultSize; + this.sizeChange(); + }, + + _getPadBorder: function() { + this._padBorder = this._padBorder || html._getPadBorderExtents(this.domNode); + return this._padBorder; + }, + + _getHeaderHeight: function(){ + var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader(); + vns.height = t + 'px'; + // header heights are reset during measuring so must be normalized after measuring. + this.views.normalizeHeaderNodeHeight(); + return t; + }, + + _resize: function(changeSize, resultSize){ + // Restore our pending values, if any + changeSize = changeSize || this._pendingChangeSize; + resultSize = resultSize || this._pendingResultSize; + delete this._pendingChangeSize; + delete this._pendingResultSize; + // if we have set up everything except the DOM, we cannot resize + if(!this.domNode){ return; } + var pn = this.domNode.parentNode; + if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){ + return; + } + // useful measurement + var padBorder = this._getPadBorder(); + var hh = undefined; + var h; + // grid height + if(this._autoHeight){ + this.domNode.style.height = 'auto'; + }else if(typeof this.autoHeight == "number"){ + h = hh = this._getHeaderHeight(); + h += (this.scroller.averageRowHeight * this.autoHeight); + this.domNode.style.height = h + "px"; + }else if(this.domNode.clientHeight <= padBorder.h){ + if(pn == document.body){ + this.domNode.style.height = this.defaultHeight; + }else if(this.height){ + this.domNode.style.height = this.height; + }else{ + this.fitTo = "parent"; + } + } + // if we are given dimensions, size the grid's domNode to those dimensions + if(resultSize){ + changeSize = resultSize; + } + if(!this._autoHeight && changeSize){ + html.marginBox(this.domNode, changeSize); + this.height = this.domNode.style.height; + delete this.fitTo; + }else if(this.fitTo == "parent"){ + h = this._parentContentBoxHeight = this._parentContentBoxHeight || html._getContentBox(pn).h; + this.domNode.style.height = Math.max(0, h) + "px"; + } + + var hasFlex = array.some(this.views.views, function(v){ return v.flexCells; }); + + if(!this._autoHeight && (h || html._getContentBox(this.domNode).h) === 0){ + // We need to hide the header, since the Grid is essentially hidden. + this.viewsHeaderNode.style.display = "none"; + }else{ + // Otherwise, show the header and give it an appropriate height. + this.viewsHeaderNode.style.display = "block"; + if(!hasFlex && hh === undefined){ + hh = this._getHeaderHeight(); + } + } + if(hasFlex){ + hh = undefined; + } + + // NOTE: it is essential that width be applied before height + // Header height can only be calculated properly after view widths have been set. + // This is because flex column width is naturally 0 in Firefox. + // Therefore prior to width sizing flex columns with spaces are maximally wrapped + // and calculated to be too tall. + this.adaptWidth(); + this.adaptHeight(hh); + + this.postresize(); + }, + + adaptWidth: function() { + // private: sets width and position for views and update grid width if necessary + var doAutoWidth = (!this.initialWidth && this.autoWidth); + var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w), + vw = this.views.arrange(1, w); + this.views.onEach("adaptWidth"); + if(doAutoWidth){ + this.domNode.style.width = vw + "px"; + } + }, + + adaptHeight: function(inHeaderHeight){ + // private: measures and normalizes header height, then sets view heights, and then updates scroller + // content extent + var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight; + var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0); + this.views.onEach('setSize', [0, h]); + this.views.onEach('adaptHeight'); + if(!this._autoHeight){ + var numScroll = 0, numNoScroll = 0; + var noScrolls = array.filter(this.views.views, function(v){ + var has = v.hasHScrollbar(); + if(has){ numScroll++; }else{ numNoScroll++; } + return (!has); + }); + if(numScroll > 0 && numNoScroll > 0){ + array.forEach(noScrolls, function(v){ + v.adaptHeight(true); + }); + } + } + if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){ + this.scroller.windowHeight = h; + }else{ + this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0); + } + }, + + // startup + startup: function(){ + if(this._started){return;} + this.inherited(arguments); + if(this.autoRender){ + this.render(); + } + }, + + // render + render: function(){ + // summary: + // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and + // scrolling states, see Update. + + if(!this.domNode){return;} + if(!this._started){return;} + + if(!this.hasLayout()) { + this.scroller.init(0, this.keepRows, this.rowsPerPage); + return; + } + // + this.update = this.defaultUpdate; + this._render(); + }, + + _render: function(){ + this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage); + this.prerender(); + this.setScrollTop(0); + this.postrender(); + }, + + prerender: function(){ + // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered. + this.keepRows = this._autoHeight ? 0 : this.keepRows; + this.scroller.setKeepInfo(this.keepRows); + this.views.render(); + this._resize(); + }, + + postrender: function(){ + this.postresize(); + this.focus.initFocusView(); + // make rows unselectable + html.setSelectable(this.domNode, this.selectable); + }, + + postresize: function(){ + // views are position absolute, so they do not inflate the parent + if(this._autoHeight){ + var size = Math.max(this.views.measureContent()) + 'px'; + + this.viewsNode.style.height = size; + } + }, + + renderRow: function(inRowIndex, inNodes){ + // summary: private, used internally to render rows + this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize); + }, + + rowRemoved: function(inRowIndex){ + // summary: private, used internally to remove rows + this.views.rowRemoved(inRowIndex); + }, + + invalidated: null, + + updating: false, + + beginUpdate: function(){ + // summary: + // Use to make multiple changes to rows while queueing row updating. + // NOTE: not currently supporting nested begin/endUpdate calls + this.invalidated = []; + this.updating = true; + }, + + endUpdate: function(){ + // summary: + // Use after calling beginUpdate to render any changes made to rows. + this.updating = false; + var i = this.invalidated, r; + if(i.all){ + this.update(); + }else if(i.rowCount != undefined){ + this.updateRowCount(i.rowCount); + }else{ + for(r in i){ + this.updateRow(Number(r)); + } + } + this.invalidated = []; + }, + + // update + defaultUpdate: function(){ + // note: initial update calls render and subsequently this function. + if(!this.domNode){return;} + if(this.updating){ + this.invalidated.all = true; + return; + } + //this.edit.saveState(inRowIndex); + this.lastScrollTop = this.scrollTop; + this.prerender(); + this.scroller.invalidateNodes(); + this.setScrollTop(this.lastScrollTop); + this.postrender(); + //this.edit.restoreState(inRowIndex); + }, + + update: function(){ + // summary: + // Update the grid, retaining edit and scrolling states. + this.render(); + }, + + updateRow: function(inRowIndex){ + // summary: + // Render a single row. + // inRowIndex: Integer + // Index of the row to render + inRowIndex = Number(inRowIndex); + if(this.updating){ + this.invalidated[inRowIndex]=true; + }else{ + this.views.updateRow(inRowIndex); + this.scroller.rowHeightChanged(inRowIndex); + } + }, + + updateRows: function(startIndex, howMany){ + // summary: + // Render consecutive rows at once. + // startIndex: Integer + // Index of the starting row to render + // howMany: Integer + // How many rows to update. + startIndex = Number(startIndex); + howMany = Number(howMany); + var i; + if(this.updating){ + for(i=0; i<howMany; i++){ + this.invalidated[i+startIndex]=true; + } + }else{ + for(i=0; i<howMany; i++){ + this.views.updateRow(i+startIndex, this._skipRowRenormalize); + } + this.scroller.rowHeightChanged(startIndex); + } + }, + + updateRowCount: function(inRowCount){ + //summary: + // Change the number of rows. + // inRowCount: int + // Number of rows in the grid. + if(this.updating){ + this.invalidated.rowCount = inRowCount; + }else{ + this.rowCount = inRowCount; + this._setAutoHeightAttr(this.autoHeight, true); + if(this.layout.cells.length){ + this.scroller.updateRowCount(inRowCount); + } + this._resize(); + if(this.layout.cells.length){ + this.setScrollTop(this.scrollTop); + } + } + }, + + updateRowStyles: function(inRowIndex){ + // summary: + // Update the styles for a row after it's state has changed. + this.views.updateRowStyles(inRowIndex); + }, + getRowNode: function(inRowIndex){ + // summary: + // find the rowNode that is not a rowSelector + if (this.focus.focusView && !(this.focus.focusView instanceof _RowSelector)){ + return this.focus.focusView.rowNodes[inRowIndex]; + }else{ // search through views + for (var i = 0, cView; (cView = this.views.views[i]); i++) { + if (!(cView instanceof _RowSelector)) { + return cView.rowNodes[inRowIndex]; + } + } + } + return null; + }, + rowHeightChanged: function(inRowIndex){ + // summary: + // Update grid when the height of a row has changed. Row height is handled automatically as rows + // are rendered. Use this function only to update a row's height outside the normal rendering process. + // inRowIndex: Integer + // index of the row that has changed height + + this.views.renormalizeRow(inRowIndex); + this.scroller.rowHeightChanged(inRowIndex); + }, + + // fastScroll: Boolean + // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower + // scroll performance but more immediate scrolling feedback + fastScroll: true, + + delayScroll: false, + + // scrollRedrawThreshold: int + // pixel distance a user must scroll vertically to trigger grid scrolling. + scrollRedrawThreshold: (has("ie") ? 100 : 50), + + // scroll methods + scrollTo: function(inTop){ + // summary: + // Vertically scroll the grid to a given pixel position + // inTop: Integer + // vertical position of the grid in pixels + if(!this.fastScroll){ + this.setScrollTop(inTop); + return; + } + var delta = Math.abs(this.lastScrollTop - inTop); + this.lastScrollTop = inTop; + if(delta > this.scrollRedrawThreshold || this.delayScroll){ + this.delayScroll = true; + this.scrollTop = inTop; + this.views.setScrollTop(inTop); + if(this._pendingScroll){ + window.clearTimeout(this._pendingScroll); + } + var _this = this; + this._pendingScroll = window.setTimeout(function(){ + delete _this._pendingScroll; + _this.finishScrollJob(); + }, 200); + }else{ + this.setScrollTop(inTop); + } + }, + + finishScrollJob: function(){ + this.delayScroll = false; + this.setScrollTop(this.scrollTop); + }, + + setScrollTop: function(inTop){ + this.scroller.scroll(this.views.setScrollTop(inTop)); + }, + + scrollToRow: function(inRowIndex){ + // summary: + // Scroll the grid to a specific row. + // inRowIndex: Integer + // grid row index + this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1); + }, + + // styling (private, used internally to style individual parts of a row) + styleRowNode: function(inRowIndex, inRowNode){ + if(inRowNode){ + this.rows.styleRowNode(inRowIndex, inRowNode); + } + }, + + // called when the mouse leaves the grid so we can deselect all hover rows + _mouseOut: function(e){ + this.rows.setOverRow(-2); + }, + + // cells + getCell: function(inIndex){ + // summary: + // Retrieves the cell object for a given grid column. + // inIndex: Integer + // Grid column index of cell to retrieve + // returns: + // a grid cell + return this.layout.cells[inIndex]; + }, + + setCellWidth: function(inIndex, inUnitWidth){ + this.getCell(inIndex).unitWidth = inUnitWidth; + }, + + getCellName: function(inCell){ + // summary: Returns the cell name of a passed cell + return "Cell " + inCell.index; // String + }, + + // sorting + canSort: function(inSortInfo){ + // summary: + // Determines if the grid can be sorted + // inSortInfo: Integer + // Sort information, 1-based index of column on which to sort, positive for an ascending sort + // and negative for a descending sort + // returns: Boolean + // True if grid can be sorted on the given column in the given direction + }, + + sort: function(){ + }, + + getSortAsc: function(inSortInfo){ + // summary: + // Returns true if grid is sorted in an ascending direction. + inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo; + return Boolean(inSortInfo > 0); // Boolean + }, + + getSortIndex: function(inSortInfo){ + // summary: + // Returns the index of the column on which the grid is sorted + inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo; + return Math.abs(inSortInfo) - 1; // Integer + }, + + setSortIndex: function(inIndex, inAsc){ + // summary: + // Sort the grid on a column in a specified direction + // inIndex: Integer + // Column index on which to sort. + // inAsc: Boolean + // If true, sort the grid in ascending order, otherwise in descending order + var si = inIndex +1; + if(inAsc != undefined){ + si *= (inAsc ? 1 : -1); + } else if(this.getSortIndex() == inIndex){ + si = -this.sortInfo; + } + this.setSortInfo(si); + }, + + setSortInfo: function(inSortInfo){ + if(this.canSort(inSortInfo)){ + this.sortInfo = inSortInfo; + this.sort(); + this.update(); + } + }, + + // DOM event handler + doKeyEvent: function(e){ + e.dispatch = 'do' + e.type; + this.onKeyEvent(e); + }, + + // event dispatch + //: protected + _dispatch: function(m, e){ + if(m in this){ + return this[m](e); + } + return false; + }, + + dispatchKeyEvent: function(e){ + this._dispatch(e.dispatch, e); + }, + + dispatchContentEvent: function(e){ + this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e); + }, + + dispatchHeaderEvent: function(e){ + e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e); + }, + + dokeydown: function(e){ + this.onKeyDown(e); + }, + + doclick: function(e){ + if(e.cellNode){ + this.onCellClick(e); + }else{ + this.onRowClick(e); + } + }, + + dodblclick: function(e){ + if(e.cellNode){ + this.onCellDblClick(e); + }else{ + this.onRowDblClick(e); + } + }, + + docontextmenu: function(e){ + if(e.cellNode){ + this.onCellContextMenu(e); + }else{ + this.onRowContextMenu(e); + } + }, + + doheaderclick: function(e){ + if(e.cellNode){ + this.onHeaderCellClick(e); + }else{ + this.onHeaderClick(e); + } + }, + + doheaderdblclick: function(e){ + if(e.cellNode){ + this.onHeaderCellDblClick(e); + }else{ + this.onHeaderDblClick(e); + } + }, + + doheadercontextmenu: function(e){ + if(e.cellNode){ + this.onHeaderCellContextMenu(e); + }else{ + this.onHeaderContextMenu(e); + } + }, + + // override to modify editing process + doStartEdit: function(inCell, inRowIndex){ + this.onStartEdit(inCell, inRowIndex); + }, + + doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){ + this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex); + }, + + doCancelEdit: function(inRowIndex){ + this.onCancelEdit(inRowIndex); + }, + + doApplyEdit: function(inRowIndex){ + this.onApplyEdit(inRowIndex); + }, + + // row editing + addRow: function(){ + // summary: + // Add a row to the grid. + this.updateRowCount(this.get('rowCount')+1); + }, + + removeSelectedRows: function(){ + // summary: + // Remove the selected rows from the grid. + if(this.allItemsSelected){ + this.updateRowCount(0); + }else{ + this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length)); + } + this.selection.clear(); + } + + }); + + _Grid.markupFactory = function(props, node, ctor, cellFunc){ + var widthFromAttr = function(n){ + var w = html.attr(n, "width")||"auto"; + if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){ + w = parseInt(w, 10)+"px"; + } + return w; + }; + // if(!props.store){ console.debug("no store!"); } + // if a structure isn't referenced, do we have enough + // data to try to build one automatically? + if( !props.structure && + node.nodeName.toLowerCase() == "table"){ + + // try to discover a structure + props.structure = query("> colgroup", node).map(function(cg){ + var sv = html.attr(cg, "span"); + var v = { + noscroll: (html.attr(cg, "noscroll") == "true") ? true : false, + __span: (!!sv ? parseInt(sv, 10) : 1), + cells: [] + }; + if(html.hasAttr(cg, "width")){ + v.width = widthFromAttr(cg); + } + return v; // for vendetta + }); + if(!props.structure.length){ + props.structure.push({ + __span: Infinity, + cells: [] // catch-all view + }); + } + // check to see if we're gonna have more than one view + + // for each tr in our th, create a row of cells + query("thead > tr", node).forEach(function(tr, tr_idx){ + var cellCount = 0; + var viewIdx = 0; + var lastViewIdx; + var cView = null; + query("> th", tr).map(function(th){ + // what view will this cell go into? + + // NOTE: + // to prevent extraneous iteration, we start counters over + // for each row, incrementing over the surface area of the + // structure that colgroup processing generates and + // creating cell objects for each <th> to place into those + // cell groups. There's a lot of state-keepking logic + // here, but it is what it has to be. + if(!cView){ // current view book keeping + lastViewIdx = 0; + cView = props.structure[0]; + }else if(cellCount >= (lastViewIdx+cView.__span)){ + viewIdx++; + // move to allocating things into the next view + lastViewIdx += cView.__span; + var lastView = cView; + cView = props.structure[viewIdx]; + } + + // actually define the cell from what markup hands us + var cell = { + name: lang.trim(html.attr(th, "name")||th.innerHTML), + colSpan: parseInt(html.attr(th, "colspan")||1, 10), + type: lang.trim(html.attr(th, "cellType")||""), + id: lang.trim(html.attr(th,"id")||"") + }; + cellCount += cell.colSpan; + var rowSpan = html.attr(th, "rowspan"); + if(rowSpan){ + cell.rowSpan = rowSpan; + } + if(html.hasAttr(th, "width")){ + cell.width = widthFromAttr(th); + } + if(html.hasAttr(th, "relWidth")){ + cell.relWidth = window.parseInt(html.attr(th, "relWidth"), 10); + } + if(html.hasAttr(th, "hidden")){ + cell.hidden = (html.attr(th, "hidden") == "true" || html.attr(th, "hidden") === true/*always boolean true in Chrome*/); + } + + if(cellFunc){ + cellFunc(th, cell); + } + + cell.type = cell.type ? lang.getObject(cell.type) : dojox.grid.cells.Cell; + + if(cell.type && cell.type.markupFactory){ + cell.type.markupFactory(th, cell); + } + + if(!cView.cells[tr_idx]){ + cView.cells[tr_idx] = []; + } + cView.cells[tr_idx].push(cell); + }); + }); + } + + return new ctor(props, node); + }; + + return _Grid; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_Layout.js b/js/dojo-1.7.2/dojox/grid/_Layout.js new file mode 100644 index 0000000..3417168 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_Layout.js @@ -0,0 +1,276 @@ +//>>built +define("dojox/grid/_Layout", [ + "dojo/_base/kernel", + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/dom-geometry", + "./cells", + "./_RowSelector" +], function(dojo, dojox, declare, array, lang, domGeometry){ + +return declare("dojox.grid._Layout", null, { + // summary: + // Controls grid cell layout. Owned by grid and used internally. + constructor: function(inGrid){ + this.grid = inGrid; + }, + // flat array of grid cells + cells: [], + // structured array of grid cells + structure: null, + // default cell width + defaultWidth: '6em', + + // methods + moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){ + var source_cells = this.structure[sourceViewIndex].cells[0]; + var dest_cells = this.structure[destViewIndex].cells[0]; + + var cell = null; + var cell_ri = 0; + var target_ri = 0; + + for(var i=0, c; c=source_cells[i]; i++){ + if(c.index == cellIndex){ + cell_ri = i; + break; + } + } + cell = source_cells.splice(cell_ri, 1)[0]; + cell.view = this.grid.views.views[destViewIndex]; + + for(i=0, c=null; c=dest_cells[i]; i++){ + if(c.index == targetIndex){ + target_ri = i; + break; + } + } + if(!before){ + target_ri += 1; + } + dest_cells.splice(target_ri, 0, cell); + + var sortedCell = this.grid.getCell(this.grid.getSortIndex()); + if(sortedCell){ + sortedCell._currentlySorted = this.grid.getSortAsc(); + } + + this.cells = []; + cellIndex = 0; + var v; + for(i=0; v=this.structure[i]; i++){ + for(var j=0, cs; cs=v.cells[j]; j++){ + for(var k=0; c=cs[k]; k++){ + c.index = cellIndex; + this.cells.push(c); + if("_currentlySorted" in c){ + var si = cellIndex + 1; + si *= c._currentlySorted ? 1 : -1; + this.grid.sortInfo = si; + delete c._currentlySorted; + } + cellIndex++; + } + } + } + + //Fix #9481 - reset idx in cell markup + array.forEach(this.cells, function(c){ + var marks = c.markup[2].split(" "); + var oldIdx = parseInt(marks[1].substring(5));//get old "idx" + if(oldIdx != c.index){ + marks[1] = "idx=\"" + c.index + "\""; + c.markup[2] = marks.join(" "); + } + }); + + this.grid.setupHeaderMenu(); + //this.grid.renderOnIdle(); + }, + + setColumnVisibility: function(columnIndex, visible){ + var cell = this.cells[columnIndex]; + if(cell.hidden == visible){ + cell.hidden = !visible; + var v = cell.view, w = v.viewWidth; + if(w && w != "auto"){ + v._togglingColumn = domGeometry.getMarginBox(cell.getHeaderNode()).w || 0; + } + v.update(); + return true; + }else{ + return false; + } + }, + + addCellDef: function(inRowIndex, inCellIndex, inDef){ + var self = this; + var getCellWidth = function(inDef){ + var w = 0; + if(inDef.colSpan > 1){ + w = 0; + }else{ + w = inDef.width || self._defaultCellProps.width || self.defaultWidth; + + if(!isNaN(w)){ + w = w + "em"; + } + } + return w; + }; + + var props = { + grid: this.grid, + subrow: inRowIndex, + layoutIndex: inCellIndex, + index: this.cells.length + }; + + if(inDef && inDef instanceof dojox.grid.cells._Base){ + var new_cell = lang.clone(inDef); + props.unitWidth = getCellWidth(new_cell._props); + new_cell = lang.mixin(new_cell, this._defaultCellProps, inDef._props, props); + return new_cell; + } + + var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell; + if(lang.isString(cell_type)){ + cell_type = lang.getObject(cell_type); + } + + props.unitWidth = getCellWidth(inDef); + return new cell_type(lang.mixin({}, this._defaultCellProps, inDef, props)); + }, + + addRowDef: function(inRowIndex, inDef){ + var result = []; + var relSum = 0, pctSum = 0, doRel = true; + for(var i=0, def, cell; (def=inDef[i]); i++){ + cell = this.addCellDef(inRowIndex, i, def); + result.push(cell); + this.cells.push(cell); + // Check and calculate the sum of all relative widths + if(doRel && cell.relWidth){ + relSum += cell.relWidth; + }else if(cell.width){ + var w = cell.width; + if(typeof w == "string" && w.slice(-1) == "%"){ + pctSum += window.parseInt(w, 10); + }else if(w == "auto"){ + // relative widths doesn't play nice with auto - since we + // don't have a way of knowing how much space the auto is + // supposed to take up. + doRel = false; + } + } + } + if(relSum && doRel){ + // We have some kind of relWidths specified - so change them to % + array.forEach(result, function(cell){ + if(cell.relWidth){ + cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%"; + } + }); + } + return result; + + }, + + addRowsDef: function(inDef){ + var result = []; + if(lang.isArray(inDef)){ + if(lang.isArray(inDef[0])){ + for(var i=0, row; inDef && (row=inDef[i]); i++){ + result.push(this.addRowDef(i, row)); + } + }else{ + result.push(this.addRowDef(0, inDef)); + } + } + return result; + }, + + addViewDef: function(inDef){ + this._defaultCellProps = inDef.defaultCell || {}; + if(inDef.width && inDef.width == "auto"){ + delete inDef.width; + } + return lang.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)}); + }, + + setStructure: function(inStructure){ + this.fieldIndex = 0; + this.cells = []; + var s = this.structure = []; + + if(this.grid.rowSelector){ + var sel = { type: dojox._scopeName + ".grid._RowSelector" }; + + if(lang.isString(this.grid.rowSelector)){ + var width = this.grid.rowSelector; + + if(width == "false"){ + sel = null; + }else if(width != "true"){ + sel['width'] = width; + } + }else{ + if(!this.grid.rowSelector){ + sel = null; + } + } + + if(sel){ + s.push(this.addViewDef(sel)); + } + } + + var isCell = function(def){ + return ("name" in def || "field" in def || "get" in def); + }; + + var isRowDef = function(def){ + if(lang.isArray(def)){ + if(lang.isArray(def[0]) || isCell(def[0])){ + return true; + } + } + return false; + }; + + var isView = function(def){ + return (def !== null && lang.isObject(def) && + ("cells" in def || "rows" in def || ("type" in def && !isCell(def)))); + }; + + if(lang.isArray(inStructure)){ + var hasViews = false; + for(var i=0, st; (st=inStructure[i]); i++){ + if(isView(st)){ + hasViews = true; + break; + } + } + if(!hasViews){ + s.push(this.addViewDef({ cells: inStructure })); + }else{ + for(i=0; (st=inStructure[i]); i++){ + if(isRowDef(st)){ + s.push(this.addViewDef({ cells: st })); + }else if(isView(st)){ + s.push(this.addViewDef(st)); + } + } + } + }else if(isView(inStructure)){ + // it's a view object + s.push(this.addViewDef(inStructure)); + } + + this.cellCount = this.cells.length; + this.grid.setupHeaderMenu(); + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_RadioSelector.js b/js/dojo-1.7.2/dojox/grid/_RadioSelector.js new file mode 100644 index 0000000..9cfd000 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_RadioSelector.js @@ -0,0 +1,4 @@ +//>>built +define("dojox/grid/_RadioSelector", ["../main", "./_Selector"], function(dojox){ + return dojox.grid._RadioSelector; +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_RowManager.js b/js/dojo-1.7.2/dojox/grid/_RowManager.js new file mode 100644 index 0000000..c840464 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_RowManager.js @@ -0,0 +1,64 @@ +//>>built +define("dojox/grid/_RowManager", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/dom-class" +], function(declare, lang, domClass){ + + var setStyleText = function(inNode, inStyleText){ + if(inNode.style.cssText == undefined){ + inNode.setAttribute("style", inStyleText); + }else{ + inNode.style.cssText = inStyleText; + } + }; + + return declare("dojox.grid._RowManager", null, { + // Stores information about grid rows. Owned by grid and used internally. + constructor: function(inGrid){ + this.grid = inGrid; + }, + linesToEms: 2, + overRow: -2, + // styles + prepareStylingRow: function(inRowIndex, inRowNode){ + return { + index: inRowIndex, + node: inRowNode, + odd: Boolean(inRowIndex&1), + selected: !!this.grid.selection.isSelected(inRowIndex), + over: this.isOver(inRowIndex), + customStyles: "", + customClasses: "dojoxGridRow" + }; + }, + styleRowNode: function(inRowIndex, inRowNode){ + var row = this.prepareStylingRow(inRowIndex, inRowNode); + this.grid.onStyleRow(row); + this.applyStyles(row); + }, + applyStyles: function(inRow){ + var i = inRow; + + i.node.className = i.customClasses; + var h = i.node.style.height; + setStyleText(i.node, i.customStyles + ';' + (i.node._style||'')); + i.node.style.height = h; + }, + updateStyles: function(inRowIndex){ + this.grid.updateRowStyles(inRowIndex); + }, + // states and events + setOverRow: function(inRowIndex){ + var last = this.overRow; + this.overRow = inRowIndex; + if((last!=this.overRow)&&(lang.isString(last) || last >= 0)){ + this.updateStyles(last); + } + this.updateStyles(this.overRow); + }, + isOver: function(inRowIndex){ + return (this.overRow == inRowIndex && !domClass.contains(this.grid.domNode, "dojoxGridColumnResizing")); + } + }); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_RowSelector.js b/js/dojo-1.7.2/dojox/grid/_RowSelector.js new file mode 100644 index 0000000..68b0c6b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_RowSelector.js @@ -0,0 +1,59 @@ +//>>built +define("dojox/grid/_RowSelector", [ + "dojo/_base/declare", + "./_View" +], function(declare, _View){ + +return declare('dojox.grid._RowSelector', _View, { + // summary: + // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows. + defaultWidth: "2em", + noscroll: true, + padBorderWidth: 2, + buildRendering: function(){ + this.inherited('buildRendering', arguments); + this.scrollboxNode.style.overflow = "hidden"; + this.headerNode.style.visibility = "hidden"; + }, + getWidth: function(){ + return this.viewWidth || this.defaultWidth; + }, + buildRowContent: function(inRowIndex, inRowNode){ + var w = this.contentWidth || 0; + inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner"> </td></tr></table>'; + }, + renderHeader: function(){ + }, + updateRow: function(){ + }, + resize: function(){ + this.adaptHeight(); + }, + adaptWidth: function(){ + // Only calculate this here - rather than every call to buildRowContent + if(!("contentWidth" in this) && this.contentNode){ + this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth; + } + }, + // styling + doStyleRowNode: function(inRowIndex, inRowNode){ + var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ]; + if(this.grid.rows.isOver(inRowIndex)){ + n.push("dojoxGridRowbarOver"); + } + if(this.grid.selection.isSelected(inRowIndex)){ + n.push("dojoxGridRowbarSelected"); + } + inRowNode.className = n.join(" "); + }, + // event handlers + domouseover: function(e){ + this.grid.onMouseOverRow(e); + }, + domouseout: function(e){ + if(!this.isIntraRowEvent(e)){ + this.grid.onMouseOutRow(e); + } + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_Scroller.js b/js/dojo-1.7.2/dojox/grid/_Scroller.js new file mode 100644 index 0000000..99eae94 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_Scroller.js @@ -0,0 +1,507 @@ +//>>built +define("dojox/grid/_Scroller", [ + "dijit/registry", + "dojo/_base/declare", + "dojo/_base/lang", + "./util", + "dojo/_base/html" +], function(dijitRegistry, declare, lang, util, html){ + + var indexInParent = function(inNode){ + var i=0, n, p=inNode.parentNode; + while((n = p.childNodes[i++])){ + if(n == inNode){ + return i - 1; + } + } + return -1; + }; + + var cleanNode = function(inNode){ + if(!inNode){ + return; + } + dojo.forEach(dijitRegistry.toArray(), function(w){ + if(w.domNode && html.isDescendant(w.domNode, inNode, true)){ + w.destroy(); + } + }); + }; + + var getTagName = function(inNodeOrId){ + var node = html.byId(inNodeOrId); + return (node && node.tagName ? node.tagName.toLowerCase() : ''); + }; + + var nodeKids = function(inNode, inTag){ + var result = []; + var i=0, n; + while((n = inNode.childNodes[i])){ + i++; + if(getTagName(n) == inTag){ + result.push(n); + } + } + return result; + }; + + var divkids = function(inNode){ + return nodeKids(inNode, 'div'); + }; + + return declare("dojox.grid._Scroller", null, { + constructor: function(inContentNodes){ + this.setContentNodes(inContentNodes); + this.pageHeights = []; + this.pageNodes = []; + this.stack = []; + }, + // specified + rowCount: 0, // total number of rows to manage + defaultRowHeight: 32, // default height of a row + keepRows: 100, // maximum number of rows that should exist at one time + contentNode: null, // node to contain pages + scrollboxNode: null, // node that controls scrolling + // calculated + defaultPageHeight: 0, // default height of a page + keepPages: 10, // maximum number of pages that should exists at one time + pageCount: 0, + windowHeight: 0, + firstVisibleRow: 0, + lastVisibleRow: 0, + averageRowHeight: 0, // the average height of a row + // private + page: 0, + pageTop: 0, + // init + init: function(inRowCount, inKeepRows, inRowsPerPage){ + switch(arguments.length){ + case 3: this.rowsPerPage = inRowsPerPage; + case 2: this.keepRows = inKeepRows; + case 1: this.rowCount = inRowCount; + default: break; + } + this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage; + this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage); + this.setKeepInfo(this.keepRows); + this.invalidate(); + if(this.scrollboxNode){ + this.scrollboxNode.scrollTop = 0; + this.scroll(0); + this.scrollboxNode.onscroll = lang.hitch(this, 'onscroll'); + } + }, + _getPageCount: function(rowCount, rowsPerPage){ + return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0; + }, + destroy: function(){ + this.invalidateNodes(); + delete this.contentNodes; + delete this.contentNode; + delete this.scrollboxNode; + }, + setKeepInfo: function(inKeepRows){ + this.keepRows = inKeepRows; + this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2); + }, + // nodes + setContentNodes: function(inNodes){ + this.contentNodes = inNodes; + this.colCount = (this.contentNodes ? this.contentNodes.length : 0); + this.pageNodes = []; + for(var i=0; i<this.colCount; i++){ + this.pageNodes[i] = []; + } + }, + getDefaultNodes: function(){ + return this.pageNodes[0] || []; + }, + // updating + invalidate: function(){ + this._invalidating = true; + this.invalidateNodes(); + this.pageHeights = []; + this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0); + this.resize(); + this._invalidating = false; + }, + updateRowCount: function(inRowCount){ + this.invalidateNodes(); + this.rowCount = inRowCount; + // update page count, adjust document height + var oldPageCount = this.pageCount; + if(oldPageCount === 0){ + //We want to have at least 1px in height to keep scroller. Otherwise with an + //empty grid you can't scroll to see the header. + this.height = 1; + } + this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage); + if(this.pageCount < oldPageCount){ + for(var i=oldPageCount-1; i>=this.pageCount; i--){ + this.height -= this.getPageHeight(i); + delete this.pageHeights[i]; + } + }else if(this.pageCount > oldPageCount){ + this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight(); + } + this.resize(); + }, + // implementation for page manager + pageExists: function(inPageIndex){ + return Boolean(this.getDefaultPageNode(inPageIndex)); + }, + measurePage: function(inPageIndex){ + if(this.grid.rowHeight){ + var height = this.grid.rowHeight + 1; + return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ? + this.rowCount - inPageIndex * this.rowsPerPage : + this.rowsPerPage) * height; + + } + var n = this.getDefaultPageNode(inPageIndex); + return (n && n.innerHTML) ? n.offsetHeight : undefined; + }, + positionPage: function(inPageIndex, inPos){ + for(var i=0; i<this.colCount; i++){ + this.pageNodes[i][inPageIndex].style.top = inPos + 'px'; + } + }, + repositionPages: function(inPageIndex){ + var nodes = this.getDefaultNodes(); + var last = 0; + + for(var i=0; i<this.stack.length; i++){ + last = Math.max(this.stack[i], last); + } + // + var n = nodes[inPageIndex]; + var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0); + for(var p=inPageIndex+1; p<=last; p++){ + n = nodes[p]; + if(n){ + if(this.getPageNodePosition(n) == y){ + return; + } + this.positionPage(p, y); + } + y += this.getPageHeight(p); + } + }, + installPage: function(inPageIndex){ + for(var i=0; i<this.colCount; i++){ + this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]); + } + }, + preparePage: function(inPageIndex, inReuseNode){ + var p = (inReuseNode ? this.popPage() : null); + for(var i=0; i<this.colCount; i++){ + var nodes = this.pageNodes[i]; + var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes)); + new_p.pageIndex = inPageIndex; + nodes[inPageIndex] = new_p; + } + }, + // rendering implementation + renderPage: function(inPageIndex){ + var nodes = []; + var i, j; + for(i=0; i<this.colCount; i++){ + nodes[i] = this.pageNodes[i][inPageIndex]; + } + for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){ + this.renderRow(j, nodes); + } + }, + removePage: function(inPageIndex){ + for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){ + this.removeRow(j); + } + }, + destroyPage: function(inPageIndex){ + for(var i=0; i<this.colCount; i++){ + var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]); + if(n){ + html.destroy(n); + } + } + }, + pacify: function(inShouldPacify){ + }, + // pacification + pacifying: false, + pacifyTicks: 200, + setPacifying: function(inPacifying){ + if(this.pacifying != inPacifying){ + this.pacifying = inPacifying; + this.pacify(this.pacifying); + } + }, + startPacify: function(){ + this.startPacifyTicks = new Date().getTime(); + }, + doPacify: function(){ + var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks; + this.setPacifying(true); + this.startPacify(); + return result; + }, + endPacify: function(){ + this.setPacifying(false); + }, + // default sizing implementation + resize: function(){ + if(this.scrollboxNode){ + this.windowHeight = this.scrollboxNode.clientHeight; + } + for(var i=0; i<this.colCount; i++){ + //We want to have 1px in height min to keep scroller. Otherwise can't scroll + //and see header in empty grid. + util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height)); + } + + // Calculate the average row height and update the defaults (row and page). + var needPage = (!this._invalidating); + if(!needPage){ + var ah = this.grid.get("autoHeight"); + if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){ + needPage = true; + } + } + if(needPage){ + this.needPage(this.page, this.pageTop); + } + var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage); + var pageHeight = this.getPageHeight(this.page); + this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0; + }, + calcLastPageHeight: function(){ + if(!this.pageCount){ + return 0; + } + var lastPage = this.pageCount - 1; + var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight; + this.pageHeights[lastPage] = lastPageHeight; + return lastPageHeight; + }, + updateContentHeight: function(inDh){ + this.height += inDh; + this.resize(); + }, + updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){ + if(this.pageExists(inPageIndex)){ + var oh = this.getPageHeight(inPageIndex); + var h = (this.measurePage(inPageIndex)); + if(h === undefined){ + h = oh; + } + this.pageHeights[inPageIndex] = h; + if(oh != h){ + this.updateContentHeight(h - oh); + var ah = this.grid.get("autoHeight"); + if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){ + if(!fromAsynRendering){ + this.grid.sizeChange(); + }else{//fix #11101 by using fromAsynRendering to avoid deadlock + var ns = this.grid.viewsNode.style; + ns.height = parseInt(ns.height) + h - oh + 'px'; + this.repositionPages(inPageIndex); + } + }else{ + this.repositionPages(inPageIndex); + } + } + return h; + } + return 0; + }, + rowHeightChanged: function(inRowIndex, fromAsynRendering){ + this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering); + }, + // scroller core + invalidateNodes: function(){ + while(this.stack.length){ + this.destroyPage(this.popPage()); + } + }, + createPageNode: function(){ + var p = document.createElement('div'); + html.attr(p,"role","presentation"); + p.style.position = 'absolute'; + //p.style.width = '100%'; + p.style[this.grid.isLeftToRight() ? "left" : "right"] = '0'; + return p; + }, + getPageHeight: function(inPageIndex){ + var ph = this.pageHeights[inPageIndex]; + return (ph !== undefined ? ph : this.defaultPageHeight); + }, + // FIXME: this is not a stack, it's a FIFO list + pushPage: function(inPageIndex){ + return this.stack.push(inPageIndex); + }, + popPage: function(){ + return this.stack.shift(); + }, + findPage: function(inTop){ + var i = 0, h = 0; + for(var ph = 0; i<this.pageCount; i++, h += ph){ + ph = this.getPageHeight(i); + if(h + ph >= inTop){ + break; + } + } + this.page = i; + this.pageTop = h; + }, + buildPage: function(inPageIndex, inReuseNode, inPos){ + this.preparePage(inPageIndex, inReuseNode); + this.positionPage(inPageIndex, inPos); + // order of operations is key below + this.installPage(inPageIndex); + this.renderPage(inPageIndex); + // order of operations is key above + this.pushPage(inPageIndex); + }, + needPage: function(inPageIndex, inPos){ + var h = this.getPageHeight(inPageIndex), oh = h; + if(!this.pageExists(inPageIndex)){ + this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos); + h = this.updatePageHeight(inPageIndex, true); + }else{ + this.positionPage(inPageIndex, inPos); + } + return h; + }, + onscroll: function(){ + this.scroll(this.scrollboxNode.scrollTop); + }, + scroll: function(inTop){ + this.grid.scrollTop = inTop; + if(this.colCount){ + this.startPacify(); + this.findPage(inTop); + var h = this.height; + var b = this.getScrollBottom(inTop); + for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){ + y += this.needPage(p, y); + } + this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop); + this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b); + // indicates some page size has been updated + if(h != this.height){ + this.repositionPages(p-1); + } + this.endPacify(); + } + }, + getScrollBottom: function(inTop){ + return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1); + }, + // events + processNodeEvent: function(e, inNode){ + var t = e.target; + while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){ + t = t.parentNode; + } + if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){ + return false; + } + var page = t.parentNode; + e.topRowIndex = page.pageIndex * this.rowsPerPage; + e.rowIndex = e.topRowIndex + indexInParent(t); + e.rowTarget = t; + return true; + }, + processEvent: function(e){ + return this.processNodeEvent(e, this.contentNode); + }, + // virtual rendering interface + renderRow: function(inRowIndex, inPageNode){ + }, + removeRow: function(inRowIndex){ + }, + // page node operations + getDefaultPageNode: function(inPageIndex){ + return this.getDefaultNodes()[inPageIndex]; + }, + positionPageNode: function(inNode, inPos){ + }, + getPageNodePosition: function(inNode){ + return inNode.offsetTop; + }, + invalidatePageNode: function(inPageIndex, inNodes){ + var p = inNodes[inPageIndex]; + if(p){ + delete inNodes[inPageIndex]; + this.removePage(inPageIndex, p); + cleanNode(p); + p.innerHTML = ''; + } + return p; + }, + // scroll control + getPageRow: function(inPage){ + return inPage * this.rowsPerPage; + }, + getLastPageRow: function(inPage){ + return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1; + }, + getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){ + if(!this.pageExists(inPage)){ + return 0; + } + var row = this.getPageRow(inPage); + var nodes = this.getDefaultNodes(); + var rows = divkids(nodes[inPage]); + for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){ + inPageTop += rows[i].offsetHeight; + } + return (row ? row - 1 : row); + }, + getLastVisibleRow: function(inPage, inBottom, inScrollBottom){ + if(!this.pageExists(inPage)){ + return 0; + } + var nodes = this.getDefaultNodes(); + var row = this.getLastPageRow(inPage); + var rows = divkids(nodes[inPage]); + for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){ + inBottom -= rows[i].offsetHeight; + } + return row + 1; + }, + findTopRow: function(inScrollTop){ + var nodes = this.getDefaultNodes(); + var rows = divkids(nodes[this.page]); + for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){ + h = rows[i].offsetHeight; + t += h; + if(t >= inScrollTop){ + this.offset = h - (t - inScrollTop); + return i + this.page * this.rowsPerPage; + } + } + return -1; + }, + findScrollTop: function(inRow){ + var rowPage = Math.floor(inRow / this.rowsPerPage); + var t = 0; + var i, l; + for(i=0; i<rowPage; i++){ + t += this.getPageHeight(i); + } + this.pageTop = t; + this.page = rowPage;//fix #10543 + this.needPage(rowPage, this.pageTop); + + var nodes = this.getDefaultNodes(); + var rows = divkids(nodes[rowPage]); + var r = inRow - this.rowsPerPage * rowPage; + for(i=0,l=rows.length; i<l && i<r; i++){ + t += rows[i].offsetHeight; + } + return t; + }, + dummy: 0 + }); +}); diff --git a/js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js b/js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js new file mode 100644 index 0000000..c02e92c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js @@ -0,0 +1,67 @@ +//>>built +define("dojox/grid/_SelectionPreserver", [ + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/lang", + "dojo/_base/array" +], function(declare, connect, lang, array){ + +return declare("dojox.grid._SelectionPreserver", null, { + // summary: + // Preserve selections across various user actions. + // + // description: + // When this feature is turned on, Grid will try to preserve selections across actions, e.g. sorting, filtering etc. + // + // Precondition - Identifier(id) is required for store since id is the only way for differentiating row items. + // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click) + // + // example: + // | //To turn on this - please set 'keepSelection' attribute to true + // | <div dojoType="dojox.grid.DataGrid" keepSelection = true .../> + // | <div dojoType="dojox.grid.TreeGrid" keepSelection = true .../> + // | <div dojoType="dojox.grid.LazyTreeGrid" keepSelection = true .../> + + constructor: function(selection){ + this.selection = selection; + var grid = this.grid = selection.grid; + this.reset(); + this._connects = [ + connect.connect(grid, '_setStore', this, 'reset'), + connect.connect(grid, '_addItem', this, '_reSelectById'), + connect.connect(selection, 'addToSelection', lang.hitch(this, '_selectById', true)), + connect.connect(selection, 'deselect', lang.hitch(this, '_selectById', false)), + connect.connect(selection, 'deselectAll', this, 'reset') + ]; + }, + destroy: function(){ + this.reset(); + array.forEach(this._connects, connect.disconnect); + delete this._connects; + }, + reset: function(){ + this._selectedById = {}; + }, + _reSelectById: function(item, index){ + // summary: + // When some rows is fetched, determine whether it should be selected. + if(item && this.grid._hasIdentity){ + this.selection.selected[index] = this._selectedById[this.grid.store.getIdentity(item)]; + } + }, + _selectById: function(toSelect, inItemOrIndex){ + // summary: + // Record selected rows by ID. + if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; } + var item = inItemOrIndex, g = this.grid; + if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){ + var entry = g._by_idx[inItemOrIndex]; + item = entry && entry.item; + } + if(item){ + this._selectedById[g.store.getIdentity(item)] = !!toSelect; + } + return item; + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_Selector.js b/js/dojo-1.7.2/dojox/grid/_Selector.js new file mode 100644 index 0000000..142b4d4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_Selector.js @@ -0,0 +1,225 @@ +//>>built +define("dojox/grid/_Selector", [ + "../main", + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/query", + "dojo/dom-class", + "./Selection", + "./_View", + "./_Builder", + "./util" +], function(dojox, declare, lang, query, domClass, Selection, _View, _Builder, util){ + + var _InputSelectorHeaderBuilder = dojox.grid._InputSelectorHeaderBuilder = lang.extend(function(view){ + _Builder._HeaderBuilder.call(this, view); + },_Builder._HeaderBuilder.prototype,{ + generateHtml: function(){ + var w = this.view.contentWidth || 0; + var selectedCount = this.view.grid.selection.getSelectedCount(); + var checked = (selectedCount && selectedCount == this.view.grid.rowCount) ? ' dijitCheckBoxChecked dijitChecked' : ''; + return '<table style="width:' + w + 'px;" ' + + 'border="0" cellspacing="0" cellpadding="0" ' + + 'role="presentation"><tr><th style="text-align: center;">' + + '<div class="dojoxGridCheckSelector dijitReset dijitInline dijitCheckBox' + checked + '"></div></th></tr></table>'; + }, + doclick: function(e){ + var selectedCount = this.view.grid.selection.getSelectedCount(); + + this.view._selectionChanging = true; + if(selectedCount==this.view.grid.rowCount){ + this.view.grid.selection.deselectAll(); + }else{ + this.view.grid.selection.selectRange(0, this.view.grid.rowCount-1); + } + this.view._selectionChanging = false; + this.view.onSelectionChanged(); + return true; + } + }); + + var _SelectorContentBuilder = dojox.grid._SelectorContentBuilder = lang.extend(function(view){ + _Builder._ContentBuilder.call(this, view); + },_Builder._ContentBuilder.prototype,{ + generateHtml: function(inDataIndex, inRowIndex){ + var w = this.view.contentWidth || 0; + return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' + + 'cellspacing="0" cellpadding="0" role="presentation"><tr>' + + '<td style="text-align: center;" class="dojoxGridRowbarInner">' + this.getCellContent(inRowIndex) + '</td></tr></table>'; + }, + getCellContent: function(inRowIndex){ + return ' '; + }, + findTarget: function(){ + var t = _Builder._ContentBuilder.prototype.findTarget.apply(this, arguments); + return t; + }, + domouseover: function(e){ + this.view.grid.onMouseOverRow(e); + }, + domouseout: function(e){ + if(!this.isIntraRowEvent(e)){ + this.view.grid.onMouseOutRow(e); + } + }, + doclick: function(e){ + var idx = e.rowIndex; + var selected = this.view.grid.selection.isSelected(idx); + var mode = this.view.grid.selection.mode; + + if(!selected){ + if(mode == 'single'){ + this.view.grid.selection.select(idx); + }else if(mode != 'none'){ + this.view.grid.selection.addToSelection(idx); + } + }else{ + this.view.grid.selection.deselect(idx); + } + + return true; + } + }); + + var _InputSelectorContentBuilder = dojox.grid._InputSelectorContentBuilder = lang.extend(function(view){ + _SelectorContentBuilder.call(this, view); + },_SelectorContentBuilder.prototype,{ + getCellContent: function(rowIndex){ + var v = this.view; + var type = v.inputType == "checkbox" ? "CheckBox" : "Radio"; + var checked = !!v.grid.selection.isSelected(rowIndex) ? ' dijit' + type + 'Checked dijitChecked' : ''; + return '<div class="dojoxGridCheckSelector dijitReset dijitInline dijit' + type + checked + '"></div>'; + } + }); + + var _Selector = declare("dojox.grid._Selector", _View, { + inputType: '', + selectionMode: '', + + // summary: + // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows. + defaultWidth: "2em", + noscroll: true, + padBorderWidth: 2, + + _contentBuilderClass: _SelectorContentBuilder, + + postCreate: function(){ + this.inherited(arguments); + + if(this.selectionMode){ + this.grid.selection.mode = this.selectionMode; + } + this.connect(this.grid.selection, 'onSelected', 'onSelected'); + this.connect(this.grid.selection, 'onDeselected', 'onDeselected'); + }, + buildRendering: function(){ + this.inherited(arguments); + this.scrollboxNode.style.overflow = "hidden"; + }, + getWidth: function(){ + return this.viewWidth || this.defaultWidth; + }, + resize: function(){ + this.adaptHeight(); + }, + setStructure: function(s){ + this.inherited(arguments); + if(s.defaultWidth){ + this.defaultWidth = s.defaultWidth; + } + }, + adaptWidth: function(){ + // Only calculate this here - rather than every call to buildRowContent + if(!("contentWidth" in this) && this.contentNode){ + this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth; + } + }, + // styling + doStyleRowNode: function(inRowIndex, inRowNode){ + var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ]; + if(this.grid.rows.isOver(inRowIndex)){ + n.push("dojoxGridRowbarOver"); + } + if(this.grid.selection.isSelected(inRowIndex)){ + n.push("dojoxGridRowbarSelected"); + } + inRowNode.className = n.join(" "); + }, + // event handlers + onSelected: function(inIndex){ + this.grid.updateRow(inIndex); + }, + onDeselected: function(inIndex){ + this.grid.updateRow(inIndex); + } + }); + if(!_View.prototype._headerBuilderClass && + !_View.prototype._contentBuilderClass){ + _Selector.prototype.postCreate = function(){ + this.connect(this.scrollboxNode,"onscroll","doscroll"); + util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]); + util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]); + if(this._contentBuilderClass){ + this.content = new this._contentBuilderClass(this); + }else{ + this.content = new _Builder._ContentBuilder(this); + } + if(this._headerBuilderClass){ + this.header = new this._headerBuilderClass(this); + }else{ + this.header = new _Builder._HeaderBuilder(this); + } + //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node + if(!this.grid.isLeftToRight()){ + this.headerNodeContainer.style.width = ""; + } + this.connect(this.grid.selection, 'onSelected', 'onSelected'); + this.connect(this.grid.selection, 'onDeselected', 'onDeselected'); + }; + } + + declare("dojox.grid._RadioSelector", _Selector, { + inputType: 'radio', + selectionMode: 'single', + + _contentBuilderClass: _InputSelectorContentBuilder, + + buildRendering: function(){ + this.inherited(arguments); + this.headerNode.style.visibility = "hidden"; + }, + + renderHeader: function(){} + }); + + declare("dojox.grid._CheckBoxSelector", _Selector, { + inputType: 'checkbox', + _headerBuilderClass: _InputSelectorHeaderBuilder, + _contentBuilderClass: _InputSelectorContentBuilder, + postCreate: function(){ + this.inherited(arguments); + this.connect(this.grid, 'onSelectionChanged', 'onSelectionChanged'); + this.connect(this.grid, 'updateRowCount', '_updateVisibility'); + }, + renderHeader: function(){ + this.inherited(arguments); + this._updateVisibility(this.grid.rowCount); + }, + _updateVisibility: function(rowCount){ + this.headerNode.style.visibility = rowCount ? "" : "hidden"; + }, + onSelectionChanged: function(){ + if(this._selectionChanging){ return; } + var inputDiv = query('.dojoxGridCheckSelector', this.headerNode)[0]; + var g = this.grid; + var s = (g.rowCount && g.rowCount == g.selection.getSelectedCount()); + g.allItemsSelected = s||false; + domClass.toggle(inputDiv, "dijitChecked", g.allItemsSelected); + domClass.toggle(inputDiv, "dijitCheckBoxChecked", g.allItemsSelected); + } + }); + + return _Selector; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_TreeView.js b/js/dojo-1.7.2/dojox/grid/_TreeView.js new file mode 100644 index 0000000..8cf24fd --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_TreeView.js @@ -0,0 +1,467 @@ +//>>built +require({cache:{ +'url:dojox/grid/resources/Expando.html':"<div class=\"dojoxGridExpando\"\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\n\t></div\n></div>\n"}}); +define("dojox/grid/_TreeView", [ + "dijit/registry", + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/event", + "dojo/dom-attr", + "dojo/dom-class", + "dojo/dom-style", + "dojo/dom-construct", + "dojo/query", + "dojo/parser", + "dojo/text!./resources/Expando.html", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "./_View", + "./_Builder", + "./util" +], function(dijit, dojox, declare, array, lang, event, domAttr, domClass, + domStyle, domCtr, query, parser, template, _Widget, _TemplatedMixin, _View, _Builder, util){ + +declare("dojox.grid._Expando", [ _Widget, _TemplatedMixin ], { + open: false, + toggleClass: "", + itemId: "", + cellIdx: -1, + view: null, + rowNode: null, + rowIdx: -1, + expandoCell: null, + level: 0, + templateString: template, + _toggleRows: function(toggleClass, open){ + if(!toggleClass || !this.rowNode){ return; } + if(query("table.dojoxGridRowTableNeedsRowUpdate").length){ + if(this._initialized){ + this.view.grid.updateRow(this.rowIdx); + } + return; + } + var self = this; + var g = this.view.grid; + if(g.treeModel){ + var p = this._tableRow ? domAttr.get(this._tableRow, "dojoxTreeGridPath") : ""; + if(p){ + query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){ + var en = query(".dojoxGridExpando", n)[0]; + if(en && en.parentNode && en.parentNode.parentNode && + !domClass.contains(en.parentNode.parentNode, "dojoxGridNoChildren")){ + var ew = dijit.byNode(en); + if(ew){ + ew._toggleRows(toggleClass, ew.open&&open); + } + } + n.style.display = open ? "" : "none"; + }); + } + }else{ + query("tr." + toggleClass, this.rowNode).forEach(function(n){ + if(domClass.contains(n, "dojoxGridExpandoRow")){ + var en = query(".dojoxGridExpando", n)[0]; + if(en){ + var ew = dijit.byNode(en); + var toggleClass = ew ? ew.toggleClass : en.getAttribute("toggleClass"); + var wOpen = ew ? ew.open : self.expandoCell.getOpenState(en.getAttribute("itemId")); + self._toggleRows(toggleClass, wOpen&&open); + } + } + n.style.display = open ? "" : "none"; + }); + } + }, + setOpen: function(open){ + if(open && domClass.contains(this.domNode, "dojoxGridExpandoLoading")){ + open = false; + } + var view = this.view; + var grid = view.grid; + var store = grid.store; + var treeModel = grid.treeModel; + var d = this; + var idx = this.rowIdx; + var me = grid._by_idx[idx]; + if(!me){ return; } + if(treeModel && !this._loadedChildren){ + if(open){ + // Do this to make sure our children are fully-loaded + var itm = grid.getItem(domAttr.get(this._tableRow, "dojoxTreeGridPath")); + if(itm){ + this.expandoInner.innerHTML = "o"; + domClass.add(this.domNode, "dojoxGridExpandoLoading"); + treeModel.getChildren(itm, function(items){ + d._loadedChildren = true; + d._setOpen(open); + }); + }else{ + this._setOpen(open); + } + }else{ + this._setOpen(open); + } + }else if(!treeModel && store){ + if(open){ + var data = grid._by_idx[this.rowIdx]; + if(data&&!store.isItemLoaded(data.item)){ + this.expandoInner.innerHTML = "o"; + domClass.add(this.domNode, "dojoxGridExpandoLoading"); + store.loadItem({ + item: data.item, + onItem: lang.hitch(this, function(i){ + var idty = store.getIdentity(i); + grid._by_idty[idty] = grid._by_idx[this.rowIdx] = { idty: idty, item: i }; + this._setOpen(open); + }) + }); + }else{ + this._setOpen(open); + } + }else{ + this._setOpen(open); + } + }else{ + this._setOpen(open); + } + }, + _setOpen: function(open){ + if(open && this._tableRow && domClass.contains(this._tableRow, "dojoxGridNoChildren")){ + this._setOpen(false); + return; + } + this.expandoInner.innerHTML = open ? "-" : "+"; + domClass.remove(this.domNode, "dojoxGridExpandoLoading"); + domClass.toggle(this.domNode, "dojoxGridExpandoOpened", open); + if(this._tableRow){ + domClass.toggle(this._tableRow, "dojoxGridRowCollapsed", !open); + var base = domAttr.get(this._tableRow, "dojoxTreeGridBaseClasses"); + var new_base = ""; + if(open){ + new_base = lang.trim((" " + base + " ").replace(" dojoxGridRowCollapsed ", " ")); + }else{ + if((" " + base + " ").indexOf(' dojoxGridRowCollapsed ') < 0){ + new_base = base + (base ? ' ' : '' ) + 'dojoxGridRowCollapsed'; + }else{ + new_base = base; + } + } + domAttr.set(this._tableRow, 'dojoxTreeGridBaseClasses', new_base); + } + var changed = (this.open !== open); + this.open = open; + if(this.expandoCell && this.itemId){ + this.expandoCell.openStates[this.itemId] = open; + } + var v = this.view; + var g = v.grid; + if(this.toggleClass && changed){ + if(!this._tableRow || !this._tableRow.style.display){ + this._toggleRows(this.toggleClass, open); + } + } + if(v && this._initialized && this.rowIdx >= 0){ + g.rowHeightChanged(this.rowIdx); + g.postresize(); + v.hasVScrollbar(true); + } + this._initialized = true; + }, + onToggle: function(e){ + this.setOpen(!this.open); + event.stop(e); + }, + setRowNode: function(rowIdx, rowNode, view){ + if(this.cellIdx < 0 || !this.itemId){ return false; } + this._initialized = false; + this.view = view; + this.rowNode = rowNode; + this.rowIdx = rowIdx; + this.expandoCell = view.structure.cells[0][this.cellIdx]; + var d = this.domNode; + if(d && d.parentNode && d.parentNode.parentNode){ + this._tableRow = d.parentNode.parentNode; + } + this.open = this.expandoCell.getOpenState(this.itemId); + if(view.grid.treeModel){ + // TODO: Rather than hard-code the 18px and 3px, we should probably + // calculate them based off css or something... However, all the + // themes that we support use these values. + domStyle.set(this.domNode , "marginLeft" , (this.level * 18) + "px"); + if(this.domNode.parentNode){ + domStyle.set(this.domNode.parentNode, "backgroundPosition", ((this.level * 18) + (3)) + "px"); + } + } + this.setOpen(this.open); + return true; + } +}); + +var _TreeContentBuilder = declare("dojox.grid._TreeContentBuilder", _Builder._ContentBuilder, { + generateHtml: function(inDataIndex, inRowIndex){ + var + html = this.getTableArray(), + v = this.view, + row = v.structure.cells[0], + item = this.grid.getItem(inRowIndex), + grid = this.grid, + store = this.grid.store; + + util.fire(this.view, "onBeforeRow", [inRowIndex, [row]]); + + var createRow = function(level, rowItem, summaryRow, toggleClasses, rowStack, shown){ + if(!shown){ + if(html[0].indexOf('dojoxGridRowTableNeedsRowUpdate') == -1){ + html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate"); + } + return; + } + var rowNodeIdx = html.length; + toggleClasses = toggleClasses || []; + var tcJoin = toggleClasses.join('|'); + var tcString = toggleClasses[toggleClasses.length - 1]; + var clString = tcString + (summaryRow ? " dojoxGridSummaryRow" : ""); + var sString = ""; + if(grid.treeModel && rowItem && !grid.treeModel.mayHaveChildren(rowItem)){ + clString += " dojoxGridNoChildren"; + } + html.push('<tr style="' + sString + '" class="' + clString + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + clString + '">'); + var nextLevel = level + 1; + var parentCell = null; + for(var i=0, cell; (cell=row[i]); i++){ + var m = cell.markup, cc = cell.customClasses = [], cs = cell.customStyles = []; + // content (format can fill in cc and cs as side-effects) + m[5] = cell.formatAtLevel(rowStack, rowItem, level, summaryRow, tcString, cc); + // classes + m[1] = cc.join(' '); + // styles + m[3] = cs.join(';'); + // in-place concat + html.push.apply(html, m); + if(!parentCell && cell.level === nextLevel && cell.parentCell){ + parentCell = cell.parentCell; + } + } + html.push('</tr>'); + if(rowItem && store && store.isItem(rowItem)){ + var idty = store.getIdentity(rowItem); + if(typeof grid._by_idty_paths[idty] == "undefined"){ + grid._by_idty_paths[idty] = rowStack.join('/'); + } + } + var expandoCell; + var parentOpen; + var path; + var values; + var iStack = rowStack.concat([]); + if(grid.treeModel && rowItem){ + if(grid.treeModel.mayHaveChildren(rowItem)){ + expandoCell = v.structure.cells[0][grid.expandoCell||0]; + parentOpen = expandoCell.getOpenState(rowItem) && shown; + path = new dojox.grid.TreePath(rowStack.join('/'), grid); + values = path.children(true)||[]; + array.forEach(values, function(cItm, idx){ + var nToggle = tcJoin.split('|'); + nToggle.push(nToggle[nToggle.length - 1] + "-" + idx); + iStack.push(idx); + createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen); + iStack.pop(); + }); + } + }else if(rowItem && parentCell && !summaryRow){ + expandoCell = v.structure.cells[0][parentCell.level]; + parentOpen = expandoCell.getOpenState(rowItem) && shown; + if(store.hasAttribute(rowItem, parentCell.field)){ + var tToggle = tcJoin.split('|'); + tToggle.pop(); + path = new dojox.grid.TreePath(rowStack.join('/'), grid); + values = path.children(true)||[]; + if(values.length){ + html[rowNodeIdx] = '<tr class="' + tToggle.join(' ') +' dojoxGridExpandoRow" dojoxTreeGridPath="' + rowStack.join('/') + '">'; + array.forEach(values, function(cItm, idx){ + var nToggle = tcJoin.split('|'); + nToggle.push(nToggle[nToggle.length - 1] + "-" + idx); + iStack.push(idx); + createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen); + iStack.pop(); + }); + iStack.push(values.length); + createRow(level, rowItem, true, toggleClasses, iStack, parentOpen); + }else{ + html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">'; + } + }else{ + if(!store.isItemLoaded(rowItem)){ + html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate"); + }else{ + html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">'; + } + } + }else if(rowItem && !summaryRow && toggleClasses.length > 1){ + html[rowNodeIdx] = '<tr class="' + toggleClasses[toggleClasses.length - 2] + '" dojoxTreeGridPath="' + rowStack.join('/') + '">'; + } + }; + createRow(0, item, false, ["dojoxGridRowToggle-" + inRowIndex], [inRowIndex], true); + html.push('</table>'); + return html.join(''); // String + }, + findTarget: function(inSource, inTag){ + var n = inSource; + while(n && (n!=this.domNode)){ + if(n.tagName && n.tagName.toLowerCase() == 'tr'){ + break; + } + n = n.parentNode; + } + return (n != this.domNode) ? n : null; + }, + getCellNode: function(inRowNode, inCellIndex){ + var node = query("td[idx='" + inCellIndex + "']", inRowNode)[0]; + if(node&&node.parentNode&&!domClass.contains(node.parentNode, "dojoxGridSummaryRow")){ + return node; + } + }, + decorateEvent: function(e){ + e.rowNode = this.findRowTarget(e.target); + if(!e.rowNode){return false;} + e.rowIndex = domAttr.get(e.rowNode, 'dojoxTreeGridPath'); + this.baseDecorateEvent(e); + e.cell = this.grid.getCell(e.cellIndex); + return true; // Boolean + } +}); + +return declare("dojox.grid._TreeView", _View, { + _contentBuilderClass: _TreeContentBuilder, + _onDndDrop: function(source, nodes, copy){ + if(this.grid && this.grid.aggregator){ + this.grid.aggregator.clearSubtotalCache(); + } + this.inherited(arguments); + }, + postCreate: function(){ + this.inherited(arguments); + this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache'); + }, + _cleanupExpandoCache: function(index, identity, item){ + if(index == -1){ + return; + } + array.forEach(this.grid.layout.cells, function(cell){ + if(typeof cell['openStates'] != 'undefined'){ + if(identity in cell.openStates){ + delete cell.openStates[identity]; + } + } + }); + if(typeof index == "string" && index.indexOf('/') > -1){ + var path = new dojox.grid.TreePath(index, this.grid); + var ppath = path.parent(); + while(ppath){ + path = ppath; + ppath = path.parent(); + } + var pitem = path.item(); + if(!pitem){ + return; + } + var idty = this.grid.store.getIdentity(pitem); + if(typeof this._expandos[idty] != 'undefined'){ + for(var i in this._expandos[idty]){ + var exp = this._expandos[idty][i]; + if(exp){ + exp.destroy(); + } + delete this._expandos[idty][i]; + } + delete this._expandos[idty]; + } + }else{ + for(var i in this._expandos){ + if(typeof this._expandos[i] != 'undefined'){ + for(var j in this._expandos[i]){ + var exp = this._expandos[i][j]; + if(exp){ + exp.destroy(); + } + } + } + } + this._expandos = {}; + } + }, + postMixInProperties: function(){ + this.inherited(arguments); + this._expandos = {}; + }, + onBeforeRow: function(inRowIndex, cells){ + // Save off our expando if we have one so we don't have to create it + // again + var g = this.grid; + if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){ + var idty = g._by_idx[inRowIndex].idty; + this._expandos[idty] = this._expandos[idty] || {}; + } + this.inherited(arguments); + }, + onAfterRow: function(inRowIndex, cells, inRowNode){ + array.forEach(query("span.dojoxGridExpando", inRowNode), function(n){ + if(n && n.parentNode){ + // Either create our expando or put the existing expando back + // into place + var tc = n.getAttribute("toggleClass"); + var idty; + var expando; + var g = this.grid; + if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){ + idty = g._by_idx[inRowIndex].idty; + expando = this._expandos[idty][tc]; + } + if(expando){ + domCtr.place(expando.domNode, n, "replace"); + expando.itemId = n.getAttribute("itemId"); + expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10); + if(isNaN(expando.cellIdx)){ + expando.cellIdx = -1; + } + }else{ + if(idty){ + expando = parser.parse(n.parentNode)[0]; + this._expandos[idty][tc] = expando; + } + } + if(expando && !expando.setRowNode(inRowIndex, inRowNode, this)){ + expando.domNode.parentNode.removeChild(expando.domNode); + } + } + }, this); + var alt = false; + var self = this; + query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(n){ + domClass.toggle(n, "dojoxGridSubRowAlt", alt); + domAttr.set(n, "dojoxTreeGridBaseClasses", n.className); + alt = !alt; + self.grid.rows.styleRowNode(domAttr.get(n, 'dojoxTreeGridPath'), n); + }); + this.inherited(arguments); + }, + updateRowStyles: function(inRowIndex){ + var rowNodes = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode); + if(rowNodes.length){ + this.styleRowNode(inRowIndex, rowNodes[0]); + } + }, + getCellNode: function(inRowIndex, inCellIndex){ + var row = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode)[0]; + if(row){ + return this.content.getCellNode(row, inCellIndex); + } + }, + destroy: function(){ + this._cleanupExpandoCache(); + this.inherited(arguments); + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_View.js b/js/dojo-1.7.2/dojox/grid/_View.js new file mode 100644 index 0000000..f7d5937 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_View.js @@ -0,0 +1,854 @@ +//>>built +require({cache:{ +'url:dojox/grid/resources/View.html':"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n"}}); +define("dojox/grid/_View", [ + "dojo", + "dijit/registry", + "../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/connect", + "dojo/_base/sniff", + "dojo/query", + "dojo/_base/window", + "dojo/text!./resources/View.html", + "dojo/dnd/Source", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dojox/html/metrics", + "./util", + "dojo/_base/html", + "./_Builder", + "dojo/dnd/Avatar", + "dojo/dnd/Manager" +], function(dojo, dijit, dojox, declare, array, lang, connect, has, query, + win, template, Source, _Widget, _TemplatedMixin, metrics, util, html, _Builder, Avatar){ + + // a private function + var getStyleText = function(inNode, inStyleText){ + return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText; + }; + + // some public functions + var _View = declare('dojox.grid._View', [_Widget, _TemplatedMixin], { + // summary: + // A collection of grid columns. A grid is comprised of a set of views that stack horizontally. + // Grid creates views automatically based on grid's layout structure. + // Users should typically not need to access individual views directly. + // + // defaultWidth: String + // Default width of the view + defaultWidth: "18em", + + // viewWidth: String + // Width for the view, in valid css unit + viewWidth: "", + + templateString: template, + + themeable: false, + classTag: 'dojoxGrid', + marginBottom: 0, + rowPad: 2, + + // _togglingColumn: int + // Width of the column being toggled (-1 for none) + _togglingColumn: -1, + + // _headerBuilderClass: Object + // The class to use for our header builder + _headerBuilderClass: _Builder._HeaderBuilder, + + // _contentBuilderClass: Object + // The class to use for our content builder + _contentBuilderClass: _Builder._ContentBuilder, + + postMixInProperties: function(){ + this.rowNodes = {}; + }, + + postCreate: function(){ + this.connect(this.scrollboxNode,"onscroll","doscroll"); + util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]); + util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]); + this.content = new this._contentBuilderClass(this); + this.header = new this._headerBuilderClass(this); + //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node + if(!this.grid.isLeftToRight()){ + this.headerNodeContainer.style.width = ""; + } + }, + + destroy: function(){ + html.destroy(this.headerNode); + delete this.headerNode; + for(var i in this.rowNodes){ + this._cleanupRowWidgets(this.rowNodes[i]); + html.destroy(this.rowNodes[i]); + } + this.rowNodes = {}; + if(this.source){ + this.source.destroy(); + } + this.inherited(arguments); + }, + + // focus + focus: function(){ + if(has("ie") || has("webkit") || has("opera")){ + this.hiddenFocusNode.focus(); + }else{ + this.scrollboxNode.focus(); + } + }, + + setStructure: function(inStructure){ + var vs = (this.structure = inStructure); + // FIXME: similar logic is duplicated in layout + if(vs.width && !isNaN(vs.width)){ + this.viewWidth = vs.width + 'em'; + }else{ + this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth; + } + this._onBeforeRow = vs.onBeforeRow||function(){}; + this._onAfterRow = vs.onAfterRow||function(){}; + this.noscroll = vs.noscroll; + if(this.noscroll){ + this.scrollboxNode.style.overflow = "hidden"; + } + this.simpleStructure = Boolean(vs.cells.length == 1); + // bookkeeping + this.testFlexCells(); + // accomodate new structure + this.updateStructure(); + }, + + _cleanupRowWidgets: function(inRowNode){ + // Summary: + // Cleans up the widgets for the given row node so that + // we can reattach them if needed + if(inRowNode){ + array.forEach(query("[widgetId]", inRowNode).map(dijit.byNode), function(w){ + if(w._destroyOnRemove){ + w.destroy(); + delete w; + }else if(w.domNode && w.domNode.parentNode){ + w.domNode.parentNode.removeChild(w.domNode); + } + }); + } + }, + + onBeforeRow: function(inRowIndex, cells){ + this._onBeforeRow(inRowIndex, cells); + if(inRowIndex >= 0){ + this._cleanupRowWidgets(this.getRowNode(inRowIndex)); + } + }, + + onAfterRow: function(inRowIndex, cells, inRowNode){ + this._onAfterRow(inRowIndex, cells, inRowNode); + var g = this.grid; + array.forEach(query(".dojoxGridStubNode", inRowNode), function(n){ + if(n && n.parentNode){ + var lw = n.getAttribute("linkWidget"); + var cellIdx = window.parseInt(html.attr(n, "cellIdx"), 10); + var cellDef = g.getCell(cellIdx); + var w = dijit.byId(lw); + if(w){ + n.parentNode.replaceChild(w.domNode, n); + if(!w._started){ + w.startup(); + } + dojo.destroy(n); + }else{ + n.innerHTML = ""; + } + } + }, this); + }, + + testFlexCells: function(){ + // FIXME: cheater, this function does double duty as initializer and tester + this.flexCells = false; + for(var j=0, row; (row=this.structure.cells[j]); j++){ + for(var i=0, cell; (cell=row[i]); i++){ + cell.view = this; + this.flexCells = this.flexCells || cell.isFlex(); + } + } + return this.flexCells; + }, + + updateStructure: function(){ + // header builder needs to update table map + this.header.update(); + // content builder needs to update markup cache + this.content.update(); + }, + + getScrollbarWidth: function(){ + var hasScrollSpace = this.hasVScrollbar(); + var overflow = html.style(this.scrollboxNode, "overflow"); + if(this.noscroll || !overflow || overflow == "hidden"){ + hasScrollSpace = false; + }else if(overflow == "scroll"){ + hasScrollSpace = true; + } + return (hasScrollSpace ? metrics.getScrollbar().w : 0); // Integer + }, + + getColumnsWidth: function(){ + var h = this.headerContentNode; + return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer + }, + + setColumnsWidth: function(width){ + this.headerContentNode.firstChild.style.width = width + 'px'; + if(this.viewWidth){ + this.viewWidth = width + 'px'; + } + }, + + getWidth: function(){ + return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String + }, + + getContentWidth: function(){ + return Math.max(0, html._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String + }, + + render: function(){ + this.scrollboxNode.style.height = ''; + this.renderHeader(); + if(this._togglingColumn >= 0){ + this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn); + this._togglingColumn = -1; + } + var cells = this.grid.layout.cells; + var getSibling = lang.hitch(this, function(node, before){ + !this.grid.isLeftToRight() && (before = !before); + var inc = before?-1:1; + var idx = this.header.getCellNodeIndex(node) + inc; + var cell = cells[idx]; + while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){ + idx += inc; + cell = cells[idx]; + } + if(cell){ + return cell.getHeaderNode(); + } + return null; + }); + if(this.grid.columnReordering && this.simpleStructure){ + if(this.source){ + this.source.destroy(); + } + + // Create the top and bottom markers + var bottomMarkerId = "dojoxGrid_bottomMarker"; + var topMarkerId = "dojoxGrid_topMarker"; + if(this.bottomMarker){ + html.destroy(this.bottomMarker); + } + this.bottomMarker = html.byId(bottomMarkerId); + if(this.topMarker){ + html.destroy(this.topMarker); + } + this.topMarker = html.byId(topMarkerId); + if (!this.bottomMarker) { + this.bottomMarker = html.create("div", { + "id": bottomMarkerId, + "class": "dojoxGridColPlaceBottom" + }, win.body()); + this._hide(this.bottomMarker); + + + this.topMarker = html.create("div", { + "id": topMarkerId, + "class": "dojoxGridColPlaceTop" + }, win.body()); + this._hide(this.topMarker); + } + this.arrowDim = html.contentBox(this.bottomMarker); + + var headerHeight = html.contentBox(this.headerContentNode.firstChild.rows[0]).h; + + this.source = new Source(this.headerContentNode.firstChild.rows[0], { + horizontal: true, + accept: [ "gridColumn_" + this.grid.id ], + viewIndex: this.index, + generateText: false, + onMouseDown: lang.hitch(this, function(e){ + this.header.decorateEvent(e); + if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) && + this.header.canResize(e) && !this.header.moveable){ + this.header.beginColumnResize(e); + }else{ + if(this.grid.headerMenu){ + this.grid.headerMenu.onCancel(true); + } + // IE reports a left click as 1, where everything else reports 0 + if(e.button === (has("ie") < 9 ? 1 : 0)){ + Source.prototype.onMouseDown.call(this.source, e); + } + } + }), + onMouseOver: lang.hitch(this, function(e){ + var src = this.source; + if(src._getChildByEvent(e)){ + Source.prototype.onMouseOver.apply(src, arguments); + } + }), + _markTargetAnchor: lang.hitch(this, function(before){ + var src = this.source; + if(src.current == src.targetAnchor && src.before == before){ return; } + if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){ + src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before"); + } + Source.prototype._markTargetAnchor.call(src, before); + + var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before); + var endAdd = 0; + + if (!target) { + target = src.targetAnchor; + endAdd = html.contentBox(target).w + this.arrowDim.w/2 + 2; + } + + var pos = html.position(target, true); + var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd); + + html.style(this.bottomMarker, "visibility", "visible"); + html.style(this.topMarker, "visibility", "visible"); + html.style(this.bottomMarker, { + "left": left + "px", + "top" : (headerHeight + pos.y) + "px" + }); + + html.style(this.topMarker, { + "left": left + "px", + "top" : (pos.y - this.arrowDim.h) + "px" + }); + + if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){ + src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before"); + } + }), + _unmarkTargetAnchor: lang.hitch(this, function(){ + var src = this.source; + if(!src.targetAnchor){ return; } + if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){ + src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before"); + } + this._hide(this.bottomMarker); + this._hide(this.topMarker); + Source.prototype._unmarkTargetAnchor.call(src); + }), + destroy: lang.hitch(this, function(){ + connect.disconnect(this._source_conn); + connect.unsubscribe(this._source_sub); + Source.prototype.destroy.call(this.source); + if(this.bottomMarker){ + html.destroy(this.bottomMarker); + delete this.bottomMarker; + } + if(this.topMarker){ + html.destroy(this.topMarker); + delete this.topMarker; + } + }), + onDndCancel: lang.hitch(this, function(){ + Source.prototype.onDndCancel.call(this.source); + this._hide(this.bottomMarker); + this._hide(this.topMarker); + }) + }); + + this._source_conn = connect.connect(this.source, "onDndDrop", this, "_onDndDrop"); + this._source_sub = connect.subscribe("/dnd/drop/before", this, "_onDndDropBefore"); + this.source.startup(); + } + }, + + _hide: function(node){ + html.style(node, { + top: "-10000px", + "visibility": "hidden" + }); + }, + + _onDndDropBefore: function(source, nodes, copy){ + if(dojo.dnd.manager().target !== this.source){ + return; + } + this.source._targetNode = this.source.targetAnchor; + this.source._beforeTarget = this.source.before; + var views = this.grid.views.views; + var srcView = views[source.viewIndex]; + var tgtView = views[this.index]; + if(tgtView != srcView){ + srcView.convertColPctToFixed(); + tgtView.convertColPctToFixed(); + } + }, + + _onDndDrop: function(source, nodes, copy){ + if(dojo.dnd.manager().target !== this.source){ + if(dojo.dnd.manager().source === this.source){ + this._removingColumn = true; + } + return; + } + this._hide(this.bottomMarker); + this._hide(this.topMarker); + + var getIdx = function(n){ + return n ? html.attr(n, "idx") : null; + }; + var w = html.marginBox(nodes[0]).w; + if(source.viewIndex !== this.index){ + var views = this.grid.views.views; + var srcView = views[source.viewIndex]; + var tgtView = views[this.index]; + if(srcView.viewWidth && srcView.viewWidth != "auto"){ + srcView.setColumnsWidth(srcView.getColumnsWidth() - w); + } + if(tgtView.viewWidth && tgtView.viewWidth != "auto"){ + tgtView.setColumnsWidth(tgtView.getColumnsWidth()); + } + } + var stn = this.source._targetNode; + var stb = this.source._beforeTarget; + !this.grid.isLeftToRight() && (stb = !stb); + var layout = this.grid.layout; + var idx = this.index; + delete this.source._targetNode; + delete this.source._beforeTarget; + + layout.moveColumn( + source.viewIndex, + idx, + getIdx(nodes[0]), + getIdx(stn), + stb); + }, + + renderHeader: function(){ + this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent); + if(this.flexCells){ + this.contentWidth = this.getContentWidth(); + this.headerContentNode.firstChild.style.width = this.contentWidth; + } + util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]); + }, + + // note: not called in 'view' context + _getHeaderContent: function(inCell){ + var n = inCell.name || inCell.grid.getCellName(inCell); + if(/^\s+$/.test(n)){ + n = ' '//otherwise arrow styles will be messed up + } + var ret = [ '<div class="dojoxGridSortNode' ]; + + if(inCell.index != inCell.grid.getSortIndex()){ + ret.push('">'); + }else{ + ret = ret.concat([ ' ', + inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown', + '"><div class="dojoxGridArrowButtonChar">', + inCell.grid.sortInfo > 0 ? '▲' : '▼', + '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>', + '<div class="dojoxGridColCaption">']); + } + ret = ret.concat([n, '</div></div>']); + return ret.join(''); + }, + + resize: function(){ + this.adaptHeight(); + this.adaptWidth(); + }, + + hasHScrollbar: function(reset){ + var hadScroll = this._hasHScroll||false; + if(this._hasHScroll == undefined || reset){ + if(this.noscroll){ + this._hasHScroll = false; + }else{ + var style = html.style(this.scrollboxNode, "overflow"); + if(style == "hidden"){ + this._hasHScroll = false; + }else if(style == "scroll"){ + this._hasHScroll = true; + }else{ + this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth ); + } + } + } + if(hadScroll !== this._hasHScroll){ + this.grid.update(); + } + return this._hasHScroll; // Boolean + }, + + hasVScrollbar: function(reset){ + var hadScroll = this._hasVScroll||false; + if(this._hasVScroll == undefined || reset){ + if(this.noscroll){ + this._hasVScroll = false; + }else{ + var style = html.style(this.scrollboxNode, "overflow"); + if(style == "hidden"){ + this._hasVScroll = false; + }else if(style == "scroll"){ + this._hasVScroll = true; + }else{ + this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight); + } + } + } + if(hadScroll !== this._hasVScroll){ + this.grid.update(); + } + return this._hasVScroll; // Boolean + }, + + convertColPctToFixed: function(){ + // Fix any percentage widths to be pixel values + var hasPct = false; + this.grid.initialWidth = ""; + var cellNodes = query("th", this.headerContentNode); + var fixedWidths = array.map(cellNodes, function(c, vIdx){ + var w = c.style.width; + html.attr(c, "vIdx", vIdx); + if(w && w.slice(-1) == "%"){ + hasPct = true; + }else if(w && w.slice(-2) == "px"){ + return window.parseInt(w, 10); + } + return html.contentBox(c).w; + }); + if(hasPct){ + array.forEach(this.grid.layout.cells, function(cell, idx){ + if(cell.view == this){ + var cellNode = cell.view.getHeaderCellNode(cell.index); + if(cellNode && html.hasAttr(cellNode, "vIdx")){ + var vIdx = window.parseInt(html.attr(cellNode, "vIdx")); + this.setColWidth(idx, fixedWidths[vIdx]); + html.removeAttr(cellNode, "vIdx"); + } + } + }, this); + return true; + } + return false; + }, + + adaptHeight: function(minusScroll){ + if(!this.grid._autoHeight){ + var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight; + var self = this; + var checkOtherViewScrollers = function(){ + var v; + for(var i in self.grid.views.views){ + v = self.grid.views.views[i]; + if(v !== self && v.hasHScrollbar()){ + return true; + } + } + return false; + }; + if(minusScroll || (this.noscroll && checkOtherViewScrollers())){ + h -= metrics.getScrollbar().h; + } + util.setStyleHeightPx(this.scrollboxNode, h); + } + this.hasVScrollbar(true); + }, + + adaptWidth: function(){ + if(this.flexCells){ + // the view content width + this.contentWidth = this.getContentWidth(); + this.headerContentNode.firstChild.style.width = this.contentWidth; + } + // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth, + // but clientWidth seemingly does not include scrollbar width in some cases + var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth(); + if(!this._removingColumn){ + w = Math.max(w, this.getColumnsWidth()) + 'px'; + }else{ + w = Math.min(w, this.getColumnsWidth()) + 'px'; + this._removingColumn = false; + } + var cn = this.contentNode; + cn.style.width = w; + this.hasHScrollbar(true); + }, + + setSize: function(w, h){ + var ds = this.domNode.style; + var hs = this.headerNode.style; + + if(w){ + ds.width = w; + hs.width = w; + } + ds.height = (h >= 0 ? h + 'px' : ''); + }, + + renderRow: function(inRowIndex){ + var rowNode = this.createRowNode(inRowIndex); + this.buildRow(inRowIndex, rowNode); + //this.grid.edit.restore(this, inRowIndex); + return rowNode; + }, + + createRowNode: function(inRowIndex){ + var node = document.createElement("div"); + node.className = this.classTag + 'Row'; + if (this instanceof dojox.grid._RowSelector){ + html.attr(node,"role","presentation"); + }else{ + html.attr(node,"role","row"); + if (this.grid.selectionMode != "none") { + node.setAttribute("aria-selected", "false"); //rows can be selected so add aria-selected prop + } + } + node[util.gridViewTag] = this.id; + node[util.rowIndexTag] = inRowIndex; + this.rowNodes[inRowIndex] = node; + return node; + }, + + buildRow: function(inRowIndex, inRowNode){ + + this.buildRowContent(inRowIndex, inRowNode); + + this.styleRow(inRowIndex, inRowNode); + + + }, + + buildRowContent: function(inRowIndex, inRowNode){ + inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex); + if(this.flexCells && this.contentWidth){ + // FIXME: accessing firstChild here breaks encapsulation + inRowNode.firstChild.style.width = this.contentWidth; + } + util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]); + }, + + rowRemoved:function(inRowIndex){ + if(inRowIndex >= 0){ + this._cleanupRowWidgets(this.getRowNode(inRowIndex)); + } + this.grid.edit.save(this, inRowIndex); + delete this.rowNodes[inRowIndex]; + }, + + getRowNode: function(inRowIndex){ + return this.rowNodes[inRowIndex]; + }, + + getCellNode: function(inRowIndex, inCellIndex){ + var row = this.getRowNode(inRowIndex); + if(row){ + return this.content.getCellNode(row, inCellIndex); + } + }, + + getHeaderCellNode: function(inCellIndex){ + if(this.headerContentNode){ + return this.header.getCellNode(this.headerContentNode, inCellIndex); + } + }, + + // styling + styleRow: function(inRowIndex, inRowNode){ + inRowNode._style = getStyleText(inRowNode); + this.styleRowNode(inRowIndex, inRowNode); + }, + + styleRowNode: function(inRowIndex, inRowNode){ + if(inRowNode){ + this.doStyleRowNode(inRowIndex, inRowNode); + } + }, + + doStyleRowNode: function(inRowIndex, inRowNode){ + this.grid.styleRowNode(inRowIndex, inRowNode); + }, + + // updating + updateRow: function(inRowIndex){ + var rowNode = this.getRowNode(inRowIndex); + if(rowNode){ + rowNode.style.height = ''; + this.buildRow(inRowIndex, rowNode); + } + return rowNode; + }, + + updateRowStyles: function(inRowIndex){ + this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex)); + }, + + // scrolling + lastTop: 0, + firstScroll:0, + + doscroll: function(inEvent){ + //var s = dojo.marginBox(this.headerContentNode.firstChild); + var isLtr = this.grid.isLeftToRight(); + if(this.firstScroll < 2){ + if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){ + var s = html.marginBox(this.headerNodeContainer); + if(has("ie")){ + this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px'; + }else if(has("mozilla")){ + //TODO currently only for FF, not sure for safari and opera + this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px'; + //this.headerNodeContainer.style.width = s.w + 'px'; + //set scroll to right in FF + this.scrollboxNode.scrollLeft = isLtr ? + this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth : + this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth; + } + } + this.firstScroll++; + } + this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft; + // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below + var top = this.scrollboxNode.scrollTop; + if(top !== this.lastTop){ + this.grid.scrollTo(top); + } + }, + + setScrollTop: function(inTop){ + // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above + this.lastTop = inTop; + this.scrollboxNode.scrollTop = inTop; + return this.scrollboxNode.scrollTop; + }, + + // event handlers (direct from DOM) + doContentEvent: function(e){ + if(this.content.decorateEvent(e)){ + this.grid.onContentEvent(e); + } + }, + + doHeaderEvent: function(e){ + if(this.header.decorateEvent(e)){ + this.grid.onHeaderEvent(e); + } + }, + + // event dispatch(from Grid) + dispatchContentEvent: function(e){ + return this.content.dispatchEvent(e); + }, + + dispatchHeaderEvent: function(e){ + return this.header.dispatchEvent(e); + }, + + // column resizing + setColWidth: function(inIndex, inWidth){ + this.grid.setCellWidth(inIndex, inWidth + 'px'); + }, + + update: function(){ + if(!this.domNode){ + return; + } + this.content.update(); + this.grid.update(); + //get scroll after update or scroll left setting goes wrong on IE. + //See trac: #8040 + var left = this.scrollboxNode.scrollLeft; + this.scrollboxNode.scrollLeft = left; + this.headerNode.scrollLeft = left; + } + }); + + var _GridAvatar = declare("dojox.grid._GridAvatar", Avatar, { + construct: function(){ + var dd = win.doc; + + var a = dd.createElement("table"); + a.cellPadding = a.cellSpacing = "0"; + a.className = "dojoxGridDndAvatar"; + a.style.position = "absolute"; + a.style.zIndex = 1999; + a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins + var b = dd.createElement("tbody"); + var tr = dd.createElement("tr"); + var td = dd.createElement("td"); + var img = dd.createElement("td"); + tr.className = "dojoxGridDndAvatarItem"; + img.className = "dojoxGridDndAvatarItemImage"; + img.style.width = "16px"; + var source = this.manager.source, node; + if(source.creator){ + // create an avatar representation of the node + node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node; + }else{ + // or just clone the node and hope it works + node = this.manager.nodes[0].cloneNode(true); + var table, tbody; + if(node.tagName.toLowerCase() == "tr"){ + // insert extra table nodes + table = dd.createElement("table"); + tbody = dd.createElement("tbody"); + tbody.appendChild(node); + table.appendChild(tbody); + node = table; + }else if(node.tagName.toLowerCase() == "th"){ + // insert extra table nodes + table = dd.createElement("table"); + tbody = dd.createElement("tbody"); + var r = dd.createElement("tr"); + table.cellPadding = table.cellSpacing = "0"; + r.appendChild(node); + tbody.appendChild(r); + table.appendChild(tbody); + node = table; + } + } + node.id = ""; + td.appendChild(node); + tr.appendChild(img); + tr.appendChild(td); + html.style(tr, "opacity", 0.9); + b.appendChild(tr); + + a.appendChild(b); + this.node = a; + + var m = dojo.dnd.manager(); + this.oldOffsetY = m.OFFSET_Y; + m.OFFSET_Y = 1; + }, + destroy: function(){ + dojo.dnd.manager().OFFSET_Y = this.oldOffsetY; + this.inherited(arguments); + } + }); + + var oldMakeAvatar = dojo.dnd.manager().makeAvatar; + dojo.dnd.manager().makeAvatar = function(){ + var src = this.source; + if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){ + return new _GridAvatar(this); + } + return oldMakeAvatar.call(dojo.dnd.manager()); + }; + + return _View; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/_ViewManager.js b/js/dojo-1.7.2/dojox/grid/_ViewManager.js new file mode 100644 index 0000000..b9e06b7 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/_ViewManager.js @@ -0,0 +1,307 @@ +//>>built +define("dojox/grid/_ViewManager", [ + "dojo/_base/declare", + "dojo/_base/sniff", + "dojo/dom-class" +], function(declare, has, domClass){ + +return declare('dojox.grid._ViewManager', null, { + // summary: + // A collection of grid views. Owned by grid and used internally for managing grid views. + // description: + // Grid creates views automatically based on grid's layout structure. + // Users should typically not need to access individual views or the views collection directly. + constructor: function(inGrid){ + this.grid = inGrid; + }, + + defaultWidth: 200, + + views: [], + + // operations + resize: function(){ + this.onEach("resize"); + }, + + render: function(){ + this.onEach("render"); + }, + + // views + addView: function(inView){ + inView.idx = this.views.length; + this.views.push(inView); + }, + + destroyViews: function(){ + for(var i=0, v; v=this.views[i]; i++){ + v.destroy(); + } + this.views = []; + }, + + getContentNodes: function(){ + var nodes = []; + for(var i=0, v; v=this.views[i]; i++){ + nodes.push(v.contentNode); + } + return nodes; + }, + + forEach: function(inCallback){ + for(var i=0, v; v=this.views[i]; i++){ + inCallback(v, i); + } + }, + + onEach: function(inMethod, inArgs){ + inArgs = inArgs || []; + for(var i=0, v; v=this.views[i]; i++){ + if(inMethod in v){ + v[inMethod].apply(v, inArgs); + } + } + }, + + // layout + normalizeHeaderNodeHeight: function(){ + var rowNodes = []; + for(var i=0, v; (v=this.views[i]); i++){ + if(v.headerContentNode.firstChild){ + rowNodes.push(v.headerContentNode); + } + } + this.normalizeRowNodeHeights(rowNodes); + }, + + normalizeRowNodeHeights: function(inRowNodes){ + var h = 0; + var currHeights = []; + if(this.grid.rowHeight){ + h = this.grid.rowHeight; + }else{ + if(inRowNodes.length <= 1){ + // no need to normalize if we are the only one... + return; + } + for(var i=0, n; (n=inRowNodes[i]); i++){ + // We only care about the height - so don't use marginBox. This + // depends on the container not having any margin (which it shouldn't) + // Also - we only look up the height if the cell doesn't have the + // dojoxGridNonNormalizedCell class (like for row selectors) + if(!domClass.contains(n, "dojoxGridNonNormalizedCell")){ + currHeights[i] = n.firstChild.offsetHeight; + h = Math.max(h, currHeights[i]); + } + } + h = (h >= 0 ? h : 0); + + //Work around odd FF3 rendering bug: #8864. + //A one px increase fixes FireFox 3's rounding bug for fractional font sizes. + if((has("mozilla") || has("ie") > 8 ) && h){h++;} + } + for(i=0; (n=inRowNodes[i]); i++){ + if(currHeights[i] != h){ + n.firstChild.style.height = h + "px"; + } + } + }, + + resetHeaderNodeHeight: function(){ + for(var i=0, v, n; (v=this.views[i]); i++){ + n = v.headerContentNode.firstChild; + if(n){ + n.style.height = ""; + } + } + }, + + renormalizeRow: function(inRowIndex){ + var rowNodes = []; + for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){ + n.firstChild.style.height = ''; + rowNodes.push(n); + } + this.normalizeRowNodeHeights(rowNodes); + }, + + getViewWidth: function(inIndex){ + return this.views[inIndex].getWidth() || this.defaultWidth; + }, + + // must be called after view widths are properly set or height can be miscalculated + // if there are flex columns + measureHeader: function(){ + // need to reset view header heights so they are properly measured. + this.resetHeaderNodeHeight(); + this.forEach(function(inView){ + inView.headerContentNode.style.height = ''; + }); + var h = 0; + // calculate maximum view header height + this.forEach(function(inView){ + h = Math.max(inView.headerNode.offsetHeight, h); + }); + return h; + }, + + measureContent: function(){ + var h = 0; + this.forEach(function(inView){ + h = Math.max(inView.domNode.offsetHeight, h); + }); + return h; + }, + + findClient: function(inAutoWidth){ + // try to use user defined client + var c = this.grid.elasticView || -1; + // attempt to find implicit client + if(c < 0){ + for(var i=1, v; (v=this.views[i]); i++){ + if(v.viewWidth){ + for(i=1; (v=this.views[i]); i++){ + if(!v.viewWidth){ + c = i; + break; + } + } + break; + } + } + } + // client is in the middle by default + if(c < 0){ + c = Math.floor(this.views.length / 2); + } + return c; + }, + + arrange: function(l, w){ + var i, v, vw, len = this.views.length, self = this; + // find the client + var c = (w <= 0 ? len : this.findClient()); + // layout views + var setPosition = function(v, l){ + var ds = v.domNode.style; + var hs = v.headerNode.style; + + if(!self.grid.isLeftToRight()){ + ds.right = l + 'px'; + // fixed rtl, the scrollbar is on the right side in FF or WebKit + if (has("ff") < 4 || has("webkit")){ + hs.right = l + v.getScrollbarWidth() + 'px'; + hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px'; + }else{ + hs.right = l + 'px'; + } + }else{ + ds.left = l + 'px'; + hs.left = l + 'px'; + } + ds.top = 0 + 'px'; + hs.top = 0; + }; + // for views left of the client + //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with + //leading and tailing concept. + for(i=0; (v=this.views[i])&&(i<c); i++){ + // get width + vw = this.getViewWidth(i); + // process boxes + v.setSize(vw, 0); + setPosition(v, l); + if(v.headerContentNode && v.headerContentNode.firstChild){ + vw = v.getColumnsWidth()+v.getScrollbarWidth(); + }else{ + vw = v.domNode.offsetWidth; + } + // update position + l += vw; + } + // next view (is the client, i++ == c) + i++; + // start from the right edge + var r = w; + // for views right of the client (iterated from the right) + for(var j=len-1; (v=this.views[j])&&(i<=j); j--){ + // get width + vw = this.getViewWidth(j); + // set size + v.setSize(vw, 0); + // measure in pixels + vw = v.domNode.offsetWidth; + // update position + r -= vw; + // set position + setPosition(v, r); + } + if(c<len){ + v = this.views[c]; + // position the client box between left and right boxes + vw = Math.max(1, r-l); + // set size + v.setSize(vw + 'px', 0); + setPosition(v, l); + } + return l; + }, + + // rendering + renderRow: function(inRowIndex, inNodes, skipRenorm){ + var rowNodes = []; + for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){ + rowNode = v.renderRow(inRowIndex); + n.appendChild(rowNode); + rowNodes.push(rowNode); + } + if(!skipRenorm){ + this.normalizeRowNodeHeights(rowNodes); + } + }, + + rowRemoved: function(inRowIndex){ + this.onEach("rowRemoved", [ inRowIndex ]); + }, + + // updating + updateRow: function(inRowIndex, skipRenorm){ + for(var i=0, v; v=this.views[i]; i++){ + v.updateRow(inRowIndex); + } + if(!skipRenorm){ + this.renormalizeRow(inRowIndex); + } + }, + + updateRowStyles: function(inRowIndex){ + this.onEach("updateRowStyles", [ inRowIndex ]); + }, + + // scrolling + setScrollTop: function(inTop){ + var top = inTop; + for(var i=0, v; v=this.views[i]; i++){ + top = v.setScrollTop(inTop); + // Work around IE not firing scroll events that cause header offset + // issues to occur. + if(has("ie") && v.headerNode && v.scrollboxNode){ + v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft; + } + } + return top; + //this.onEach("setScrollTop", [ inTop ]); + }, + + getFirstScrollingView: function(){ + // summary: Returns the first grid view with a scroll bar + for(var i=0, v; (v=this.views[i]); i++){ + if(v.hasHScrollbar() || v.hasVScrollbar()){ + return v; + } + } + return null; + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/cells.js b/js/dojo-1.7.2/dojox/grid/cells.js new file mode 100644 index 0000000..2c2a502 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/cells.js @@ -0,0 +1,4 @@ +//>>built +define("dojox/grid/cells", ["../main", "./cells/_base"], function(dojox){ + return dojox.grid.cells; +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/cells/_base.js b/js/dojo-1.7.2/dojox/grid/cells/_base.js new file mode 100644 index 0000000..a1731ef --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/cells/_base.js @@ -0,0 +1,477 @@ +//>>built +define("dojox/grid/cells/_base", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/event", + "dojo/_base/connect", + "dojo/_base/array", + "dojo/_base/sniff", + "dojo/dom", + "dojo/dom-attr", + "dojo/dom-construct", + "dijit/_Widget", + "../util" +], function(dojo, declare, lang, event, connect, array, has, dom, domAttr, domConstruct, _Widget, util){ + + var _DeferredTextWidget = declare("dojox.grid._DeferredTextWidget", _Widget, { + deferred: null, + _destroyOnRemove: true, + postCreate: function(){ + if(this.deferred){ + this.deferred.addBoth(lang.hitch(this, function(text){ + if(this.domNode){ + this.domNode.innerHTML = text; + } + })); + } + } + }); + + var focusSelectNode = function(inNode){ + try{ + util.fire(inNode, "focus"); + util.fire(inNode, "select"); + }catch(e){// IE sux bad + } + }; + + var whenIdle = function(/*inContext, inMethod, args ...*/){ + setTimeout(lang.hitch.apply(dojo, arguments), 0); + }; + + var BaseCell = declare("dojox.grid.cells._Base", null, { + // summary: + // Respresents a grid cell and contains information about column options and methods + // for retrieving cell related information. + // Each column in a grid layout has a cell object and most events and many methods + // provide access to these objects. + styles: '', + classes: '', + editable: false, + alwaysEditing: false, + formatter: null, + defaultValue: '...', + value: null, + hidden: false, + noresize: false, + draggable: true, + //private + _valueProp: "value", + _formatPending: false, + + constructor: function(inProps){ + this._props = inProps || {}; + lang.mixin(this, inProps); + if(this.draggable === undefined){ + this.draggable = true; + } + }, + + _defaultFormat: function(inValue, callArgs){ + var s = this.grid.formatterScope || this; + var f = this.formatter; + if(f && s && typeof f == "string"){ + f = this.formatter = s[f]; + } + var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue; + if(typeof v == "undefined"){ + return this.defaultValue; + } + if(v && v.addBoth){ + // Check if it's a deferred + v = new _DeferredTextWidget({deferred: v}, + domConstruct.create("span", {innerHTML: this.defaultValue})); + } + if(v && v.declaredClass && v.startup){ + return "<div class='dojoxGridStubNode' linkWidget='" + + v.id + + "' cellIdx='" + + this.index + + "'>" + + this.defaultValue + + "</div>"; + } + return v; + }, + + // data source + format: function(inRowIndex, inItem){ + // summary: + // provides the html for a given grid cell. + // inRowIndex: int + // grid row index + // returns: html for a given grid cell + var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue); + d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&').replace(/</g, '<') : d; + if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){ + return this.formatEditing(d, inRowIndex); + }else{ + return this._defaultFormat(d, [d, inRowIndex, this]); + } + }, + formatEditing: function(inDatum, inRowIndex){ + // summary: + // formats the cell for editing + // inDatum: anything + // cell data to edit + // inRowIndex: int + // grid row index + // returns: string of html to place in grid cell + }, + // utility + getNode: function(inRowIndex){ + // summary: + // gets the dom node for a given grid cell. + // inRowIndex: int + // grid row index + // returns: dom node for a given grid cell + return this.view.getCellNode(inRowIndex, this.index); + }, + getHeaderNode: function(){ + return this.view.getHeaderCellNode(this.index); + }, + getEditNode: function(inRowIndex){ + return (this.getNode(inRowIndex) || 0).firstChild || 0; + }, + canResize: function(){ + var uw = this.unitWidth; + return uw && (uw!=='auto'); + }, + isFlex: function(){ + var uw = this.unitWidth; + return uw && lang.isString(uw) && (uw=='auto' || uw.slice(-1)=='%'); + }, + // edit support + applyEdit: function(inValue, inRowIndex){ + this.grid.edit.applyCellEdit(inValue, this, inRowIndex); + }, + cancelEdit: function(inRowIndex){ + this.grid.doCancelEdit(inRowIndex); + }, + _onEditBlur: function(inRowIndex){ + if(this.grid.edit.isEditCell(inRowIndex, this.index)){ + //console.log('editor onblur', e); + this.grid.edit.apply(); + } + }, + registerOnBlur: function(inNode, inRowIndex){ + if(this.commitOnBlur){ + connect.connect(inNode, "onblur", function(e){ + // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid + setTimeout(lang.hitch(this, "_onEditBlur", inRowIndex), 250); + }); + } + }, + //protected + needFormatNode: function(inDatum, inRowIndex){ + this._formatPending = true; + whenIdle(this, "_formatNode", inDatum, inRowIndex); + }, + cancelFormatNode: function(){ + this._formatPending = false; + }, + //private + _formatNode: function(inDatum, inRowIndex){ + if(this._formatPending){ + this._formatPending = false; + // make cell selectable + if(!has("ie")){ + dom.setSelectable(this.grid.domNode, true); + } + this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex); + } + }, + //protected + formatNode: function(inNode, inDatum, inRowIndex){ + // summary: + // format the editing dom node. Use when editor is a widget. + // inNode: dom node + // dom node for the editor + // inDatum: anything + // cell data to edit + // inRowIndex: int + // grid row index + if(has("ie")){ + // IE sux bad + whenIdle(this, "focus", inRowIndex, inNode); + }else{ + this.focus(inRowIndex, inNode); + } + }, + dispatchEvent: function(m, e){ + if(m in this){ + return this[m](e); + } + }, + //public + getValue: function(inRowIndex){ + // summary: + // returns value entered into editor + // inRowIndex: int + // grid row index + // returns: + // value of editor + return this.getEditNode(inRowIndex)[this._valueProp]; + }, + setValue: function(inRowIndex, inValue){ + // summary: + // set the value of the grid editor + // inRowIndex: int + // grid row index + // inValue: anything + // value of editor + var n = this.getEditNode(inRowIndex); + if(n){ + n[this._valueProp] = inValue; + } + }, + focus: function(inRowIndex, inNode){ + // summary: + // focus the grid editor + // inRowIndex: int + // grid row index + // inNode: dom node + // editor node + focusSelectNode(inNode || this.getEditNode(inRowIndex)); + }, + save: function(inRowIndex){ + // summary: + // save editor state + // inRowIndex: int + // grid row index + this.value = this.value || this.getValue(inRowIndex); + //console.log("save", this.value, inCell.index, inRowIndex); + }, + restore: function(inRowIndex){ + // summary: + // restore editor state + // inRowIndex: int + // grid row index + this.setValue(inRowIndex, this.value); + //console.log("restore", this.value, inCell.index, inRowIndex); + }, + //protected + _finish: function(inRowIndex){ + // summary: + // called when editing is completed to clean up editor + // inRowIndex: int + // grid row index + dom.setSelectable(this.grid.domNode, false); + this.cancelFormatNode(); + }, + //public + apply: function(inRowIndex){ + // summary: + // apply edit from cell editor + // inRowIndex: int + // grid row index + this.applyEdit(this.getValue(inRowIndex), inRowIndex); + this._finish(inRowIndex); + }, + cancel: function(inRowIndex){ + // summary: + // cancel cell edit + // inRowIndex: int + // grid row index + this.cancelEdit(inRowIndex); + this._finish(inRowIndex); + } + }); + BaseCell.markupFactory = function(node, cellDef){ + var formatter = lang.trim(domAttr.get(node, "formatter")||""); + if(formatter){ + cellDef.formatter = lang.getObject(formatter)||formatter; + } + var get = lang.trim(domAttr.get(node, "get")||""); + if(get){ + cellDef.get = lang.getObject(get); + } + var getBoolAttr = function(attr, cell, cellAttr){ + var value = lang.trim(domAttr.get(node, attr)||""); + if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); } + }; + getBoolAttr("sortDesc", cellDef); + getBoolAttr("editable", cellDef); + getBoolAttr("alwaysEditing", cellDef); + getBoolAttr("noresize", cellDef); + getBoolAttr("draggable", cellDef); + + var value = lang.trim(domAttr.get(node, "loadingText")||domAttr.get(node, "defaultValue")||""); + if(value){ + cellDef.defaultValue = value; + } + + var getStrAttr = function(attr, cell, cellAttr){ + var value = lang.trim(domAttr.get(node, attr)||"")||undefined; + if(value){ cell[cellAttr||attr] = value; } + }; + getStrAttr("styles", cellDef); + getStrAttr("headerStyles", cellDef); + getStrAttr("cellStyles", cellDef); + getStrAttr("classes", cellDef); + getStrAttr("headerClasses", cellDef); + getStrAttr("cellClasses", cellDef); + }; + + var Cell = declare("dojox.grid.cells.Cell", BaseCell, { + // summary + // grid cell that provides a standard text input box upon editing + constructor: function(){ + this.keyFilter = this.keyFilter; + }, + // keyFilter: RegExp + // optional regex for disallowing keypresses + keyFilter: null, + formatEditing: function(inDatum, inRowIndex){ + this.needFormatNode(inDatum, inRowIndex); + return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">'; + }, + formatNode: function(inNode, inDatum, inRowIndex){ + this.inherited(arguments); + // FIXME: feels too specific for this interface + this.registerOnBlur(inNode, inRowIndex); + }, + doKey: function(e){ + if(this.keyFilter){ + var key = String.fromCharCode(e.charCode); + if(key.search(this.keyFilter) == -1){ + event.stop(e); + } + } + }, + _finish: function(inRowIndex){ + this.inherited(arguments); + var n = this.getEditNode(inRowIndex); + try{ + util.fire(n, "blur"); + }catch(e){} + } + }); + Cell.markupFactory = function(node, cellDef){ + BaseCell.markupFactory(node, cellDef); + var keyFilter = lang.trim(domAttr.get(node, "keyFilter")||""); + if(keyFilter){ + cellDef.keyFilter = new RegExp(keyFilter); + } + }; + + var RowIndex = declare("dojox.grid.cells.RowIndex", Cell, { + name: 'Row', + + postscript: function(){ + this.editable = false; + }, + get: function(inRowIndex){ + return inRowIndex + 1; + } + }); + RowIndex.markupFactory = function(node, cellDef){ + Cell.markupFactory(node, cellDef); + }; + + var Select = declare("dojox.grid.cells.Select", Cell, { + // summary: + // grid cell that provides a standard select for editing + + // options: Array + // text of each item + options: null, + + // values: Array + // value for each item + values: null, + + // returnIndex: Integer + // editor returns only the index of the selected option and not the value + returnIndex: -1, + + constructor: function(inCell){ + this.values = this.values || this.options; + }, + formatEditing: function(inDatum, inRowIndex){ + this.needFormatNode(inDatum, inRowIndex); + var h = [ '<select class="dojoxGridSelect">' ]; + for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){ + v = v.replace ? v.replace(/&/g, '&').replace(/</g, '<') : v; + o = o.replace ? o.replace(/&/g, '&').replace(/</g, '<') : o; + h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>"); + } + h.push('</select>'); + return h.join(''); + }, + _defaultFormat: function(inValue, callArgs){ + var v = this.inherited(arguments); + // when 'values' and 'options' both provided and there is no cutomized formatter, + // then we use 'options' as label in order to be consistent + if(!this.formatter && this.values && this.options){ + var i = array.indexOf(this.values, v); + if(i >= 0){ + v = this.options[i]; + } + } + return v; + }, + getValue: function(inRowIndex){ + var n = this.getEditNode(inRowIndex); + if(n){ + var i = n.selectedIndex, o = n.options[i]; + return this.returnIndex > -1 ? i : o.value || o.innerHTML; + } + } + }); + Select.markupFactory = function(node, cell){ + Cell.markupFactory(node, cell); + var options = lang.trim(domAttr.get(node, "options")||""); + if(options){ + var o = options.split(','); + if(o[0] != options){ + cell.options = o; + } + } + var values = lang.trim(domAttr.get(node, "values")||""); + if(values){ + var v = values.split(','); + if(v[0] != values){ + cell.values = v; + } + } + }; + + var AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, { + // summary: + // grid cell that is always in an editable state, regardless of grid editing state + alwaysEditing: true, + _formatNode: function(inDatum, inRowIndex){ + this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex); + }, + applyStaticValue: function(inRowIndex){ + var e = this.grid.edit; + e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex); + e.start(this, inRowIndex, true); + } + }); + AlwaysEdit.markupFactory = function(node, cell){ + Cell.markupFactory(node, cell); + }; + + var Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, { + // summary: + // grid cell that provides a standard checkbox that is always on for editing + _valueProp: "checked", + formatEditing: function(inDatum, inRowIndex){ + return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />'; + }, + doclick: function(e){ + if(e.target.tagName == 'INPUT'){ + this.applyStaticValue(e.rowIndex); + } + } + }); + Bool.markupFactory = function(node, cell){ + AlwaysEdit.markupFactory(node, cell); + }; + + return BaseCell; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/cells/dijit.js b/js/dojo-1.7.2/dojox/grid/cells/dijit.js new file mode 100644 index 0000000..502c4d2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/cells/dijit.js @@ -0,0 +1,256 @@ +//>>built +define("dojox/grid/cells/dijit", [ + "dojo/_base/kernel", + "../../main", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/json", + "dojo/_base/connect", + "dojo/_base/sniff", + "dojo/dom", + "dojo/dom-attr", + "dojo/dom-construct", + "dojo/dom-geometry", + "dojo/data/ItemFileReadStore", + "dijit/form/DateTextBox", + "dijit/form/TimeTextBox", + "dijit/form/ComboBox", + "dijit/form/CheckBox", + "dijit/form/TextBox", + "dijit/form/NumberSpinner", + "dijit/form/NumberTextBox", + "dijit/form/CurrencyTextBox", + "dijit/form/HorizontalSlider", + "dijit/Editor", + "../util", + "./_base" +], function(dojo, dojox, declare, array, lang, json, connect, has, dom, domAttr, domConstruct, + domGeometry, ItemFileReadStore, DateTextBox, TimeTextBox, ComboBox, CheckBox, TextBox, + NumberSpinner, NumberTextBox, CurrencyTextBox, HorizontalSlider, Editor, util, BaseCell){ + +// TODO: shouldn't it be the test file's job to require these modules, +// if it is using them? Most of these modules aren't referenced by this file. + + var _Widget = declare("dojox.grid.cells._Widget", BaseCell, { + widgetClass: TextBox, + constructor: function(inCell){ + this.widget = null; + if(typeof this.widgetClass == "string"){ + dojo.deprecated("Passing a string to widgetClass is deprecated", "pass the widget class object instead", "2.0"); + this.widgetClass = lang.getObject(this.widgetClass); + } + }, + formatEditing: function(inDatum, inRowIndex){ + this.needFormatNode(inDatum, inRowIndex); + return "<div></div>"; + }, + getValue: function(inRowIndex){ + return this.widget.get('value'); + }, + _unescapeHTML: function(value){ + return (value && value.replace && this.grid.escapeHTMLInData) ? + value.replace(/</g, '<').replace(/&/g, '&') : value; + }, + setValue: function(inRowIndex, inValue){ + if(this.widget&&this.widget.set){ + inValue = this._unescapeHTML(inValue); + //Look for lazy-loading editor and handle it via its deferred. + if(this.widget.onLoadDeferred){ + var self = this; + this.widget.onLoadDeferred.addCallback(function(){ + self.widget.set("value",inValue===null?"":inValue); + }); + }else{ + this.widget.set("value", inValue); + } + }else{ + this.inherited(arguments); + } + }, + getWidgetProps: function(inDatum){ + return lang.mixin( + { + dir: this.dir, + lang: this.lang + }, + this.widgetProps||{}, + { + constraints: lang.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes + value: this._unescapeHTML(inDatum) + } + ); + }, + createWidget: function(inNode, inDatum, inRowIndex){ + return new this.widgetClass(this.getWidgetProps(inDatum), inNode); + }, + attachWidget: function(inNode, inDatum, inRowIndex){ + inNode.appendChild(this.widget.domNode); + this.setValue(inRowIndex, inDatum); + }, + formatNode: function(inNode, inDatum, inRowIndex){ + if(!this.widgetClass){ + return inDatum; + } + if(!this.widget){ + this.widget = this.createWidget.apply(this, arguments); + }else{ + this.attachWidget.apply(this, arguments); + } + this.sizeWidget.apply(this, arguments); + this.grid.views.renormalizeRow(inRowIndex); + this.grid.scroller.rowHeightChanged(inRowIndex, true/*fix #11101*/); + this.focus(); + return undefined; + }, + sizeWidget: function(inNode, inDatum, inRowIndex){ + var + p = this.getNode(inRowIndex), + box = dojo.contentBox(p); + dojo.marginBox(this.widget.domNode, {w: box.w}); + }, + focus: function(inRowIndex, inNode){ + if(this.widget){ + setTimeout(lang.hitch(this.widget, function(){ + util.fire(this, "focus"); + }), 0); + } + }, + _finish: function(inRowIndex){ + this.inherited(arguments); + util.removeNode(this.widget.domNode); + if(has("ie")){ + dom.setSelectable(this.widget.domNode, true); + } + } + }); + _Widget.markupFactory = function(node, cell){ + BaseCell.markupFactory(node, cell); + var widgetProps = lang.trim(domAttr.get(node, "widgetProps")||""); + var constraint = lang.trim(domAttr.get(node, "constraint")||""); + var widgetClass = lang.trim(domAttr.get(node, "widgetClass")||""); + if(widgetProps){ + cell.widgetProps = json.fromJson(widgetProps); + } + if(constraint){ + cell.constraint = json.fromJson(constraint); + } + if(widgetClass){ + cell.widgetClass = lang.getObject(widgetClass); + } + }; + + var ComboBox = declare("dojox.grid.cells.ComboBox", _Widget, { + widgetClass: ComboBox, + getWidgetProps: function(inDatum){ + var items=[]; + array.forEach(this.options, function(o){ + items.push({name: o, value: o}); + }); + var store = new ItemFileReadStore({data: {identifier:"name", items: items}}); + return lang.mixin({}, this.widgetProps||{}, { + value: inDatum, + store: store + }); + }, + getValue: function(){ + var e = this.widget; + // make sure to apply the displayed value + e.set('displayedValue', e.get('displayedValue')); + return e.get('value'); + } + }); + ComboBox.markupFactory = function(node, cell){ + _Widget.markupFactory(node, cell); + var options = lang.trim(domAttr.get(node, "options")||""); + if(options){ + var o = options.split(','); + if(o[0] != options){ + cell.options = o; + } + } + }; + + var DateTextBox = declare("dojox.grid.cells.DateTextBox", _Widget, { + widgetClass: DateTextBox, + setValue: function(inRowIndex, inValue){ + if(this.widget){ + this.widget.set('value', new Date(inValue)); + }else{ + this.inherited(arguments); + } + }, + getWidgetProps: function(inDatum){ + return lang.mixin(this.inherited(arguments), { + value: new Date(inDatum) + }); + } + }); + DateTextBox.markupFactory = function(node, cell){ + _Widget.markupFactory(node, cell); + }; + + var CheckBox = declare("dojox.grid.cells.CheckBox", _Widget, { + widgetClass: CheckBox, + getValue: function(){ + return this.widget.checked; + }, + setValue: function(inRowIndex, inValue){ + if(this.widget&&this.widget.attributeMap.checked){ + this.widget.set("checked", inValue); + }else{ + this.inherited(arguments); + } + }, + sizeWidget: function(inNode, inDatum, inRowIndex){ + return; + } + }); + CheckBox.markupFactory = function(node, cell){ + _Widget.markupFactory(node, cell); + }; + + var Editor = declare("dojox.grid.cells.Editor", _Widget, { + widgetClass: Editor, + getWidgetProps: function(inDatum){ + return lang.mixin({}, this.widgetProps||{}, { + height: this.widgetHeight || "100px" + }); + }, + createWidget: function(inNode, inDatum, inRowIndex){ + // widget needs its value set after creation + var widget = new this.widgetClass(this.getWidgetProps(inDatum), inNode); + connect.connect(widget, 'onLoad', lang.hitch(this, 'populateEditor')); + return widget; + }, + formatNode: function(inNode, inDatum, inRowIndex){ + this.content = inDatum; + this.inherited(arguments); + if(has("mozilla")){ + // FIXME: seem to need to reopen the editor and display the toolbar + var e = this.widget; + e.open(); + if(this.widgetToolbar){ + domConstruct.place(e.toolbar.domNode, e.editingArea, "before"); + } + } + }, + populateEditor: function(){ + this.widget.set('value', this.content); + this.widget.placeCursorAtEnd(); + } + }); + Editor.markupFactory = function(node, cell){ + _Widget.markupFactory(node, cell); + var h = lang.trim(domAttr.get(node, "widgetHeight")||""); + if(h){ + if((h != "auto")&&(h.substr(-2) != "em")){ + h = parseInt(h, 10)+"px"; + } + cell.widgetHeight = h; + } + }; + + return dojox.grid.cells.dijit; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/cells/tree.js b/js/dojo-1.7.2/dojox/grid/cells/tree.js new file mode 100644 index 0000000..7974a8a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/cells/tree.js @@ -0,0 +1,75 @@ +//>>built +define("dojox/grid/cells/tree", [ + "dojo/_base/kernel", + "../../main", + "dojo/_base/lang", + "../cells" +], function(dojo, dojox, lang){ + +dojox.grid.cells.TreeCell = { + formatAggregate: function(inItem, level, inRowIndexes){ + var f, g=this.grid, i=g.edit.info, + d=g.aggregator ? g.aggregator.getForCell(this, level, inItem, level === this.level ? "cnt" : this.parentCell.aggregate) : (this.value || this.defaultValue); + return this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]); + }, + formatIndexes: function(inRowIndexes, inItem){ + var f, g=this.grid, i=g.edit.info, + d=this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue); + if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndexes[0] && i.cell==this))){ + return this.formatEditing(d, inRowIndexes[0], inRowIndexes); + }else{ + return this._defaultFormat(d, [d, inRowIndexes[0], inRowIndexes, this]); + } + }, + getOpenState: function(itemId){ + var grid = this.grid, store = grid.store, itm = null; + if(store.isItem(itemId)){ + itm = itemId; + itemId = store.getIdentity(itemId); + } + if(!this.openStates){ this.openStates = {}; } + if(typeof itemId != "string" || !(itemId in this.openStates)){ + this.openStates[itemId] = grid.getDefaultOpenState(this, itm); + } + return this.openStates[itemId]; + }, + formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses){ + if(!lang.isArray(inRowIndexes)){ + inRowIndexes = [inRowIndexes]; + } + var result = ""; + if(level > this.level || (level === this.level && summaryRow)){ + cellClasses.push("dojoxGridSpacerCell"); + if(level === this.level){ + cellClasses.push("dojoxGridTotalCell"); + } + result = '<span></span>'; + }else if(level < this.level){ + cellClasses.push("dojoxGridSummaryCell"); + result = '<span class="dojoxGridSummarySpan">' + this.formatAggregate(inItem, level, inRowIndexes) + '</span>'; + }else{ + var ret = ""; + if(this.isCollapsable){ + var store = this.grid.store, id = ""; + if(store.isItem(inItem)){ + id = store.getIdentity(inItem); + } + cellClasses.push("dojoxGridExpandoCell"); + ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._Expando" level="' + level + '" class="dojoxGridExpando"' + + '" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>'; + } + result = ret + this.formatIndexes(inRowIndexes, inItem); + } + + if(this.grid.focus.cell && this.index == this.grid.focus.cell.index && + inRowIndexes.join('/') == this.grid.focus.rowIndex){ + cellClasses.push(this.grid.focus.focusClass); + } + + return result; + } +}; + +return dojox.grid.cells.TreeCell; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/compatGrid.tar.gz b/js/dojo-1.7.2/dojox/grid/compatGrid.tar.gz Binary files differnew file mode 100644 index 0000000..87c39c8 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/compatGrid.tar.gz diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_Events.js b/js/dojo-1.7.2/dojox/grid/enhanced/_Events.js new file mode 100644 index 0000000..c461531 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/_Events.js @@ -0,0 +1,215 @@ +//>>built +define("dojox/grid/enhanced/_Events", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/keys", + "dojo/_base/html", + "dojo/_base/event", + "dojox/grid/_Events" +], function(dojo, declare, keys, html, event, _Events){ + +return declare("dojox.grid.enhanced._Events", null, { + // summary: + // Overwrite some default events of DataGrid + // + // description: + // Methods are copied or replaced for overwriting, this might be refined once + // an overall plugin architecture is set up for DataGrid. + + //_events: Object + // Method map cached from dojox.grid._Events(). + _events: null, + + // headerCellActiveClass: String + // css class to apply to grid header cells when activated(mouse down) + headerCellActiveClass: 'dojoxGridHeaderActive', + + // cellActiveClass: String + // css class to apply to grid content cells when activated(mouse down) + cellActiveClass: 'dojoxGridCellActive', + + // rowActiveClass: String + // css class to apply to grid rows when activated(mouse down) + rowActiveClass: 'dojoxGridRowActive', + + constructor: function(inGrid){ + //TODO - extend dojox.grid._Events rather than mixin for 1.8 + this._events = new _Events(); + //mixin "this" to Grid + inGrid.mixin(inGrid, this); + }, + dokeyup: function(e){ + // summary: + // Grid key up event handler. + // e: Event + // Un-decorated event object + this.focus.currentArea().keyup(e); + }, + onKeyDown: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onKeyDown(); + if(e.altKey || e.metaKey){ return; } + var focus = this.focus; + var editing = this.edit.isEditing(); + switch(e.keyCode){ + case keys.TAB: + if(e.ctrlKey){ return; } + focus.tab(e.shiftKey ? -1:1,e); + break; + case keys.UP_ARROW: + case keys.DOWN_ARROW: + if(editing){ return; } + focus.currentArea().move(e.keyCode == keys.UP_ARROW ? -1 : 1, 0, e); + break; + case keys.LEFT_ARROW: + case keys.RIGHT_ARROW: + if(editing){ return; } + var offset = (e.keyCode == keys.LEFT_ARROW) ? 1 : -1; + if(html._isBodyLtr()){ offset *= -1; } + focus.currentArea().move(0, offset, e); + break; + case keys.F10: + if(this.menus && e.shiftKey){ + this.onRowContextMenu(e); + } + break; + default: + focus.currentArea().keydown(e); + break; + } + }, + //TODO - make the following events more reasonalble - e.g. more accurate conditions + //events for row selectors + domouseup: function(e){ + if(e.cellNode){ + this.onMouseUp(e); + }else{ + this.onRowSelectorMouseUp(e); + } + }, + domousedown: function(e){ + if(!e.cellNode){ + this.onRowSelectorMouseDown(e); + } + }, + onMouseUp: function(e){ + // summary: + // New - Event fired when mouse is up inside grid. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + this[e.rowIndex == -1 ? "onHeaderCellMouseUp" : "onCellMouseUp"](e); + }, + onCellMouseDown: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onCellMouseDown() + html.addClass(e.cellNode, this.cellActiveClass); + html.addClass(e.rowNode, this.rowActiveClass); + }, + onCellMouseUp: function(e){ + // summary: + // New - Event fired when mouse is up inside content cell. + // e: Event + // Decorated event object that contains reference to grid, cell, and rowIndex + html.removeClass(e.cellNode, this.cellActiveClass); + html.removeClass(e.rowNode, this.rowActiveClass); + }, + onCellClick: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onCellClick() + + //invoke dojox.grid._Events.onCellClick() + this._events.onCellClick.call(this, e); + //move mouse events to the focus manager. + this.focus.contentMouseEvent(e);//TODO + }, + onCellDblClick: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onCellDblClick() + if(this.pluginMgr.isFixedCell(e.cell)){ return; } + if(this._click.length > 1 && (!this._click[0] || !this._click[1])){ + this._click[0] = this._click[1] = e; + } + //invoke dojox.grid._Events.onCellDblClick() + this._events.onCellDblClick.call(this, e); + }, + onRowClick: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onRowClick() + this.edit.rowClick(e); + if(!e.cell || !this.plugin('indirectSelection')){ + this.selection.clickSelectEvent(e); + } + }, + onRowContextMenu: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onRowContextMenu() + if(!this.edit.isEditing() && this.menus){ + this.showMenu(e); + } + }, + onSelectedRegionContextMenu: function(e){ + // summary: + // New - Event fired when a selected region context menu is accessed via mouse right click. + // e: Event + // Decorated event object which contains reference to grid and info of selected + // regions(selection type - row|column, selected index - [...]) + if(this.selectedRegionMenu){ + this.selectedRegionMenu._openMyself({ + target: e.target, + coords: e.keyCode !== keys.F10 && "pageX" in e ? { + x: e.pageX, + y: e.pageY + } : null + }); + event.stop(e); + } + }, + onHeaderCellMouseOut: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onHeaderCellMouseOut() + if(e.cellNode){ + html.removeClass(e.cellNode, this.cellOverClass); + html.removeClass(e.cellNode, this.headerCellActiveClass); + } + }, + onHeaderCellMouseDown: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onHeaderCellMouseDown() + if(e.cellNode){//TBD - apply to selection region for nested sorting? + html.addClass(e.cellNode, this.headerCellActiveClass); + } + }, + onHeaderCellMouseUp: function(e){ + // summary: + // New event + if(e.cellNode){ + html.removeClass(e.cellNode, this.headerCellActiveClass); + } + }, + onHeaderCellClick: function(e){ + // summary: + // Overwritten, see dojox.grid._Events.onHeaderCellClick() + //move focus to header. + this.focus.currentArea("header"); + //invoke dojox.grid._Events.onHeaderCellClick() + if(!e.cell.isRowSelector){ + this._events.onHeaderCellClick.call(this, e); + } + //move mouse events to the focus manager. + this.focus.headerMouseEvent(e); + }, + onRowSelectorMouseDown: function(e){ + this.focus.focusArea("rowHeader", e); + }, + + onRowSelectorMouseUp: function(e){}, + + //triggered in _View, see Selector plugin + onMouseUpRow: function(e){ + if(e.rowIndex != -1){ + this.onRowMouseUp(e); + } + }, + onRowMouseUp: function(e){} +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js b/js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js new file mode 100644 index 0000000..872d089 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js @@ -0,0 +1,774 @@ +//>>built +define("dojox/grid/enhanced/_FocusManager", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/event", + "dojo/_base/sniff", + "dojo/_base/html", + "dojo/keys", + "dijit/a11y", + "dijit/focus", + "../_FocusManager" +], function(dojo, lang, declare, array, connect, event, has, html, keys, dijitA11y, dijitFocus, _FocusManager){ + +var _FocusArea = declare("dojox.grid.enhanced._FocusArea", null, { + // summary: + // This is a friend class of _FocusManager +/*===== + // name: string + // Name of this area. + name: "", + + // onFocus: function(event, step) + // Called when this area logically gets focus. + // event: Event object + // May be unavailable, should check before use. + // step: Integer + // The distance in the tab sequence from last focused area to this area. + // returns: + // whether this area is successfully focused. If not, the next area will get focus. + onFocus: function(event, step){return true;}, + + // onBlur: function(event, step) + // Called when this area logically loses focus. + // event: Event object + // May be unavailable, should check before use. + // step: Integer + // The distance in the tab sequence from this area to the area to focus. + // returns: + // If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one. + // If String, means the next area to focus is given by this returned name. + onBlur: function(event, step){return true;}, + + // onMove: function(rowStep, colStep, event) + // Called when focus is moving around within this area. + // rowStep: Integer + // colStep: Integer + // event: Event object + // May be unavailable, should check before use. + onMove: function(rowStep, colStep, event){}, + + // onKey: function(event, isBubble) + // Called when some key is pressed when focus is logically in this area. + // event: Event object + // isBubble: Boolean + // Whether is in bubble stage (true) or catch stage (false). + // returns: + // If you do NOT want the event to propagate any further along the area stack, return exactly false. + // So if you return nothing (undefined), this event is still propagating. + onKey: function(event, isBubble){return true}, + + // getRegions: function() + // Define the small regions (dom nodes) in this area. + // returns: Array of dom nodes. + getRegions: function(){}, + + // onRegionFocus: function(event) + // Connected to the onfocus event of the defined regions (if any) + onRegionFocus: function(event){}, + + // onRegionBlur: function(event) + // Connected to the onblur event of the defined regions (if any) + onRegionBlur: function(event){}, +=====*/ + constructor: function(area, focusManager){ + this._fm = focusManager; + this._evtStack = [area.name]; + var dummy = function(){return true;}; + area.onFocus = area.onFocus || dummy; + area.onBlur = area.onBlur || dummy; + area.onMove = area.onMove || dummy; + area.onKeyUp = area.onKeyUp || dummy; + area.onKeyDown = area.onKeyDown || dummy; + lang.mixin(this, area); + }, + move: function(rowStep, colStep, evt){ + if(this.name){ + var i, len = this._evtStack.length; + for(i = len - 1; i >= 0; --i){ + if(this._fm._areas[this._evtStack[i]].onMove(rowStep, colStep, evt) === false){ + return false; + } + } + } + return true; + }, + _onKeyEvent: function(evt, funcName){ + if(this.name){ + var i, len = this._evtStack.length; + for(i = len - 1; i >= 0; --i){ + if(this._fm._areas[this._evtStack[i]][funcName](evt, false) === false){ + return false; + } + } + for(i = 0; i < len; ++i){ + if(this._fm._areas[this._evtStack[i]][funcName](evt, true) === false){ + return false; + } + } + } + return true; + }, + keydown: function(evt){ + return this._onKeyEvent(evt, "onKeyDown"); + }, + keyup: function(evt){ + return this._onKeyEvent(evt, "onKeyUp"); + }, + contentMouseEventPlanner: function(){ + return 0; + }, + headerMouseEventPlanner: function(){ + return 0; + } +}); + +return declare("dojox.grid.enhanced._FocusManager", _FocusManager, { + _stopEvent: function(evt){ + try{ + if(evt && evt.preventDefault){ + event.stop(evt); + } + }catch(e){} + }, + + constructor: function(grid){ + this.grid = grid; + this._areas = {}; + this._areaQueue = []; + this._contentMouseEventHandlers = []; + this._headerMouseEventHandlers = []; + this._currentAreaIdx = -1; + this._gridBlured = true; + this._connects.push(connect.connect(grid, "onBlur", this, "_doBlur")); + this._connects.push(connect.connect(grid.scroller, "renderPage", this, "_delayedCellFocus")); + + this.addArea({ + name: "header", + onFocus: lang.hitch(this, this.focusHeader), + onBlur: lang.hitch(this, this._blurHeader), + onMove: lang.hitch(this, this._navHeader), + getRegions: lang.hitch(this, this._findHeaderCells), + onRegionFocus: lang.hitch(this, this.doColHeaderFocus), + onRegionBlur: lang.hitch(this, this.doColHeaderBlur), + onKeyDown: lang.hitch(this, this._onHeaderKeyDown) + }); + this.addArea({ + name: "content", + onFocus: lang.hitch(this, this._focusContent), + onBlur: lang.hitch(this, this._blurContent), + onMove: lang.hitch(this, this._navContent), + onKeyDown: lang.hitch(this, this._onContentKeyDown) + }); + this.addArea({ + name: "editableCell", + onFocus: lang.hitch(this, this._focusEditableCell), + onBlur: lang.hitch(this, this._blurEditableCell), + onKeyDown: lang.hitch(this, this._onEditableCellKeyDown), + onContentMouseEvent: lang.hitch(this, this._onEditableCellMouseEvent), + contentMouseEventPlanner: function(evt, areas){ return -1; } + }); + this.placeArea("header"); + this.placeArea("content"); + this.placeArea("editableCell"); + this.placeArea("editableCell","above","content"); + }, + destroy: function(){ + for(var name in this._areas){ + var area = this._areas[name]; + array.forEach(area._connects, connect.disconnect); + area._connects = null; + if(area.uninitialize){ + area.uninitialize(); + } + } + this.inherited(arguments); + }, + addArea: function(area){ + if(area.name && lang.isString(area.name)){ + if(this._areas[area.name]){ + //Just replace the original area, instead of remove it, so the position does not change. + array.forEach(area._connects, connect.disconnect); + } + this._areas[area.name] = new _FocusArea(area, this); + if(area.onHeaderMouseEvent){ + this._headerMouseEventHandlers.push(area.name); + } + if(area.onContentMouseEvent){ + this._contentMouseEventHandlers.push(area.name); + } + } + }, + getArea: function(areaName){ + return this._areas[areaName]; + }, + _bindAreaEvents: function(){ + var area, hdl, areas = this._areas; + array.forEach(this._areaQueue, function(name){ + area = areas[name]; + if(!area._initialized && lang.isFunction(area.initialize)){ + area.initialize(); + area._initialized = true; + } + if(area.getRegions){ + area._regions = area.getRegions() || []; + array.forEach(area._connects || [], connect.disconnect); + area._connects = []; + array.forEach(area._regions, function(r){ + if(area.onRegionFocus){ + hdl = connect.connect(r, "onfocus", area.onRegionFocus); + area._connects.push(hdl); + } + if(area.onRegionBlur){ + hdl = connect.connect(r, "onblur", area.onRegionBlur); + area._connects.push(hdl); + } + }); + } + }); + }, + removeArea: function(areaName){ + var area = this._areas[areaName]; + if(area){ + this.ignoreArea(areaName); + var i = array.indexOf(this._contentMouseEventHandlers, areaName); + if(i >= 0){ + this._contentMouseEventHandlers.splice(i, 1); + } + i = array.indexOf(this._headerMouseEventHandlers, areaName); + if(i >= 0){ + this._headerMouseEventHandlers.splice(i, 1); + } + array.forEach(area._connects, connect.disconnect); + if(area.uninitialize){ + area.uninitialize(); + } + delete this._areas[areaName]; + } + }, + currentArea: function(areaName, toBlurOld){ + // summary: + // Set current area to the one areaName refers. + // areaName: String + var idx, cai = this._currentAreaIdx; + if(lang.isString(areaName) && (idx = array.indexOf(this._areaQueue, areaName)) >= 0){ + if(cai != idx){ + this.tabbingOut = false; + if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){ + this._areas[this._areaQueue[cai]].onBlur(); + } + this._currentAreaIdx = idx; + } + }else{ + return (cai < 0 || cai >= this._areaQueue.length) ? + new _FocusArea({}, this) : + this._areas[this._areaQueue[this._currentAreaIdx]]; + } + return null; + }, + placeArea: function(name, pos, otherAreaName){ + // summary: + // Place the area refered by *name* at some logical position relative to an existing area. + // example: + // placeArea("myarea","before"|"after",...) + // placeArea("myarea","below"|"above",...) + if(!this._areas[name]){ return; } + var idx = array.indexOf(this._areaQueue,otherAreaName); + switch(pos){ + case "after": + if(idx >= 0){ ++idx; } + //intentional drop through + case "before": + if(idx >= 0){ + this._areaQueue.splice(idx,0,name); + break; + } + //intentional drop through + default: + this._areaQueue.push(name); + break; + case "above": + var isAbove = true; + //intentional drop through + case "below": + var otherArea = this._areas[otherAreaName]; + if(otherArea){ + if(isAbove){ + otherArea._evtStack.push(name); + }else{ + otherArea._evtStack.splice(0,0,name); + } + } + } + }, + ignoreArea: function(name){ + this._areaQueue = array.filter(this._areaQueue,function(areaName){ + return areaName != name; + }); + }, + focusArea: function(/* int|string|areaObj */areaId,evt){ + var idx; + if(typeof areaId == "number"){ + idx = areaId < 0 ? this._areaQueue.length + areaId : areaId; + }else{ + idx = array.indexOf(this._areaQueue, + lang.isString(areaId) ? areaId : (areaId && areaId.name)); + } + if(idx < 0){ idx = 0; } + var step = idx - this._currentAreaIdx; + this._gridBlured = false; + if(step){ + this.tab(step, evt); + }else{ + this.currentArea().onFocus(evt, step); + } + }, + tab: function(step,evt){ + //console.log("===========tab",step,"curArea",this._currentAreaIdx,"areaCnt",this._areaQueue.length); + this._gridBlured = false; + this.tabbingOut = false; + if(step === 0){ + return; + } + var cai = this._currentAreaIdx; + var dir = step > 0 ? 1:-1; + if(cai < 0 || cai >= this._areaQueue.length){ + cai = (this._currentAreaIdx += step); + }else{ + var nextArea = this._areas[this._areaQueue[cai]].onBlur(evt,step); + if(nextArea === true){ + cai = (this._currentAreaIdx += step); + }else if(lang.isString(nextArea) && this._areas[nextArea]){ + cai = this._currentAreaIdx = array.indexOf(this._areaQueue,nextArea); + } + } + //console.log("target area:",cai); + for(; cai >= 0 && cai < this._areaQueue.length; cai += dir){ + this._currentAreaIdx = cai; + if(this._areaQueue[cai] && this._areas[this._areaQueue[cai]].onFocus(evt,step)){ + //console.log("final target area:",this._currentAreaIdx); + return; + } + } + //console.log("tab out"); + this.tabbingOut = true; + if(step < 0){ + this._currentAreaIdx = -1; + dijitFocus.focus(this.grid.domNode); + }else{ + this._currentAreaIdx = this._areaQueue.length; + dijitFocus.focus(this.grid.lastFocusNode); + } + }, + _onMouseEvent: function(type, evt){ + var lowercase = type.toLowerCase(), + handlers = this["_" + lowercase + "MouseEventHandlers"], + res = array.map(handlers, function(areaName){ + return { + "area": areaName, + "idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers) + }; + }, this).sort(function(a, b){ + return b.idx - a.idx; + }), + resHandlers = array.map(res, function(handler){ + return res.area; + }), + i = res.length; + while(--i >= 0){ + if(this._areas[res[i].area]["on" + type + "MouseEvent"](evt, resHandlers) === false){ + return; + } + } + }, + contentMouseEvent: function(evt){ + this._onMouseEvent("Content", evt); + }, + headerMouseEvent: function(evt){ + this._onMouseEvent("Header", evt); + }, + initFocusView: function(){ + // summary: + // Overwritten + this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0]; + this._bindAreaEvents(); + }, + isNavHeader: function(){ + // summary: + // Overwritten + // Check whether currently navigating among column headers. + // return: + // true - focus is on a certain column header | false otherwise + return this._areaQueue[this._currentAreaIdx] == "header"; + }, + previousKey: function(e){ + // summary: + // Overwritten + this.tab(-1,e); + }, + nextKey: function(e){ + // summary: + // Overwritten + this.tab(1,e); + }, + setFocusCell: function(/* Object */inCell, /* Integer */inRowIndex){ + // summary: + // Overwritten - focuses the given grid cell + if(inCell){ + this.currentArea(this.grid.edit.isEditing() ? "editableCell" : "content", true); + //This is very slow when selecting cells! + //this.focusGridView(); + this._focusifyCellNode(false); + this.cell = inCell; + this.rowIndex = inRowIndex; + this._focusifyCellNode(true); + } + this.grid.onCellFocus(this.cell, this.rowIndex); + }, + doFocus: function(e){ + // summary: + // Overwritten + // trap focus only for grid dom node + // do not focus for scrolling if grid is about to blur + if(e && e.target == e.currentTarget && !this.tabbingOut){ + if(this._gridBlured){ + this._gridBlured = false; + if(this._currentAreaIdx < 0 || this._currentAreaIdx >= this._areaQueue.length){ + this.focusArea(0, e); + }else{ + this.focusArea(this._currentAreaIdx, e); + } + } + }else{ + this.tabbingOut = false; + } + event.stop(e); + }, + _doBlur: function(){ + this._gridBlured = true; + }, + doLastNodeFocus: function(e){ + // summary: + // Overwritten + if(this.tabbingOut){ + this.tabbingOut = false; + }else{ + this.focusArea(-1, e); + } + }, + _delayedHeaderFocus: function(){ + // summary: + // Overwritten + if(this.isNavHeader()){ + this.focusHeader(); + } + }, + _delayedCellFocus: function(){ + // summary: + // Overwritten + this.currentArea("header", true); + this.focusArea(this._currentAreaIdx); + }, + _changeMenuBindNode: function(oldBindNode, newBindNode){ + var hm = this.grid.headerMenu; + if(hm && this._contextMenuBindNode == oldBindNode){ + hm.unBindDomNode(oldBindNode); + hm.bindDomNode(newBindNode); + this._contextMenuBindNode = newBindNode; + } + }, + //---------------Header Area------------------------------------------ + focusHeader: function(evt, step){ //need a further look why these changes to parent's + // summary: + // Overwritten + var didFocus = false; + this.inherited(arguments); + if(this._colHeadNode && html.style(this._colHeadNode, 'display') != "none"){ + dijitFocus.focus(this._colHeadNode); + this._stopEvent(evt); + didFocus = true; + } + return didFocus; + }, + _blurHeader: function(evt,step){ + // summary: + // Overwritten + if(this._colHeadNode){ + html.removeClass(this._colHeadNode, this.focusClass); + } + html.removeAttr(this.grid.domNode,"aria-activedescendant"); + // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader) + this._changeMenuBindNode(this.grid.domNode,this.grid.viewsHeaderNode); + //moved here from nextKey + this._colHeadNode = this._colHeadFocusIdx = null; + return true; + }, + _navHeader: function(rowStep, colStep, evt){ + var colDir = colStep < 0 ? -1 : 1, + savedIdx = array.indexOf(this._findHeaderCells(), this._colHeadNode); + if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){ + this.colSizeAdjust(evt, savedIdx, colDir * 5); + return; + } + this.move(rowStep, colStep); + }, + _onHeaderKeyDown: function(e, isBubble){ + if(isBubble){ + var dk = keys; + switch(e.keyCode){ + case dk.ENTER: + case dk.SPACE: + var colIdx = this.getHeaderIndex(); + if(colIdx >= 0 && !this.grid.pluginMgr.isFixedCell(e.cell)/*TODO*/){ + this.grid.setSortIndex(colIdx, null, e); + event.stop(e); + } + break; + } + } + return true; + }, + _setActiveColHeader: function(){ + // summary: + // Overwritten + this.inherited(arguments); + //EDG now will decorate event on header key events, if no focus, the cell will be wrong + dijitFocus.focus(this._colHeadNode); + }, + //---------------Content Area------------------------------------------ + findAndFocusGridCell: function(){ + // summary: + // Overwritten + this._focusContent(); + }, + _focusContent: function(evt,step){ + var didFocus = true; + var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0 + if(this.isNoFocusCell() && !isEmpty){ + //skip all the hidden cells + for(var i = 0, cell = this.grid.getCell(0); cell && cell.hidden; cell = this.grid.getCell(++i)){} + this.setFocusIndex(0, cell ? i : 0); + }else if(this.cell && !isEmpty){ + if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){ + // if rowNode for current index is undefined (likely as a result of a sort and because of #7304) + // scroll to that row + this.grid.scrollToRow(this.rowIndex); + this.focusGrid(); + }else{ + this.setFocusIndex(this.rowIndex, this.cell.index); + } + }else{ + didFocus = false; + } + if(didFocus){ this._stopEvent(evt); } + return didFocus; + }, + _blurContent: function(evt,step){ + this._focusifyCellNode(false); + return true; + }, + _navContent: function(rowStep, colStep, evt){ + if((this.rowIndex === 0 && rowStep < 0) || (this.rowIndex === this.grid.rowCount - 1 && rowStep > 0)){ + return; + } + this._colHeadNode = null; + this.move(rowStep, colStep, evt); + if(evt){ + event.stop(evt); + } + }, + _onContentKeyDown: function(e, isBubble){ + if(isBubble){ + var dk = keys, s = this.grid.scroller; + switch(e.keyCode){ + case dk.ENTER: + case dk.SPACE: + var g = this.grid; + if(g.indirectSelection){ break; } + g.selection.clickSelect(this.rowIndex, connect.isCopyKey(e), e.shiftKey); + g.onRowClick(e); + event.stop(e); + break; + case dk.PAGE_UP: + if(this.rowIndex !== 0){ + if(this.rowIndex != s.firstVisibleRow + 1){ + this._navContent(s.firstVisibleRow - this.rowIndex, 0); + }else{ + this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1)); + this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0); + } + event.stop(e); + } + break; + case dk.PAGE_DOWN: + if(this.rowIndex + 1 != this.grid.rowCount){ + event.stop(e); + if(this.rowIndex != s.lastVisibleRow - 1){ + this._navContent(s.lastVisibleRow - this.rowIndex - 1, 0); + }else{ + this.grid.setScrollTop(s.findScrollTop(this.rowIndex + 1)); + this._navContent(s.lastVisibleRow - s.firstVisibleRow - 1, 0); + } + event.stop(e); + } + break; + } + } + return true; + }, + //------------------editable content area------------------------- + _blurFromEditableCell: false, + _isNavigating: false, + _navElems: null, + _focusEditableCell: function(evt,step){ + var didFocus = false; + if(this._isNavigating){ + didFocus = true; + }else if(this.grid.edit.isEditing() && this.cell){ + if(this._blurFromEditableCell || !this._blurEditableCell(evt, step)){ + this.setFocusIndex(this.rowIndex,this.cell.index); + didFocus = true; + } + this._stopEvent(evt); + } + return didFocus; + }, + _applyEditableCell: function(){ + try{ + this.grid.edit.apply(); + }catch(e){ + console.warn("_FocusManager._applyEditableCell() error:", e); + } + }, + _blurEditableCell: function(evt,step){ + this._blurFromEditableCell = false; + if(this._isNavigating){ + var toBlur = true; + if(evt){ + var elems = this._navElems; + var firstElem = elems.lowest || elems.first; + var lastElem = elems.last || elems.highest || firstElem; + var target = has("ie") ? evt.srcElement : evt.target; + toBlur = target == (step > 0 ? lastElem : firstElem); + } + if(toBlur){ + this._isNavigating = false; + html.setSelectable(this.cell.getNode(this.rowIndex), false); + return "content"; + } + return false; + }else if(this.grid.edit.isEditing() && this.cell){ + if(!step || typeof step != "number"){ return false; } + var dir = step > 0 ? 1 : -1; + var cc = this.grid.layout.cellCount; + for(var cell, col = this.cell.index + dir; col >= 0 && col < cc; col += dir){ + cell = this.grid.getCell(col); + if(cell.editable){ + this.cell = cell; + this._blurFromEditableCell = true; + return false; + } + } + if((this.rowIndex > 0 || dir == 1) && (this.rowIndex < this.grid.rowCount || dir == -1)){ + this.rowIndex += dir; + //this.cell = this.grid.getCell(0); //There must be an editable cell, so this is not necessary. + for(col = dir > 0 ? 0 : cc - 1; col >= 0 && col < cc; col += dir){ + cell = this.grid.getCell(col); + if(cell.editable){ + this.cell = cell; + break; + } + } + this._applyEditableCell(); + return "content"; + } + } + return true; + }, + _initNavigatableElems: function(){ + this._navElems = dijitA11y._getTabNavigable(this.cell.getNode(this.rowIndex)); + }, + _onEditableCellKeyDown: function(e, isBubble){ + var dk = keys, + g = this.grid, + edit = g.edit, + editApplied = false, + toPropagate = true; + switch(e.keyCode){ + case dk.ENTER: + if(isBubble && edit.isEditing()){ + this._applyEditableCell(); + editApplied = true; + event.stop(e); + } + //intentional drop through + case dk.SPACE: + if(!isBubble && this._isNavigating){ + toPropagate = false; + break; + } + if(isBubble){ + if(!this.cell.editable && this.cell.navigatable){ + this._initNavigatableElems(); + var toFocus = this._navElems.lowest || this._navElems.first; + if(toFocus){ + this._isNavigating = true; + html.setSelectable(this.cell.getNode(this.rowIndex), true); + dijitFocus.focus(toFocus); + event.stop(e); + this.currentArea("editableCell", true); + break; + } + } + if(!editApplied && !edit.isEditing() && !g.pluginMgr.isFixedCell(this.cell)){ + edit.setEditCell(this.cell, this.rowIndex); + } + if(editApplied){ + this.currentArea("content", true); + }else if(this.cell.editable && g.canEdit()){ + this.currentArea("editableCell", true); + } + } + break; + case dk.PAGE_UP: + case dk.PAGE_DOWN: + if(!isBubble && edit.isEditing()){ + //prevent propagating to content area + toPropagate = false; + } + break; + case dk.ESCAPE: + if(!isBubble){ + edit.cancel(); + this.currentArea("content", true); + } + } + return toPropagate; + }, + _onEditableCellMouseEvent: function(evt){ + if(evt.type == "click"){ + var cell = this.cell || evt.cell; + if(cell && !cell.editable && cell.navigatable){ + this._initNavigatableElems(); + if(this._navElems.lowest || this._navElems.first){ + var target = has("ie") ? evt.srcElement : evt.target; + if(target != cell.getNode(evt.rowIndex)){ + this._isNavigating = true; + this.focusArea("editableCell", evt); + html.setSelectable(cell.getNode(evt.rowIndex), true); + dijitFocus.focus(target); + return false; + } + } + }else if(this.grid.singleClickEdit){ + this.currentArea("editableCell"); + return false; + } + } + return true; + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js b/js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js new file mode 100644 index 0000000..b0a4969 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js @@ -0,0 +1,172 @@ +//>>built +define("dojox/grid/enhanced/_Plugin", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "../EnhancedGrid" +], function(dojo, lang, declare, array, connect){ + +return declare("dojox.grid.enhanced._Plugin", null, { + // summary: + // Base class for all plugins. + // + // description: + // Provides common plugin functionality and basic life cycle management. + // + // Each concrete plugin must have a name field and is responsible for registering itself to the global plugin registry + // e.g. for dnd plugin: + // | dojox.grid.EnhancedGrid.registerPlugin("dnd" /*plugin name*/, + // | dojox.grid.enhanced.plugins.DnD /*full class name of a plugin*/ + // | {"preInit": false, "dependency": ["nestedSorting"]} /*properties*/); + // + // [Keywords] of plugin properties(case sensitive) + // - "preInit": boolean, whether a plugin should be created before EnhancedGrid.postCreate(), + // false by default(plugins are created after EnhancedGrid.postCreate()). + // - "dependency": array or string, plugin(s) indicated by "dependency" will be created before the current one. + // Note: recursive cycle dependencies are not supported e.g. following dependency is invalid: + // pluginA -> pluginB -> pluginA + // + // example: + // 1. Customize default DnD plugin + // | dojo.declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, { + // | name:"dnd" //still reuse the plugin name + // | constructor: function(inGrid, option){ ... } + // | }); + // | dojox.grid.EnhancedGrid.registerPlugin("dnd", mygrid.MyDnD); + // + // 2. Add new plugin - PluginA + // | dojo.declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, { + // | name: "pA", + // | constructor: function(inGrid, option){ ... } + // | }); + // | dojox.grid.EnhancedGrid.registerPlugin("pA",mygrid.PluginA); + // + // 3. Use plugins + // | dojo.require("mygrid.MyDnD"); + // | dojo.require("mygrid.PluginA"); + + // | <script type="text/javascript"> + // | var grid = new dojox.grid.EnhancedGrid( + // | {plugins: {dnd:true, pA:true}, ... }, dojo.byId("gridDiv")); + // | grid.startup(); + // | </script> + + //name: String + // Plugin name, e.g. 'nestedSorting', 'dnd'... + name: 'plugin', + + //grid: Object + // Grid that the plugin belongs to + grid: null, + + //option: Object + // Plugin properties - leveraged with default and user specified properties. + // e.g. for dnd plugin, it may look like {"class": dojox.grid.enhanced.plugins.DnD, "dependency": ["nestedSorting"], ...} + option: {}, + + //_connects: Array + // List of all connections. + _connects: [], + + //_subscribes: Array + // List of all subscribes. + _subscribes: [], + + //privates: Object + // Private properties/methods shouldn't be mixin-ed anytime. + privates: {}, + + constructor: function(inGrid, option){ + this.grid = inGrid; + this.option = option; + this._connects = []; + this._subscribes = []; + this.privates = lang.mixin({},dojox.grid.enhanced._Plugin.prototype); + this.init(); + }, + + init: function(){}, + + onPreInit: function(){}, + + onPostInit: function(){}, + + onStartUp: function(){}, + + connect: function(obj, event, method){ + // summary: + // Connects specified obj/event to specified method of this object. + // example: + // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...}); + // | // when foo.bar() is called, call the listener in the scope of plugin + // | plugin.connect(foo, "bar", function(){ + // | console.debug(this.xxx());//"this" - plugin scope + // | }); + var conn = connect.connect(obj, event, this, method); + this._connects.push(conn); + return conn; + }, + disconnect: function(handle){ + // summary: + // Disconnects handle and removes it from connection list. + array.some(this._connects, function(conn, i, conns){ + if(conn == handle){ + connect.disconnect(handle); + conns.splice(i, 1); + return true; + } + return false; + }); + }, + subscribe: function(topic, method){ + // summary: + // Subscribes to the specified topic and calls the specified method + // of this object. + // example: + // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...}); + // | // when /my/topic is published, call the subscriber in the scope of plugin + // | // with passed parameter - "v" + // | plugin.subscribe("/my/topic", function(v){ + // | console.debug(this.xxx(v));//"this" - plugin scope + // | }); + var subscribe = connect.subscribe(topic, this, method); + this._subscribes.push(subscribe); + return subscribe; + }, + unsubscribe: function(handle){ + // summary: + // Un-subscribes handle and removes it from subscriptions list. + array.some(this._subscribes, function(subscribe, i, subscribes){ + if(subscribe == handle){ + connect.unsubscribe(handle); + subscribes.splice(i, 1); + return true; + } + return false; + }); + }, + onSetStore: function(store){ + // summary: + // Called when store is changed. + }, + destroy: function(){ + // summary: + // Destroy all resources. + array.forEach(this._connects, connect.disconnect); + array.forEach(this._subscribes, connect.unsubscribe); + delete this._connects; + delete this._subscribes; + delete this.option; + delete this.privates; + //console.log('Plugin [', this.name, '].destroy() executed!'); + } +}); + +//Each plugin is responsible for registering itself +// e.g. for DnD plugin(name:'dnd'): +// | dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*class*/, +// | {"dependency": ["nestedSorting"]}/*Optional - properties*/); + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js b/js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js new file mode 100644 index 0000000..20e6e91 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js @@ -0,0 +1,275 @@ +//>>built +define("dojox/grid/enhanced/_PluginManager", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "./_Events", + "./_FocusManager", + "../util" +], function(dojo, lang, declare, array, connect, _Events, _FocusManager, util){ + +var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, { + // summary: + // Singleton plugin manager + // + // description: + // Plugin manager is responsible for + // 1. Loading required plugins + // 2. Handling collaborat ion and dependencies among plugins + // + // Some plugin dependencies: + // - "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on. + + //_options: Object + // Normalized plugin options + _options: null, + + //_plugins: Array + // Plugin list + _plugins: null, + + //_connects: Array + // Connection list + _connects: null, + + constructor: function(inGrid){ + this.grid = inGrid; + this._store = inGrid.store; + this._options = {}; + this._plugins = []; + this._connects = []; + this._parseProps(this.grid.plugins); + + inGrid.connect(inGrid, "_setStore", lang.hitch(this, function(store){ + if(this._store !== store){ + this.forEach('onSetStore', [store, this._store]); + this._store = store; + } + })); + }, + startup: function(){ + this.forEach('onStartUp'); + }, + preInit: function(){ + // summary: + // Load appropriate plugins before DataGrid.postCreate(). + // See EnhancedGrid.postCreate() + this.grid.focus.destroy(); + this.grid.focus = new _FocusManager(this.grid); + new _Events(this.grid);//overwrite some default events of DataGrid + this._init(true); + this.forEach('onPreInit'); + }, + postInit: function(){ + // summary: + // Load plugins after DataGrid.postCreate() - the default phase when plugins are created + // See EnhancedGrid.postCreate() + this._init(false); + + array.forEach(this.grid.views.views, this._initView, this); + this._connects.push(connect.connect(this.grid.views, 'addView', lang.hitch(this, this._initView))); + + if(this._plugins.length > 0){ + var edit = this.grid.edit; + if(edit){ edit.styleRow = function(inRow){}; } + } + this.forEach('onPostInit'); + }, + forEach: function(func, args){ + array.forEach(this._plugins, function(p){ + if(!p || !p[func]){ return; } + p[func].apply(p, args ? args : []); + }); + }, + _parseProps: function(plugins){ + // summary: + // Parse plugins properties + // plugins: Object + // Plugin properties defined by user + if(!plugins){ return; } + + var p, loading = {}, options = this._options, grid = this.grid; + var registry = _PluginManager.registry;//global plugin registry + for(p in plugins){ + if(plugins[p]){//filter out boolean false e.g. {p:false} + this._normalize(p, plugins, registry, loading); + } + } + //"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used. + if(options.dnd || options.indirectSelection){ + options.columnReordering = false; + } + + //mixin all plugin properties into Grid + lang.mixin(grid, options); + }, + _normalize: function(p, plugins, registry, loading){ + // summary: + // Normalize plugin properties especially the dependency chain + // p: String + // Plugin name + // plugins: Object + // Plugin properties set by user + // registry: Object + // The global plugin registry + // loading: Object + // Map for checking process state + if(!registry[p]){ throw new Error('Plugin ' + p + ' is required.');} + + if(loading[p]){ throw new Error('Recursive cycle dependency is not supported.'); } + + var options = this._options; + if(options[p]){ return options[p]; } + + loading[p] = true; + //TBD - more strict conditions? + options[p] = lang.mixin({}, registry[p], lang.isObject(plugins[p]) ? plugins[p] : {}); + + var dependencies = options[p]['dependency']; + if(dependencies){ + if(!lang.isArray(dependencies)){ + dependencies = options[p]['dependency'] = [dependencies]; + } + array.forEach(dependencies, function(dependency){ + if(!this._normalize(dependency, plugins, registry, loading)){ + throw new Error('Plugin ' + dependency + ' is required.'); + } + }, this); + } + delete loading[p]; + return options[p]; + }, + _init: function(pre){ + // summary: + // Find appropriate plugins and load them + // pre: Boolean + // True - preInit | False - postInit(by default) + var p, preInit, options = this._options; + for(p in options){ + preInit = options[p]['preInit']; + if((pre ? preInit : !preInit) && options[p]['class'] && !this.pluginExisted(p)){ + this.loadPlugin(p); + } + } + }, + loadPlugin: function(name){ + // summary: + // Load required plugin("name") + // name: String + // Plugin name + // return: Object + // The newly loaded plugin + var option = this._options[name]; + if(!option){ return null; } //return if no plugin option + + var plugin = this.getPlugin(name); + if(plugin){ return plugin; } //return if plugin("name") already existed + + var dependencies = option['dependency']; + array.forEach(dependencies, function(dependency){ + if(!this.loadPlugin(dependency)){ + throw new Error('Plugin ' + dependency + ' is required.'); + } + }, this); + var cls = option['class']; + delete option['class'];//remove it for safety + plugin = new this.getPluginClazz(cls)(this.grid, option); + this._plugins.push(plugin); + return plugin; + }, + _initView: function(view){ + // summary: + // Overwrite several default behavior for each views(including _RowSelector view) + if(!view){ return; } + //add more events handler - _View + util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']); + util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']); + }, + pluginExisted: function(name){ + // summary: + // Check if plugin("name") existed + // name: String + // Plugin name + // return: Boolean + // True - existed | False - not existed + return !!this.getPlugin(name); + }, + getPlugin: function(name){ + // summary: + // Get plugin("name") + // name: String + // Plugin name + // return: Object + // Plugin instance + var plugins = this._plugins; + name = name.toLowerCase(); + for(var i = 0, len = plugins.length; i < len; i++){ + if(name == plugins[i]['name'].toLowerCase()){ + return plugins[i]; + } + } + return null; + }, + getPluginClazz: function(clazz){ + // summary: + // Load target plugin which must be already required (require(..)) + // clazz: class | String + // Plugin class + if(lang.isFunction(clazz)){ + return clazz;//return if it's already a clazz + } + var errorMsg = 'Please make sure Plugin "' + clazz + '" is existed.'; + try{ + var cls = lang.getObject(clazz); + if(!cls){ throw new Error(errorMsg); } + return cls; + }catch(e){ + throw new Error(errorMsg); + } + }, + isFixedCell: function(cell){ + // summary: + // See if target cell(column) is fixed or not. + // cell: Object + // Target cell(column) + // return: Boolean + // True - fixed| False - not fixed + + //target cell can use Boolean attributes named "isRowSelector" or "fixedPos" to mark it's a fixed cell(column) + return cell && (cell.isRowSelector || cell.fixedPos); + }, + destroy: function(){ + // summary: + // Destroy all resources + array.forEach(this._connects, connect.disconnect); + this.forEach('destroy'); + if(this.grid.unwrap){ + this.grid.unwrap(); + } + delete this._connects; + delete this._plugins; + delete this._options; + } +}); + +_PluginManager.registerPlugin = function(clazz, props){ + // summary: + // Register plugins - TODO, a better way rather than global registry? + // clazz: String + // Full class name, e.g. "dojox.grid.enhanced.plugins.DnD" + // props: Object - Optional + // Plugin properties e.g. {"dependency": ["nestedSorting"], ...} + if(!clazz){ + console.warn("Failed to register plugin, class missed!"); + return; + } + var cls = _PluginManager; + cls.registry = cls.registry || {}; + cls.registry[clazz.prototype.name]/*plugin name*/ = lang.mixin({"class": clazz}, (props ? props : {})); +}; + +return _PluginManager; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js new file mode 100644 index 0000000..29bd64b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js @@ -0,0 +1,48 @@ +//>>built +define("dojox/grid/enhanced/nls/EnhancedGrid", { root: +//begin v1.x content +({ + singleSort: "Single Sort", + nestedSort: "Nested Sort", + ascending: "Click to sort Ascending", + descending: "Click to sort Descending", + sortingState: "${0} - ${1}", + unsorted: "Do not sort this column", + indirectSelectionRadio: "Row ${0}, single selection, radio box", + indirectSelectionCheckBox: "Row ${0}, multiple selection, check box", + selectAll: "Select all" +}) +//end v1.x content +, +"ar": true, +"ca": true, +"cs": true, +"da": true, +"de": true, +"el": true, +"es": true, +"fi": true, +"fr": true, +"he": true, +"hr": true, +"hu": true, +"hr": true, +"it": true, +"ja": true, +"kk": true, +"ko": true, +"nb": true, +"nl": true, +"pl": true, +"pt": true, +"pt-pt": true, +"ro": true, +"ru": true, +"sk": true, +"sl": true, +"sv": true, +"th": true, +"tr": true, +"zh": true, +"zh-tw": true +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js new file mode 100644 index 0000000..5bf56a4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js @@ -0,0 +1,121 @@ +//>>built +define("dojox/grid/enhanced/nls/Filter", { root: +//begin v1.x content +({ + "clearFilterDialogTitle": "Clear Filter", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Rule ${0}", + + "conditionEqual": "equal", + "conditionNotEqual": "does not equal", + "conditionLess": "is less than", + "conditionLessEqual": "less than or equal", + "conditionLarger": "is greater than", + "conditionLargerEqual": "greater than or equal", + "conditionContains": "contains", + "conditionIs": "is", + "conditionStartsWith": "starts with", + "conditionEndWith": "ends with", + "conditionNotContain": "does not contain", + "conditionIsNot": "is not", + "conditionNotStartWith": "does not start with", + "conditionNotEndWith": "does not end with", + "conditionBefore": "before", + "conditionAfter": "after", + "conditionRange": "range", + "conditionIsEmpty": "is empty", + + "all": "all", + "any": "any", + "relationAll": "all rules", + "waiRelAll": "Match all of the following rules:", + "relationAny": "any rules", + "waiRelAny": "Match any of the following rules:", + "relationMsgFront": "Match:", + "relationMsgTail": "", + "and": "and", + "or": "or", + + "addRuleButton": "Add Rule", + "waiAddRuleButton": "Add a new rule", + "removeRuleButton": "Remove Rule", + "waiRemoveRuleButtonTemplate": "Remove rule ${0}", + + "cancelButton": "Cancel", + "waiCancelButton": "Cancel this dialog", + "clearButton": "Clear", + "waiClearButton": "Clear the filter", + "filterButton": "Filter", + "waiFilterButton": "Submit the filter", + + "columnSelectLabel": "Column", + "waiColumnSelectTemplate": "Column for rule ${0}", + "conditionSelectLabel": "Condition", + "waiConditionSelectTemplate": "Condition for rule ${0}", + "valueBoxLabel": "Value", + "waiValueBoxTemplate": "Enter value to filter for rule ${0}", + + "rangeTo": "to", + "rangeTemplate": "from ${0} to ${1}", + + "statusTipHeaderColumn": "Column", + "statusTipHeaderCondition": "Rules", + "statusTipTitle": "Filter Bar", + "statusTipMsg": "Click the filter bar here to filter on values in ${0}.", + "anycolumn": "any column", + "statusTipTitleNoFilter": "Filter Bar", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Match any rules.", + "statusTipRelAll": "Match all rules.", + + "defaultItemsName": "items", + "filterBarMsgHasFilterTemplate": "${0} of ${1} ${2} shown.", + "filterBarMsgNoFilterTemplate": "No filter applied", + + "filterBarDefButton": "Define filter", + "waiFilterBarDefButton": "Filter the table", + "a11yFilterBarDefButton": "Filter...", + "filterBarClearButton": "Clear filter", + "waiFilterBarClearButton": "Clear the filter", + "closeFilterBarBtn": "Close filter bar", + + "clearFilterMsg": "This will remove the filter and show all available records.", + "anyColumnOption": "Any Column", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +, +"ar": true, +"ca": true, +"cs": true, +"da": true, +"de": true, +"el": true, +"es": true, +"fi": true, +"fr": true, +"he": true, +"hr": true, +"hu": true, +"hr": true, +"it": true, +"ja": true, +"kk": true, +"ko": true, +"nb": true, +"nl": true, +"pl": true, +"pt": true, +"pt-pt": true, +"ro": true, +"ru": true, +"sk": true, +"sl": true, +"sv": true, +"th": true, +"tr": true, +"zh": true, +"zh-tw": true +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js new file mode 100644 index 0000000..65eec33 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js @@ -0,0 +1,56 @@ +//>>built +define("dojox/grid/enhanced/nls/Pagination", { root: +//begin v1.x content +({ + "descTemplate": "${2} - ${3} of ${1} ${0}", + "firstTip": "First Page", + "lastTip": "Last Page", + "nextTip": "Next Page", + "prevTip": "Previous Page", + "itemTitle": "items", + "singularItemTitle": "item", + "pageStepLabelTemplate": "Page ${0}", + "pageSizeLabelTemplate": "${0} items per page", + "allItemsLabelTemplate": "All items", + "gotoButtonTitle": "Go to a specific page", + "dialogTitle": "Go to Page", + "dialogIndication": "Specify the page number", + "pageCountIndication": " (${0} pages)", + "dialogConfirm": "Go", + "dialogCancel": "Cancel", + "all": "All" +}) +//end v1.x content +, +"ar": true, +"ca": true, +"cs": true, +"da": true, +"de": true, +"el": true, +"es": true, +"fi": true, +"fr": true, +"he": true, +"hr": true, +"hu": true, +"hr": true, +"it": true, +"ja": true, +"kk": true, +"ko": true, +"nb": true, +"nl": true, +"pl": true, +"pt": true, +"pt-pt": true, +"ro": true, +"ru": true, +"sk": true, +"sl": true, +"sv": true, +"th": true, +"tr": true, +"zh": true, +"zh-tw": true +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js new file mode 100644 index 0000000..f55709f --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ar/EnhancedGrid", //begin v1.x content +({ + singleSort: "فرز منفرد", + nestedSort: "فرز متداخل", + ascending: "تصاعدي", + descending: "تنازلي", + sortingState: "${0} - ${1}", + unsorted: "عدم فرز هذا العمود", + indirectSelectionRadio: "الصف ${0}، اختيار منفرد، اختيار دائري", + indirectSelectionCheckBox: "الصف ${0}، اختيارات متعددة، مربع اختيار", + selectAll: "تحديد كل" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js new file mode 100644 index 0000000..fa26b93 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js @@ -0,0 +1,90 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ar/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "محو ترشيح البيانات", + "filterDefDialogTitle": "ترشيح البيانات", + "ruleTitleTemplate": "القاعدة ${0}", + + "conditionEqual": "يساوي", + "conditionNotEqual": "لا يساوي", + "conditionLess": "أصغر من", + "conditionLessEqual": "أصغر من أو يساوي", + "conditionLarger": "أكبر من", + "conditionLargerEqual": "أكبر من أو يساوي", + "conditionContains": "يتضمن", + "conditionIs": "هو", + "conditionStartsWith": "يبدأ بالحروف", + "conditionEndWith": "ينتهي بالحروف", + "conditionNotContain": "لا يتضمن", + "conditionIsNot": "ليس", + "conditionNotStartWith": "لا يبدأ بالحروف", + "conditionNotEndWith": "لا ينتهي بالحروف", + "conditionBefore": "قبل", + "conditionAfter": "بعد", + "conditionRange": "المدى", + "conditionIsEmpty": "خالي", + + "all": "كل", + "any": "أي", + "relationAll": "كل القواعد", + "waiRelAll": "مطابقة كل القواعد التالية:", + "relationAny": "أية قواعد", + "waiRelAny": "مطابقة أي من القواعد التالية:", + "relationMsgFront": "مطابقة", + "relationMsgTail": "", + "and": "and", + "or": "or", + + "addRuleButton": "اضافة قاعدة", + "waiAddRuleButton": "اضافة قاعدة جديدة", + "removeRuleButton": "ازالة قاعدة", + "waiRemoveRuleButtonTemplate": "ازالة القاعدة ${0}", + + "cancelButton": "الغاء", + "waiCancelButton": "الغاء مربع الحوار هذا", + "clearButton": "محو", + "waiClearButton": "محو ترشيح البيانات", + "filterButton": "ترشيح البيانات", + "waiFilterButton": "احالة ترشيح البيانات", + + "columnSelectLabel": "العمود", + "waiColumnSelectTemplate": "العمود للقاعدة ${0}", + "conditionSelectLabel": "الشرط", + "waiConditionSelectTemplate": "الشرط للقاعدة ${0}", + "valueBoxLabel": "القيمة", + "waiValueBoxTemplate": "أدخل قيمة لترشيح البيانات للقاعدة ${0}", + + "rangeTo": "الى", + "rangeTemplate": "من ${0} الى ${1}", + + "statusTipHeaderColumn": "العمود", + "statusTipHeaderCondition": "القواعد", + "statusTipTitle": "خط ترشيح البيانات", + "statusTipMsg": "اضغط على خط ترشيح البيانات هنا لترشيح البيانات بناءا على القيم التي توجد في ${0}.", + "anycolumn": "أي عمود", + "statusTipTitleNoFilter": "خط ترشيح البيانات", + "statusTipTitleHasFilter": "ترشيح البيانات", + + "defaultItemsName": "بنود", + "filterBarMsgHasFilterTemplate": "يتم عرض ${0} من ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "لم يتم تطبيق أي ترشيح للبيانات.", + + "filterBarDefButton": "تعريف ترشيح البيانات", + "waiFilterBarDefButton": "ترشيح بيانات الجدول", + "a11yFilterBarDefButton": "ترشيح البيانات...", + "filterBarClearButton": "محو ترشيح البيانات", + "waiFilterBarClearButton": "محو ترشيح البيانات", + "closeFilterBarBtn": "اغلاق خط ترشيح البيانات", + + "clearFilterMsg": "سيؤدي هذا الى ازالة ترشيح البيانات وعرض كل السجلات المتاحة.", + "anyColumnOption": "أي عمود", + + "trueLabel": "متحقق", + "falseLabel": "غير متحقق" +}) +//end v1.x content +); + + + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js new file mode 100644 index 0000000..ed7a329 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ar/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} من ${1} ${0}", + "firstTip": "الصفحة الأولى", + "lastTip": "الصفحة الأخيرة", + "nextTip": "الصفحة التالية", + "prevTip": "الصفحة السابقة", + "itemTitle": "بنود", + "pageStepLabelTemplate": "الصفحة ${0}", + "pageSizeLabelTemplate": "${0} بند/بنود بكل صفحة", + "allItemsLabelTemplate": "كل البنود", + "gotoButtonTitle": "اذهب الى الصفحة المحددة", + "dialogTitle": "اذهب الى الصفحة", + "dialogIndication": "حدد رقم الصفحة", + "pageCountIndication": " (${0} صفحات)", + "dialogConfirm": "بدء", + "dialogCancel": "الغاء", + "all": "كل" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js new file mode 100644 index 0000000..b5eb2c3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ca/EnhancedGrid", //begin v1.x content +({ + singleSort: "Ordre únic", + nestedSort: "Ordre imbricat", + ascending: "Ascendent", + descending: "Descendent", + sortingState: "${0} - ${1}", + unsorted: "No ordenis aquesta finestra", + indirectSelectionRadio: "Fila ${0}, selecció única, quadre d'opció", + indirectSelectionCheckBox: "Fila ${0}, selecció múltiple, quadre de selecció", + selectAll: "Seleccionar-ho tot" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js new file mode 100644 index 0000000..f758b8d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ca/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Netejar el filtre", + "filterDefDialogTitle": "Filtre", + "ruleTitleTemplate": "Regla ${0}", + + "conditionEqual": "igual que", + "conditionNotEqual": "no és igual que", + "conditionLess": "és menys que", + "conditionLessEqual": "és menys o igual que", + "conditionLarger": "és més que", + "conditionLargerEqual": "és més o igual que", + "conditionContains": "conté", + "conditionIs": "és", + "conditionStartsWith": "comença per", + "conditionEndWith": "acaba per", + "conditionNotContain": "no conté", + "conditionIsNot": "no és", + "conditionNotStartWith": "no comença per", + "conditionNotEndWith": "no acaba per", + "conditionBefore": "abans", + "conditionAfter": "després", + "conditionRange": "interval", + "conditionIsEmpty": "és buida", + + "all": "tot", + "any": "qualsevol", + "relationAll": "totes les regles", + "waiRelAll": "Fes coincidir totes les regles següents:", + "relationAny": "qualsevol regla", + "waiRelAny": "Fes coincidir qualsevol de les regles següents:", + "relationMsgFront": "Coincidència", + "relationMsgTail": "", + "and": "i", + "or": "o", + + "addRuleButton": "Afegeix regla", + "waiAddRuleButton": "Afegeix una regla nova", + "removeRuleButton": "Elimina regla", + "waiRemoveRuleButtonTemplate": "Elimina la regla ${0}", + + "cancelButton": "Cancel·la", + "waiCancelButton": "Cancel·la aquest diàleg", + "clearButton": "Esborra", + "waiClearButton": "Neteja el filtre", + "filterButton": "Filtre", + "waiFilterButton": "Envia el filtre", + + "columnSelectLabel": "Columna", + "waiColumnSelectTemplate": "Columna per a la regla ${0}", + "conditionSelectLabel": "Condició", + "waiConditionSelectTemplate": "Condició per a la regla ${0}", + "valueBoxLabel": "Valor", + "waiValueBoxTemplate": "Especifiqueu el valor de filtre per a la regla ${0}", + + "rangeTo": "a", + "rangeTemplate": "de ${0} a ${1}", + + "statusTipHeaderColumn": "Columna", + "statusTipHeaderCondition": "Regles", + "statusTipTitle": "Barra de filtre", + "statusTipMsg": "Feu clic aquí a la barra de filtre per filtrar els valors a ${0}.", + "anycolumn": "qualsevol columna", + "statusTipTitleNoFilter": "Barra de filtre", + "statusTipTitleHasFilter": "Filtre", + "statusTipRelAny": "Coincideix amb qualsevol regla.", + "statusTipRelAll": "Coincideix amb totes les regles.", + + "defaultItemsName": "elements", + "filterBarMsgHasFilterTemplate": "Es mostren ${0} de ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "No s'ha aplicat cap filtre", + + "filterBarDefButton": "Defineix filtre", + "waiFilterBarDefButton": "Filtra la taula", + "a11yFilterBarDefButton": "Filtre...", + "filterBarClearButton": "Netejar filtre", + "waiFilterBarClearButton": "Neteja el filtre", + "closeFilterBarBtn": "Tancar la barra de filtre", + + "clearFilterMsg": "Això eliminarà el filtre i mostrarà tots els registres disponibles.", + "anyColumnOption": "Qualsevol columna", + + "trueLabel": "Cert", + "falseLabel": "Fals" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js new file mode 100644 index 0000000..74b7121 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ca/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} de ${1} ${0}", + "firstTip": "Primera pàgina", + "lastTip": "Darrera pàgina", + "nextTip": "Pàgina següent", + "prevTip": "Pàgina anterior", + "itemTitle": "elements", + "singularItemTitle": "element", + "pageStepLabelTemplate": "Pàgina ${0}", + "pageSizeLabelTemplate": "${0} elements per pàgina", + "allItemsLabelTemplate": "Tots els elements", + "gotoButtonTitle": "Vés a una pàgina específica", + "dialogTitle": "Vés a pàgina", + "dialogIndication": "Especifiqueu el número de pàgina", + "pageCountIndication": " (${0} pàgines)", + "dialogConfirm": "Vés-hi", + "dialogCancel": "Cancel·la", + "all": "tot" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js new file mode 100644 index 0000000..86191d4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/cs/EnhancedGrid", //begin v1.x content +({ + singleSort: "Jednotlivé řazení", + nestedSort: "Vnořené řazení", + ascending: "Vzestupně", + descending: "Sestupně", + sortingState: "${0} - ${1}", + unsorted: "Neřadit tento sloupec", + indirectSelectionRadio: "Řádek ${0}, jednotlivý výběr, přepínač", + indirectSelectionCheckBox: "Řádek ${0}, vícenásobný výběr, zaškrtávací políčko", + selectAll: "Vybrat vše" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js new file mode 100644 index 0000000..6157fce --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/cs/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Vymazat filtr", + "filterDefDialogTitle": "Filtr", + "ruleTitleTemplate": "Pravidlo ${0}", + + "conditionEqual": "rovná se", + "conditionNotEqual": "nerovná se", + "conditionLess": "méně než", + "conditionLessEqual": "méně nebo rovno", + "conditionLarger": "více než", + "conditionLargerEqual": "více nebo rovno", + "conditionContains": "obsahuje", + "conditionIs": "je", + "conditionStartsWith": "začíná", + "conditionEndWith": "končí", + "conditionNotContain": "neobsahuje", + "conditionIsNot": "není", + "conditionNotStartWith": "nezačíná", + "conditionNotEndWith": "nekončí", + "conditionBefore": "před", + "conditionAfter": "po", + "conditionRange": "rozsah", + "conditionIsEmpty": "je prázdné", + + "all": "vše", + "any": "jakékoli", + "relationAll": "všechna pravidla", + "waiRelAll": "Porovnat všechna tato pravidla:", + "relationAny": "jakákoli pravidla", + "waiRelAny": "Porovnat jakákoli z těchto pravidel:", + "relationMsgFront": "Shoda", + "relationMsgTail": "", + "and": "a", + "or": "nebo", + + "addRuleButton": "Přidat pravidlo", + "waiAddRuleButton": "Přidat nové pravidlo", + "removeRuleButton": "Odebrat pravidlo", + "waiRemoveRuleButtonTemplate": "Odebrat pravidlo ${0}", + + "cancelButton": "Storno", + "waiCancelButton": "Zrušit toto dialogové okno", + "clearButton": "Vymazat", + "waiClearButton": "Vymazat filtr", + "filterButton": "Filtr", + "waiFilterButton": "Odeslat filtr", + + "columnSelectLabel": "Sloupec", + "waiColumnSelectTemplate": "Sloupec pro pravidlo ${0}", + "conditionSelectLabel": "Podmínka", + "waiConditionSelectTemplate": "Podmínka pro pravidlo ${0}", + "valueBoxLabel": "Hodnota", + "waiValueBoxTemplate": "Zadejte hodnotu do filtru pro pravidlo ${0}", + + "rangeTo": "do", + "rangeTemplate": "z ${0} do ${1}", + + "statusTipHeaderColumn": "Sloupec", + "statusTipHeaderCondition": "Pravidla", + "statusTipTitle": "Panel filtrování", + "statusTipMsg": "Klepněte zde na panel filtrování, abyste filtrovali hodnoty v ${0}.", + "anycolumn": "jakýkoli sloupec", + "statusTipTitleNoFilter": "Panel filtrování", + "statusTipTitleHasFilter": "Filtr", + "statusTipRelAny": "Vyhovovat libovolnému pravidlu", + "statusTipRelAll": "Vyhovovat všem pravidlům", + + "defaultItemsName": "položek", + "filterBarMsgHasFilterTemplate": "${0} z ${1} ${2} zobrazeno.", + "filterBarMsgNoFilterTemplate": "Není použitý žádný filtr", + + "filterBarDefButton": "Definovat filtr", + "waiFilterBarDefButton": "Filtrovat tabulku", + "a11yFilterBarDefButton": "Filtrovat...", + "filterBarClearButton": "Vymazat filtr", + "waiFilterBarClearButton": "Vymazat filtr", + "closeFilterBarBtn": "Zavřít panel filtrování", + + "clearFilterMsg": "Tímto se odebere filtr a zobrazí všechny dostupné záznamy.", + "anyColumnOption": "Jakýkoli sloupec", + + "trueLabel": "Pravda", + "falseLabel": "Nepravda" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js new file mode 100644 index 0000000..2f8086d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/cs/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} z ${1} ${0}", + "firstTip": "První stránka", + "lastTip": "Poslední stránka", + "nextTip": "Další stránka", + "prevTip": "Předchozí stránka", + "itemTitle": "položky", + "singularItemTitle": "položka", + "pageStepLabelTemplate": "Stránka ${0}", + "pageSizeLabelTemplate": "${0} položek na stránku", + "allItemsLabelTemplate": "Všechny položky", + "gotoButtonTitle": "Přejít na specifickou stránku", + "dialogTitle": "Přejít na stránku", + "dialogIndication": "Uvést číslo stránky", + "pageCountIndication": " (${0} stránky)", + "dialogConfirm": "Přejít", + "dialogCancel": "Storno", + "all": "vše" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js new file mode 100644 index 0000000..331ab8f --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/da/EnhancedGrid", //begin v1.x content +({ + singleSort: "Enkelt sortering", + nestedSort: "Indlejret sortering", + ascending: "Stigende", + descending: "Faldende", + sortingState: "${0} - ${1}", + unsorted: "Sortér ikke denne kolonne", + indirectSelectionRadio: "Række ${0}, enkelt valg, valgknap", + indirectSelectionCheckBox: "Række ${0}, flere valg, afkrydsningsfelt", + selectAll: "Markér alle" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js new file mode 100644 index 0000000..c382275 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/da/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Ryd filter", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Regel ${0}", + + "conditionEqual": "lig med", + "conditionNotEqual": "er forskellig fra", + "conditionLess": "er mindre end", + "conditionLessEqual": "mindre end eller lig med", + "conditionLarger": "er større end", + "conditionLargerEqual": "større end eller lig med", + "conditionContains": "indeholder", + "conditionIs": "er", + "conditionStartsWith": "begynder med", + "conditionEndWith": "slutter med", + "conditionNotContain": "indeholder ikke", + "conditionIsNot": "er ikke", + "conditionNotStartWith": "begynder ikke med", + "conditionNotEndWith": "slutter ikke med", + "conditionBefore": "før", + "conditionAfter": "efter", + "conditionRange": "interval", + "conditionIsEmpty": "er tom", + + "all": "alle", + "any": "vilkårlig", + "relationAll": "alle regler", + "waiRelAll": "Matcher alle følgende regler:", + "relationAny": "vilkårlige regler", + "waiRelAny": "Matcher en eller flere af følgende regler:", + "relationMsgFront": "Match", + "relationMsgTail": "", + "and": "og", + "or": "eller", + + "addRuleButton": "Tilføj regel", + "waiAddRuleButton": "Tilføj en ny regel", + "removeRuleButton": "Fjern regel", + "waiRemoveRuleButtonTemplate": "Fjern reglen ${0}", + + "cancelButton": "Annullér", + "waiCancelButton": "Annullér denne dialogboks", + "clearButton": "Ryd", + "waiClearButton": "Ryd filtret", + "filterButton": "Filter", + "waiFilterButton": "Send filtret", + + "columnSelectLabel": "Kolonne", + "waiColumnSelectTemplate": "Kolonne for reglen ${0}", + "conditionSelectLabel": "Betingelse", + "waiConditionSelectTemplate": "Betingelse for reglen ${0}", + "valueBoxLabel": "Værdi", + "waiValueBoxTemplate": "Angiv værdi, der skal filtreres efter for reglen ${0}", + + "rangeTo": "til", + "rangeTemplate": "fra ${0} til ${1}", + + "statusTipHeaderColumn": "Kolonne", + "statusTipHeaderCondition": "Regler", + "statusTipTitle": "Filterlinje", + "statusTipMsg": "Klik på filterlinjen for at filtrere efter værdier i ${0}.", + "anycolumn": "vilkårlig kolonne", + "statusTipTitleNoFilter": "Filterlinje", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Matcher en hvilken som helst regel.", + "statusTipRelAll": "Matcher alle regler.", + + "defaultItemsName": "elementer", + "filterBarMsgHasFilterTemplate": "${0} af ${1} ${2} vist.", + "filterBarMsgNoFilterTemplate": "Intet filter anvendt", + + "filterBarDefButton": "Definér filter", + "waiFilterBarDefButton": "Filtrér tabellen", + "a11yFilterBarDefButton": "Filtrér...", + "filterBarClearButton": "Ryd filter", + "waiFilterBarClearButton": "Ryd filtret", + "closeFilterBarBtn": "Luk filterlinje", + + "clearFilterMsg": "Denne funktion fjerner filtret og viser alle tilgængelige records.", + "anyColumnOption": "Vilkårlig kolonne", + + "trueLabel": "Sand", + "falseLabel": "Falsk" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js new file mode 100644 index 0000000..0ebcfce --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/da/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} af ${1} ${0}", + "firstTip": "Første side", + "lastTip": "Sidste side", + "nextTip": "Næste side", + "prevTip": "Forrige side", + "itemTitle": "elementer", + "singularItemTitle": "element", + "pageStepLabelTemplate": "Side ${0}", + "pageSizeLabelTemplate": "${0} elementer pr. side", + "allItemsLabelTemplate": "Alle elementer", + "gotoButtonTitle": "Gå til en bestemt side", + "dialogTitle": "Gå til side", + "dialogIndication": "Angiv sidetallet", + "pageCountIndication": " (${0} sider)", + "dialogConfirm": "Gå", + "dialogCancel": "Annullér", + "all": "alle" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js new file mode 100644 index 0000000..120b559 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/de/EnhancedGrid", //begin v1.x content +({ + singleSort: "Einzelne Sortierung", + nestedSort: "Verschachtelte Sortierung", + ascending: "Aufsteigend", + descending: "Absteigend", + sortingState: "${0} - ${1}", + unsorted: "Diese Spalte nicht sortieren", + indirectSelectionRadio: "Zeile ${0}, einzelne Auswahl, Optionsfeld", + indirectSelectionCheckBox: "Zeile ${0}, Mehrfachauswahl, Kontrollkästchen", + selectAll: "Alles auswählen" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js new file mode 100644 index 0000000..8a1f295 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/de/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Filter löschen", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Regel ${0}", + + "conditionEqual": "gleich", + "conditionNotEqual": "ungleich", + "conditionLess": "kleiner als", + "conditionLessEqual": "kleiner-gleich", + "conditionLarger": "größer als", + "conditionLargerEqual": "größer-gleich", + "conditionContains": "enthält", + "conditionIs": "ist", + "conditionStartsWith": "beginnt mit", + "conditionEndWith": "endet mit", + "conditionNotContain": "enthält nicht", + "conditionIsNot": "ist nicht", + "conditionNotStartWith": "beginnt nicht mit", + "conditionNotEndWith": "endet nicht mit", + "conditionBefore": "vorher", + "conditionAfter": "danach", + "conditionRange": "Bereich", + "conditionIsEmpty": "ist leer", + + "all": "alle", + "any": "beliebige", + "relationAll": "alle Regeln", + "waiRelAll": "Stimmt mit allen der folgenden Regeln überein:", + "relationAny": "beliebige Regeln", + "waiRelAny": "Stimmt mit einer beliebigen der folgenden Regeln überein:", + "relationMsgFront": "Übereinstimmung", + "relationMsgTail": "", + "and": "und", + "or": "oder", + + "addRuleButton": "Regel hinzufügen", + "waiAddRuleButton": "Neue Regel hinzufügen", + "removeRuleButton": "Regel entfernen", + "waiRemoveRuleButtonTemplate": "Regel ${0} entfernen", + + "cancelButton": "Abbrechen", + "waiCancelButton": "Diesen Dialog abbrechen", + "clearButton": "Löschen", + "waiClearButton": "Den Filter löschen", + "filterButton": "Filter", + "waiFilterButton": "Den Filter abschicken", + + "columnSelectLabel": "Spalte", + "waiColumnSelectTemplate": "Spalte für Regel ${0}", + "conditionSelectLabel": "Bedingung", + "waiConditionSelectTemplate": "Bedingung für Regel ${0}", + "valueBoxLabel": "Wert", + "waiValueBoxTemplate": "Wert eingeben, um nach Regel ${0} zu filtern", + + "rangeTo": "bis", + "rangeTemplate": "von ${0} bis ${1}", + + "statusTipHeaderColumn": "Spalte", + "statusTipHeaderCondition": "Regeln", + "statusTipTitle": "Filterleiste", + "statusTipMsg": "Klicken Sie auf die Filterleiste hier, um nach Werten in ${0} zu filtern.", + "anycolumn": "beliebige Spalte", + "statusTipTitleNoFilter": "Filterleiste", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Übereinstimmung mit einer oder mehreren beliebigen Regeln.", + "statusTipRelAll": "Übereinstimmung mit allen Regeln.", + + "defaultItemsName": "Elemente", + "filterBarMsgHasFilterTemplate": "${0} von ${1} ${2} angezeigt.", + "filterBarMsgNoFilterTemplate": "Kein Filter angewendet", + + "filterBarDefButton": "Filter definieren", + "waiFilterBarDefButton": "Die Tabelle filtern", + "a11yFilterBarDefButton": "Filter...", + "filterBarClearButton": "Filter löschen", + "waiFilterBarClearButton": "Den Filter löschen", + "closeFilterBarBtn": "Filterleiste schließen", + + "clearFilterMsg": "Damit wird der Filter gelöscht und es werden alle verfügbaren Sätze angezeigt.", + "anyColumnOption": "Beliebige Spalte", + + "trueLabel": "Wahr", + "falseLabel": "Falsch" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js new file mode 100644 index 0000000..67f173e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/de/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} von ${1} ${0}", + "firstTip": "Erste Seite", + "lastTip": "Letzte Seite", + "nextTip": "Nächste Seite", + "prevTip": "Vorherige Seite", + "itemTitle": "Elemente", + "singularItemTitle": "Element", + "pageStepLabelTemplate": "Seite ${0}", + "pageSizeLabelTemplate": "${0} Elemente pro Seite", + "allItemsLabelTemplate": "Alle Elemente", + "gotoButtonTitle": "Bestimmte Seite aufrufen", + "dialogTitle": "Seite aufrufen", + "dialogIndication": "Seitenzahl angeben", + "pageCountIndication": " (${0} Seiten)", + "dialogConfirm": "Start", + "dialogCancel": "Abbrechen", + "all": "alle" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js new file mode 100644 index 0000000..e1179cc --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/el/EnhancedGrid", //begin v1.x content +({ + singleSort: "Απλή ταξινόμηση", + nestedSort: "Ένθετη ταξινόμηση", + ascending: "Αύξουσα", + descending: "Φθίνουσα", + sortingState: "${0} - ${1}", + unsorted: "Χωρίς ταξινόμηση αυτής της στήλης", + indirectSelectionRadio: "Γραμμή ${0}, μονή επιλογή, κουμπί επιλογής", + indirectSelectionCheckBox: "Γραμμή ${0}, πολλαπλές επιλογές, τετραγωνίδιο επιλογής", + selectAll: "Επιλογή όλων" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js new file mode 100644 index 0000000..cf1a917 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/el/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Εκκαθάριση φίλτρου", + "filterDefDialogTitle": "Φίλτρο", + "ruleTitleTemplate": "Κανόνας ${0}", + + "conditionEqual": "ίσο", + "conditionNotEqual": "όχι ίσο", + "conditionLess": "είναι μικρότερο από", + "conditionLessEqual": "μικρότερο ή ίσο", + "conditionLarger": "είναι μεγαλύτερο από", + "conditionLargerEqual": "μεγαλύτερο ή ίσο", + "conditionContains": "περιέχει", + "conditionIs": "είναι", + "conditionStartsWith": "αρχίζει από", + "conditionEndWith": "τελειώνει σε", + "conditionNotContain": "δεν περιέχει", + "conditionIsNot": "δεν είναι", + "conditionNotStartWith": "δεν αρχίζει από", + "conditionNotEndWith": "δεν τελειώνει σε", + "conditionBefore": "πριν", + "conditionAfter": "μετά", + "conditionRange": "εύρος", + "conditionIsEmpty": "είναι κενό", + + "all": "όλα", + "any": "οποιοδήποτε", + "relationAll": "όλοι οι κανόνες", + "waiRelAll": "Αντιστοιχία με όλους τους παρακάτω κανόνες:", + "relationAny": "οποιοσδήποτε κανόνας", + "waiRelAny": "Αντιστοιχία με οποιονδήποτε από τους παρακάτω κανόνες:", + "relationMsgFront": "Αντιστοιχία", + "relationMsgTail": "", + "and": "και", + "or": "ή", + + "addRuleButton": "Προσθήκη κανόνα", + "waiAddRuleButton": "Προσθήκη νέου κανόνα", + "removeRuleButton": "Αφαίρεση κανόνα", + "waiRemoveRuleButtonTemplate": "Αφαίρεση κανόνα ${0}", + + "cancelButton": "Ακύρωση", + "waiCancelButton": "Ακύρωση αυτού του πλαισίου διαλόγου", + "clearButton": "Εκκαθάριση", + "waiClearButton": "Εκκαθάριση του φίλτρου", + "filterButton": "Φίλτρο", + "waiFilterButton": "Υποβολή του φίλτρου", + + "columnSelectLabel": "Στήλη", + "waiColumnSelectTemplate": "Στήλη για τον κανόνα ${0}", + "conditionSelectLabel": "Συνθήκη", + "waiConditionSelectTemplate": "Συνθήκη για τον κανόνα ${0}", + "valueBoxLabel": "Τιμή", + "waiValueBoxTemplate": "Καταχωρήστε τιμή φίλτρου για τον κανόνα ${0}", + + "rangeTo": "έως", + "rangeTemplate": "από ${0} έως ${1}", + + "statusTipHeaderColumn": "Στήλη", + "statusTipHeaderCondition": "Κανόνες", + "statusTipTitle": "Γραμμή φίλτρου", + "statusTipMsg": "Πατήστε στη γραμμή φίλτρου για φιλτράρισμα με βάση τις τιμές στο ${0}.", + "anycolumn": "οποιαδήποτε στήλη", + "statusTipTitleNoFilter": "Γραμμή φίλτρου", + "statusTipTitleHasFilter": "Φίλτρο", + "statusTipRelAny": "Αντιστοιχία με οποιουσδήποτε κανόνες.", + "statusTipRelAll": "Αντιστοιχία με όλους τους κανόνες.", + + "defaultItemsName": "στοιχεία", + "filterBarMsgHasFilterTemplate": "Εμφανίζονται ${0} από ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "Δεν έχει εφαρμοστεί φίλτρο", + + "filterBarDefButton": "Ορισμός φίλτρου", + "waiFilterBarDefButton": "Φιλτράρισμα του πίνακα", + "a11yFilterBarDefButton": "Φιλτράρισμα...", + "filterBarClearButton": "Εκκαθάριση φίλτρου", + "waiFilterBarClearButton": "Εκκαθάριση του φίλτρου", + "closeFilterBarBtn": "Κλείσιμο γραμμής φίλτρου", + + "clearFilterMsg": "Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.", + "anyColumnOption": "Οποιαδήποτε στήλη", + + "trueLabel": "Αληθές", + "falseLabel": "Ψευδές" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js new file mode 100644 index 0000000..b03e995 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/el/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} από ${1} ${0}", + "firstTip": "Πρώτη σελίδα", + "lastTip": "Τελευταία σελίδα", + "nextTip": "Επόμενη σελίδα", + "prevTip": "Προηγούμενη σελίδα", + "itemTitle": "στοιχεία", + "singularItemTitle": "στοιχείο", + "pageStepLabelTemplate": "Σελίδα ${0}", + "pageSizeLabelTemplate": "${0} στοιχεία ανά σελίδα", + "allItemsLabelTemplate": "Όλα τα στοιχεία", + "gotoButtonTitle": "Μετάβαση σε συγκεκριμένη σελίδα", + "dialogTitle": "Μετάβαση σε σελίδα", + "dialogIndication": "Καθορίστε τον αριθμό της σελίδας", + "pageCountIndication": " (${0} σελίδες)", + "dialogConfirm": "Μετάβαση", + "dialogCancel": "Ακύρωση", + "all": "όλα" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js new file mode 100644 index 0000000..5886b73 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/es/EnhancedGrid", //begin v1.x content +({ + singleSort: "Orden único", + nestedSort: "Orden anidado", + ascending: "Ascendente", + descending: "Descendente", + sortingState: "${0} - ${1}", + unsorted: "No ordenar esta columna", + indirectSelectionRadio: "Fila ${0}, selección única, botón de selección", + indirectSelectionCheckBox: "Fila ${0}, selección múltiple, recuadro de selección", + selectAll: "Seleccionar todo" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js new file mode 100644 index 0000000..8994bb5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/es/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Borrar filtro", + "filterDefDialogTitle": "Filtro", + "ruleTitleTemplate": "Regla ${0}", + + "conditionEqual": "es igual a", + "conditionNotEqual": "no es igual a", + "conditionLess": "es menor que", + "conditionLessEqual": "es menor o igual que", + "conditionLarger": "es mayor que", + "conditionLargerEqual": "es mayor o igual que", + "conditionContains": "contiene", + "conditionIs": "es", + "conditionStartsWith": "empieza por", + "conditionEndWith": "acaba por", + "conditionNotContain": "no contiene", + "conditionIsNot": "no es", + "conditionNotStartWith": "no empieza por", + "conditionNotEndWith": "no acaba por", + "conditionBefore": "antes", + "conditionAfter": "después", + "conditionRange": "rango", + "conditionIsEmpty": "está vacío", + + "all": "todas", + "any": "cualquiera", + "relationAll": "todas las reglas", + "waiRelAll": "Coincidir con todas las reglas siguientes:", + "relationAny": "cualquier regla", + "waiRelAny": "Coincidir con cualquiera de las reglas siguientes:", + "relationMsgFront": "Coincidir", + "relationMsgTail": "", + "and": "y", + "or": "o", + + "addRuleButton": "Añadir regla", + "waiAddRuleButton": "Añadir una regla nueva", + "removeRuleButton": "Eliminar regla", + "waiRemoveRuleButtonTemplate": "Eliminar la regla ${0}", + + "cancelButton": "Cancelar", + "waiCancelButton": "Cancelar este diálogo", + "clearButton": "Borrar", + "waiClearButton": "Borrar el filtro", + "filterButton": "Filtrar", + "waiFilterButton": "Enviar el filtro", + + "columnSelectLabel": "Columna", + "waiColumnSelectTemplate": "Columna para la regla ${0}", + "conditionSelectLabel": "Condición", + "waiConditionSelectTemplate": "Condición para la regla ${0}", + "valueBoxLabel": "Valor", + "waiValueBoxTemplate": "Escriba el valor que se debe filtrar para la regla ${0}", + + "rangeTo": "a", + "rangeTemplate": "de ${0} a ${1}", + + "statusTipHeaderColumn": "Columna", + "statusTipHeaderCondition": "Reglas", + "statusTipTitle": "Barra de filtro", + "statusTipMsg": "Pulse aquí en la barra de filtro para filtrar por los valores de ${0}.", + "anycolumn": "cualquier columna", + "statusTipTitleNoFilter": "Barra de filtro", + "statusTipTitleHasFilter": "Filtro", + "statusTipRelAny": "Coincidir con cualquier regla.", + "statusTipRelAll": "Coincidir con todas las reglas.", + + "defaultItemsName": "elementos", + "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.", + "filterBarMsgNoFilterTemplate": "Ningún filtro aplicado", + + "filterBarDefButton": "Definir filtro", + "waiFilterBarDefButton": "Filtrar la tabla", + "a11yFilterBarDefButton": "Filtrar...", + "filterBarClearButton": "Borrar filtro", + "waiFilterBarClearButton": "Borrar el filtro", + "closeFilterBarBtn": "Cerrar barra de filtro", + + "clearFilterMsg": "Esto eliminará el filtro y mostrará todos los registros disponibles.", + "anyColumnOption": "Cualquier columna", + + "trueLabel": "Verdadero", + "falseLabel": "Falso" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js new file mode 100644 index 0000000..6bcc4da --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/es/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} de ${1} ${0}", + "firstTip": "Primera página", + "lastTip": "Última página", + "nextTip": "Página siguiente", + "prevTip": "Página anterior", + "itemTitle": "elementos", + "singularItemTitle": "elemento", + "pageStepLabelTemplate": "Página ${0}", + "pageSizeLabelTemplate": "${0} elementos por página", + "allItemsLabelTemplate": "Todos los elementos", + "gotoButtonTitle": "Ir a una página específica", + "dialogTitle": "Ir a página", + "dialogIndication": "Especifique el número de página", + "pageCountIndication": " (${0} páginas)", + "dialogConfirm": "Ir", + "dialogCancel": "Cancelar", + "all": "todas" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js new file mode 100644 index 0000000..307794a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/fi/EnhancedGrid", //begin v1.x content +({ + singleSort: "Yksinkertainen lajittelu", + nestedSort: "Sisäkkäinen lajittelu", + ascending: "Nouseva", + descending: "Laskeva", + sortingState: "${0} - ${1}", + unsorted: "Älä lajittele tätä saraketta", + indirectSelectionRadio: "Rivi ${0}, yksittäisvalinta, ruutu", + indirectSelectionCheckBox: "Rivi ${0}, monivalinta, valintaruutu", + selectAll: "Valitse kaikki" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js new file mode 100644 index 0000000..e2a5346 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/fi/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Tyhjennä suodatin", + "filterDefDialogTitle": "Suodatin", + "ruleTitleTemplate": "Sääntö ${0}", + + "conditionEqual": "yhtä suuri kuin", + "conditionNotEqual": "ei ole yhtä suuri kuin", + "conditionLess": "on pienempi kuin", + "conditionLessEqual": "pienempi tai yhtä suuri kuin", + "conditionLarger": "on suurempi kuin", + "conditionLargerEqual": "suurempi tai yhtä suuri kuin", + "conditionContains": "sisältää", + "conditionIs": "on", + "conditionStartsWith": "alussa on", + "conditionEndWith": "lopussa on", + "conditionNotContain": "ei sisällä", + "conditionIsNot": "ei ole", + "conditionNotStartWith": "alussa ei ole", + "conditionNotEndWith": "lopussa ei ole", + "conditionBefore": "ennen", + "conditionAfter": "jälkeen", + "conditionRange": "vaihtelualue", + "conditionIsEmpty": "on tyhjä", + + "all": "kaikki", + "any": "mikä tahansa", + "relationAll": "kaikki säännöt", + "waiRelAll": "Täsmäytä kaikki seuraavat säännöt:", + "relationAny": "mitkä tahansa säännöt", + "waiRelAny": "Täsmäytä mitkä tahansa seuraavista säännöistä:", + "relationMsgFront": "Vastine", + "relationMsgTail": "", + "and": "ja", + "or": "tai", + + "addRuleButton": "Lisää sääntö", + "waiAddRuleButton": "Lisää uusi sääntö", + "removeRuleButton": "Poista sääntö", + "waiRemoveRuleButtonTemplate": "Poista sääntö ${0}", + + "cancelButton": "Peruuta", + "waiCancelButton": "Peruuta keskustelu", + "clearButton": "Tyhjennä", + "waiClearButton": "Tyhjennä suodatin", + "filterButton": "Suodata", + "waiFilterButton": "Lähetä suodatin", + + "columnSelectLabel": "Sarake", + "waiColumnSelectTemplate": "Säännön ${0} sarake", + "conditionSelectLabel": "Ehto", + "waiConditionSelectTemplate": "Säännön ${0} ehto", + "valueBoxLabel": "Arvo", + "waiValueBoxTemplate": "Syötä säännön ${0} suodatettava arvo", + + "rangeTo": "kohde", + "rangeTemplate": "lähde ${0}, kohde ${1}", + + "statusTipHeaderColumn": "Sarake", + "statusTipHeaderCondition": "Säännöt", + "statusTipTitle": "Suodatinpalkki", + "statusTipMsg": "Napsauta suodatinpalkkia kohteen ${0} arvojen suodattamiseksi.", + "anycolumn": "mikä tahansa sarake", + "statusTipTitleNoFilter": "Suodatinpalkki", + "statusTipTitleHasFilter": "Suodatin", + "statusTipRelAny": "Vastaa jotakin sääntöä.", + "statusTipRelAll": "Vastaa kaikkia sääntöjä.", + + "defaultItemsName": "nimikkeet", + "filterBarMsgHasFilterTemplate": "näkyvissä ${0} / ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "Mikään suodatin ei ole käytössä", + + "filterBarDefButton": "Määritä suodatin", + "waiFilterBarDefButton": "Suodata taulukko", + "a11yFilterBarDefButton": "Suodata...", + "filterBarClearButton": "Tyhjennä suodatin", + "waiFilterBarClearButton": "Tyhjennä suodatin", + "closeFilterBarBtn": "Sulje suodatinpalkki", + + "clearFilterMsg": "Tämä toimenpide poistaa suodattimen ja näyttää kaikki saatavilla olevat tallenteet.", + "anyColumnOption": "Mikä tahansa sarake", + + "trueLabel": "Tosi", + "falseLabel": "Epätosi" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js new file mode 100644 index 0000000..beae77a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/fi/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} / ${1} ${0}", + "firstTip": "Ensimmäinen sivu", + "lastTip": "Viimeinen sivu", + "nextTip": "Seuraava sivu", + "prevTip": "Edellinen sivu", + "itemTitle": "nimikkeet", + "singularItemTitle": "kohde", + "pageStepLabelTemplate": "Sivu ${0}", + "pageSizeLabelTemplate": "${0} nimikettä sivua kohti", + "allItemsLabelTemplate": "Kaikki nimikkeet", + "gotoButtonTitle": "Siirry tietylle sivulle", + "dialogTitle": "Siirry sivulle", + "dialogIndication": "Kirjoita sivunumero", + "pageCountIndication": " (${0} sivua)", + "dialogConfirm": "Siirry", + "dialogCancel": "Peruuta", + "all": "kaikki" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js new file mode 100644 index 0000000..d1ee539 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/fr/EnhancedGrid", //begin v1.x content +({ + singleSort: "Tri simple", + nestedSort: "Tri imbriqué", + ascending: "Croissant", + descending: "Décroissant", + sortingState: "${0} - ${1}", + unsorted: "Ne pas trier cette colonne", + indirectSelectionRadio: "Ligne ${0}, sélection unique, bouton radio", + indirectSelectionCheckBox: "Ligne ${0}, sélection multiple, case à cocher", + selectAll: "Tout sélectionner" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js new file mode 100644 index 0000000..9295240 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/fr/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Effacer le filtre", + "filterDefDialogTitle": "Filtrer", + "ruleTitleTemplate": "Règle ${0}", + + "conditionEqual": "égal", + "conditionNotEqual": "est différent de", + "conditionLess": "est inférieur à", + "conditionLessEqual": "inférieur ou égal", + "conditionLarger": "est supérieur à", + "conditionLargerEqual": "supérieur ou égal", + "conditionContains": "contient", + "conditionIs": "est", + "conditionStartsWith": "commence par", + "conditionEndWith": "se termine par", + "conditionNotContain": "ne contient pas", + "conditionIsNot": "n'est pas", + "conditionNotStartWith": "ne commence pas par", + "conditionNotEndWith": "ne se termine pas par", + "conditionBefore": "avant", + "conditionAfter": "après", + "conditionRange": "plage", + "conditionIsEmpty": "est vide", + + "all": "tout", + "any": "n'importe quelle", + "relationAll": "toutes les règles", + "waiRelAll": "Satisfaire à toutes les règles suivantes :", + "relationAny": "n'importe quelles règles", + "waiRelAny": "Satisfaire à une quelconque des règles suivantes :", + "relationMsgFront": "Satisfaire", + "relationMsgTail": "", + "and": "et", + "or": "ou", + + "addRuleButton": "Ajouter une règle", + "waiAddRuleButton": "Ajouter une nouvelle règle", + "removeRuleButton": "Supprimer la règle", + "waiRemoveRuleButtonTemplate": "Supprimer la règle ${0}", + + "cancelButton": "Annuler", + "waiCancelButton": "Annuler cette boîte de dialogue", + "clearButton": "Effacer", + "waiClearButton": "Effacer le filtre", + "filterButton": "Filtrer", + "waiFilterButton": "Soumettre le filtre", + + "columnSelectLabel": "Colonne", + "waiColumnSelectTemplate": "Colonne pour la règle ${0}", + "conditionSelectLabel": "Condition", + "waiConditionSelectTemplate": "Condition pour la règle ${0}", + "valueBoxLabel": "Valeur", + "waiValueBoxTemplate": "Saisir la valeur à filtrer pour la règle ${0}", + + "rangeTo": "à", + "rangeTemplate": "de ${0} à ${1}", + + "statusTipHeaderColumn": "Colonne", + "statusTipHeaderCondition": "Règles", + "statusTipTitle": "Barre de filtre", + "statusTipMsg": "Cliquer sur la barre de filtre ici pour filtrer sur les valeurs de ${0}.", + "anycolumn": "n'importe quelle colonne", + "statusTipTitleNoFilter": "Barre de filtre", + "statusTipTitleHasFilter": "Filtrer", + "statusTipRelAny": "Répondre à l'une des règles.", + "statusTipRelAll": "Réponde à toutes les régles.", + + "defaultItemsName": "éléments", + "filterBarMsgHasFilterTemplate": "${0} sur ${1} ${2} affichés.", + "filterBarMsgNoFilterTemplate": "Aucun filtre appliqué", + + "filterBarDefButton": "Définir le filtre", + "waiFilterBarDefButton": "Filtrer le tableau", + "a11yFilterBarDefButton": "Filtrer...", + "filterBarClearButton": "Effacer le filtre", + "waiFilterBarClearButton": "Effacer le filtre", + "closeFilterBarBtn": "Fermer la barre de filtre", + + "clearFilterMsg": "Cela supprimera le filtre et affichera tous les enregistrements disponibles.", + "anyColumnOption": "N'importe quelle colonne", + + "trueLabel": "Vrai", + "falseLabel": "Faux" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js new file mode 100644 index 0000000..b9f614d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/fr/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} sur ${1} ${0}", + "firstTip": "Première page", + "lastTip": "Dernière page", + "nextTip": "Page suivante", + "prevTip": "Page précédente", + "itemTitle": "éléments", + "singularItemTitle": "élément", + "pageStepLabelTemplate": "Page ${0}", + "pageSizeLabelTemplate": "${0} éléments par page", + "allItemsLabelTemplate": "Tous les éléments", + "gotoButtonTitle": "Accéder à une page spécifique", + "dialogTitle": "Accéder à la page", + "dialogIndication": "Indiquer le numéro de page", + "pageCountIndication": " (${0} pages)", + "dialogConfirm": "Accès", + "dialogCancel": "Annuler", + "all": "tout" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js new file mode 100644 index 0000000..b161267 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/he/EnhancedGrid", //begin v1.x content +({ + singleSort: "מיון יחיד", + nestedSort: "מיון מקונן", + ascending: "עולה", + descending: "יורד", + sortingState: "${0} - ${1}", + unsorted: "אין למיין עמודה זו", + indirectSelectionRadio: "שורה ${0}, בחירה יחידה, תיבת בחירה", + indirectSelectionCheckBox: "שורה ${0}, בחירה מרובה, תיבת סימון", + selectAll: "בחירת הכל" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js new file mode 100644 index 0000000..5dd2eaa --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js @@ -0,0 +1,90 @@ +//>>built +define( +"dojox/grid/enhanced/nls/he/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "ניקוי מסנן", + "filterDefDialogTitle": "מסנן", + "ruleTitleTemplate": "כלל ${0}", + + "conditionEqual": "שווה", + "conditionNotEqual": "לא שווה", + "conditionLess": "קטן מ", + "conditionLessEqual": "קטן או שווה", + "conditionLarger": "גדול מ", + "conditionLargerEqual": "גדול או שווה", + "conditionContains": "מכיל", + "conditionIs": "הוא", + "conditionStartsWith": "מתחיל ב", + "conditionEndWith": "מסתיים ב", + "conditionNotContain": "לא מכיל", + "conditionIsNot": "אינו", + "conditionNotStartWith": "לא מתחיל ב", + "conditionNotEndWith": "לא מסתיים ב", + "conditionBefore": "לפני", + "conditionAfter": "אחרי", + "conditionRange": "טווח", + "conditionIsEmpty": "ריק", + + "all": "הכל", + "any": "כל", + "relationAll": "כל הכללים", + "waiRelAll": "התאמה לכל הכללים הבאים:", + "relationAny": "כל כלל שהוא", + "waiRelAny": "התאמה לכל אחד מהכללים הבאים:", + "relationMsgFront": "התאמה", + "relationMsgTail": "", + "and": "ו", + "or": "או", + + "addRuleButton": "הוספת כלל", + "waiAddRuleButton": "הוספת כלל חדש", + "removeRuleButton": "סילוק כלל", + "waiRemoveRuleButtonTemplate": "סילוק כלל ${0}", + + "cancelButton": "ביטול", + "waiCancelButton": "ביטול תיבת דו-שיח זו", + "clearButton": "ניקוי", + "waiClearButton": "ניקוי המסנן", + "filterButton": "מסנן", + "waiFilterButton": "הגשת המסנן", + + "columnSelectLabel": "עמודה", + "waiColumnSelectTemplate": "עמודה עבור כלל ${0}", + "conditionSelectLabel": "תנאי", + "waiConditionSelectTemplate": "תנאי עבור כלל ${0}", + "valueBoxLabel": "ערך", + "waiValueBoxTemplate": "ציון ערך לסינון עבור כלל ${0}", + + "rangeTo": "עד", + "rangeTemplate": "מ-${0} עד ${1}", + + "statusTipHeaderColumn": "עמודה", + "statusTipHeaderCondition": "כללים", + "statusTipTitle": "סרגל סינון", + "statusTipMsg": "לחצו על סרגל הסינון כאן כדי לסנן ערכים ב-${0}.", + "anycolumn": "כל עמודה", + "statusTipTitleNoFilter": "סרגל סינון", + "statusTipTitleHasFilter": "מסנן", + + "defaultItemsName": "פריטים", + "filterBarMsgHasFilterTemplate": "מוצג ${0} מתוך ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "לא הוחל מסנן", + + "filterBarDefButton": "הגדרת מסנן", + "waiFilterBarDefButton": "סינון הטבלה", + "a11yFilterBarDefButton": "מסנן...", + "filterBarClearButton": "ניקוי מסנן", + "waiFilterBarClearButton": "ניקוי המסנן", + "closeFilterBarBtn": "סגירת סרגל סינון", + + "clearFilterMsg": "פעולה זו תגרום לסילוק המסנן ולהצגת כל הרשומות הזמינות.", + "anyColumnOption": "כל עמודה", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); + + + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js new file mode 100644 index 0000000..b343a44 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/he/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} מתוך ${1} ${0}", + "firstTip": "עמוד ראשון", + "lastTip": "עמוד אחרון", + "nextTip": "העמוד הבא", + "prevTip": "העמוד הקודם", + "itemTitle": "פריטים", + "pageStepLabelTemplate": "עמוד ${0}", + "pageSizeLabelTemplate": "${0} פריטים לעמוד", + "allItemsLabelTemplate": "כל הפריטים", + "gotoButtonTitle": "מעבר לעמוד ספציפי", + "dialogTitle": "מעבר לעמוד", + "dialogIndication": "ציון מספר העמוד", + "pageCountIndication": " (${0} עמודים)", + "dialogConfirm": "ביצוע", + "dialogCancel": "ביטול", + "all": "הכל" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js new file mode 100644 index 0000000..b97c618 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/hr/EnhancedGrid", //begin v1.x content +({ + singleSort: "Jedan sort", + nestedSort: "Ugniježđeni sort", + ascending: "Uzlazno", + descending: "Silazno", + sortingState: "${0} - ${1}", + unsorted: "Ne sortiraj ovaj stupac", + indirectSelectionRadio: "Red ${0}, jedan izbor, radio kućica", + indirectSelectionCheckBox: "Red ${0}, više izbora, kontrolna kućica", + selectAll: "Izaberi sve" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js new file mode 100644 index 0000000..8494a50 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/hr/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Brisanje filtera", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Pravilo ${0}", + + "conditionEqual": "jednako", + "conditionNotEqual": "nije jednako", + "conditionLess": "je manje od", + "conditionLessEqual": "manje ili jednako", + "conditionLarger": "je veće od", + "conditionLargerEqual": "veće ili jednako", + "conditionContains": "sadrži", + "conditionIs": "je", + "conditionStartsWith": "počinje sa", + "conditionEndWith": "završava sa", + "conditionNotContain": "ne sadrži", + "conditionIsNot": "nije", + "conditionNotStartWith": "ne počinje sa", + "conditionNotEndWith": "ne završava sa", + "conditionBefore": "prije", + "conditionAfter": "poslije", + "conditionRange": "raspon", + "conditionIsEmpty": "je prazan", + + "all": "svi", + "any": "bilo koji", + "relationAll": "sva pravila", + "waiRelAll": "Usporedi sva sljedeća pravila:", + "relationAny": "bilo koja pravila", + "waiRelAny": "Usporedi bilo koje od sljedećih pravila:", + "relationMsgFront": "Odgovara", + "relationMsgTail": "", + "and": "i", + "or": "ili", + + "addRuleButton": "Bilo koje pravilo", + "waiAddRuleButton": "Dodaj novo pravilo", + "removeRuleButton": "Ukloni pravilo", + "waiRemoveRuleButtonTemplate": "Ukloni pravilo ${0}", + + "cancelButton": "Opoziv", + "waiCancelButton": "Opoziv ovog dijaloga", + "clearButton": "Obriši", + "waiClearButton": "Obriši filter", + "filterButton": "Filter", + "waiFilterButton": "Predaj filter", + + "columnSelectLabel": "Stupac", + "waiColumnSelectTemplate": "Stupac za pravilo ${0}", + "conditionSelectLabel": "Uvjet", + "waiConditionSelectTemplate": "Uvjet za pravilo ${0}", + "valueBoxLabel": "Vrijednost", + "waiValueBoxTemplate": "Unesite vrijednost filtera za pravilo ${0}", + + "rangeTo": "do", + "rangeTemplate": "od ${0} do ${1}", + + "statusTipHeaderColumn": "Stupac", + "statusTipHeaderCondition": "Pravila", + "statusTipTitle": "Traka filtera", + "statusTipMsg": "Kliknite traku filtera za filtriranje po vrijednostima u ${0}.", + "anycolumn": "bilo koji stupac", + "statusTipTitleNoFilter": "Traka filtera", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Usporedi bilo koja pravila.", + "statusTipRelAll": "Usporedi sva pravila.", + + "defaultItemsName": "stavke", + "filterBarMsgHasFilterTemplate": "${0} od ${1} ${2} prikazano.", + "filterBarMsgNoFilterTemplate": "Filter nije primijenjen", + + "filterBarDefButton": "Definiraj filter", + "waiFilterBarDefButton": "Filtriraj tablicu", + "a11yFilterBarDefButton": "Filtriraj...", + "filterBarClearButton": "Obriši filter", + "waiFilterBarClearButton": "Obriši filter", + "closeFilterBarBtn": "Zatvori traku filtera", + + "clearFilterMsg": "Ovo uklanja filter i prikazuje sve raspoložive slogove.", + "anyColumnOption": "Bilo koji stupac", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js new file mode 100644 index 0000000..4ddd71b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/hr/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} od ${1} ${0}", + "firstTip": "Prva stranica", + "lastTip": "Zadnja stranica", + "nextTip": "Sljedeća stranica", + "prevTip": "Prethodna stranica", + "itemTitle": "stavke", + "singularItemTitle": "stavka", + "pageStepLabelTemplate": "Strana ${0}", + "pageSizeLabelTemplate": "${0} stavki po stranici", + "allItemsLabelTemplate": "Sve stavke", + "gotoButtonTitle": "Idi na određenu stranicu", + "dialogTitle": "Idi na stranicu", + "dialogIndication": "Navedite broj stranice", + "pageCountIndication": " (${0} stranica)", + "dialogConfirm": "Idi", + "dialogCancel": "Opoziv", + "all": "svi" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js new file mode 100644 index 0000000..d8d4f9a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/hu/EnhancedGrid", //begin v1.x content +({ + singleSort: "Egyszerű rendezés", + nestedSort: "Beágyazott rendezés", + ascending: "Növekvő", + descending: "Csökkenő", + sortingState: "${0} - ${1}", + unsorted: "Ne rendezze ezt az oszlopot", + indirectSelectionRadio: "${0} sor, egyetlen kijelölés, választógomb", + indirectSelectionCheckBox: "${0} sor, több kijelölés, jelölőnégyzet", + selectAll: "Összes kijelölése" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js new file mode 100644 index 0000000..8dd5943 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/hu/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Szűrő törlése", + "filterDefDialogTitle": "Szűrő", + "ruleTitleTemplate": "${0} szabály", + + "conditionEqual": "egyenlő", + "conditionNotEqual": "nem egyenlő", + "conditionLess": "kisebb mint", + "conditionLessEqual": "kisebb vagy egyenlő", + "conditionLarger": "nagyobb mint", + "conditionLargerEqual": "nagyobb vagy egyenlő", + "conditionContains": "tartalmazza", + "conditionIs": "pontosan", + "conditionStartsWith": "kezdete", + "conditionEndWith": "vége", + "conditionNotContain": "nem tartalmazza", + "conditionIsNot": "nem", + "conditionNotStartWith": "nem kezdete", + "conditionNotEndWith": "nem vége", + "conditionBefore": "előtt", + "conditionAfter": "után", + "conditionRange": "tartomány", + "conditionIsEmpty": "üres", + + "all": "mind", + "any": "bármely", + "relationAll": "minden szabály", + "waiRelAll": "Megfelel a következő összes szabálynak:", + "relationAny": "bármely szabály", + "waiRelAny": "Megfelel a következő bármely szabálynak:", + "relationMsgFront": "Egyezik", + "relationMsgTail": "", + "and": "és", + "or": "vagy", + + "addRuleButton": "Szabály hozzáadása", + "waiAddRuleButton": "Új szabály hozzáadása", + "removeRuleButton": "Szabály eltávolítása", + "waiRemoveRuleButtonTemplate": "${0} szabály eltávolítása", + + "cancelButton": "Mégse", + "waiCancelButton": "A párbeszédablak bezárása", + "clearButton": "Törlés", + "waiClearButton": "A szűrő törlése", + "filterButton": "Szűrő", + "waiFilterButton": "A szűrő elküldése", + + "columnSelectLabel": "Oszlop", + "waiColumnSelectTemplate": "Oszlop a(z) ${0} szabályhoz", + "conditionSelectLabel": "Feltétel", + "waiConditionSelectTemplate": "Feltétel a(z) ${0} szabályhoz", + "valueBoxLabel": "Érték", + "waiValueBoxTemplate": "Írja be a szűrni kívánt értéket a(z) ${0} szabályhoz", + + "rangeTo": "-", + "rangeTemplate": "${0} - ${1}", + + "statusTipHeaderColumn": "Oszlop", + "statusTipHeaderCondition": "Szabályok", + "statusTipTitle": "Szűrősáv", + "statusTipMsg": "Kattintson a szűrősávra az értékek szűréséhez a következőben: ${0}.", + "anycolumn": "bármely oszlop", + "statusTipTitleNoFilter": "Szűrősáv", + "statusTipTitleHasFilter": "Szűrő", + "statusTipRelAny": "Bármely szabálynak megfelel.", + "statusTipRelAll": "Minden szabálynak megfelel.", + + "defaultItemsName": "elemek", + "filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} megjelenítve.", + "filterBarMsgNoFilterTemplate": "Nincs szűrő alkalmazva.", + + "filterBarDefButton": "Szűrő meghatározása", + "waiFilterBarDefButton": "Táblázat szűrése", + "a11yFilterBarDefButton": "Szűrés...", + "filterBarClearButton": "Szűrő törlése", + "waiFilterBarClearButton": "A szűrő törlése", + "closeFilterBarBtn": "Szűrősáv bezárása", + + "clearFilterMsg": "Eltávolítja a szűrőt és megjeleníti az összes elérhető rekordot.", + "anyColumnOption": "Bármely oszlop", + + "trueLabel": "Igaz", + "falseLabel": "Hamis" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js new file mode 100644 index 0000000..51ff037 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/hu/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} / ${1} ${0}", + "firstTip": "Első oldal", + "lastTip": "Utolsó oldal", + "nextTip": "Következő oldal", + "prevTip": "Előző oldal", + "itemTitle": "elemek", + "singularItemTitle": "elem", + "pageStepLabelTemplate": "${0}. oldal", + "pageSizeLabelTemplate": "${0} elem oldalanként", + "allItemsLabelTemplate": "Összes elem", + "gotoButtonTitle": "Ugrás adott oldalra", + "dialogTitle": "Ugrás adott oldalra", + "dialogIndication": "Adja meg az oldalszámot", + "pageCountIndication": " (${0} oldal)", + "dialogConfirm": "Mehet", + "dialogCancel": "Mégse", + "all": "mind" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js new file mode 100644 index 0000000..430c858 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/it/EnhancedGrid", //begin v1.x content +({ + singleSort: "Ordine singolo", + nestedSort: "Ordine nidificato", + ascending: "Ascendente", + descending: "Decrescente", + sortingState: "${0} - ${1}", + unsorted: "Non ordinare questa colonna", + indirectSelectionRadio: "Riga ${0}, selezione singola, casella di opzione", + indirectSelectionCheckBox: "Riga ${0}, selezione multipla, casella di spunta", + selectAll: "Seleziona tutto" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js new file mode 100644 index 0000000..69d6a6b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/it/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Cancella filtro", + "filterDefDialogTitle": "Filtro", + "ruleTitleTemplate": "Regola ${0}", + + "conditionEqual": "uguale a", + "conditionNotEqual": "non uguale a", + "conditionLess": "minore di", + "conditionLessEqual": "minore di o uguale a", + "conditionLarger": "maggiore di", + "conditionLargerEqual": "maggiore di o uguale a", + "conditionContains": "contiene", + "conditionIs": "è", + "conditionStartsWith": "inizia con", + "conditionEndWith": "finisce con", + "conditionNotContain": "non contiene", + "conditionIsNot": "non è", + "conditionNotStartWith": "non inizia con", + "conditionNotEndWith": "non finisce con", + "conditionBefore": "prima", + "conditionAfter": "dopo", + "conditionRange": "intervallo", + "conditionIsEmpty": "è vuoto", + + "all": "tutte", + "any": "qualsiasi", + "relationAll": "tutte le regole", + "waiRelAll": "Confronta con tutte le seguenti regole:", + "relationAny": "qualsiasi regola", + "waiRelAny": "Confronta con qualsiasi delle seguenti regole:", + "relationMsgFront": "Confronta", + "relationMsgTail": "", + "and": "e", + "or": "o", + + "addRuleButton": "Aggiungi regola", + "waiAddRuleButton": "Aggiungi una nuova regola", + "removeRuleButton": "Rimuovi regola", + "waiRemoveRuleButtonTemplate": "Rimuovi regola ${0}", + + "cancelButton": "Annulla", + "waiCancelButton": "Annulla questa finestra di dialogo", + "clearButton": "Cancella", + "waiClearButton": "Cancella il filtro", + "filterButton": "Filtro", + "waiFilterButton": "Inoltra il filtro", + + "columnSelectLabel": "Colonna", + "waiColumnSelectTemplate": "Colonna per la regola ${0}", + "conditionSelectLabel": "Condizione", + "waiConditionSelectTemplate": "Condizione per la regola ${0}", + "valueBoxLabel": "Valore", + "waiValueBoxTemplate": "Immettere il valore da filtrare per la regola ${0}", + + "rangeTo": "a", + "rangeTemplate": "da ${0} a ${1}", + + "statusTipHeaderColumn": "Colonna", + "statusTipHeaderCondition": "Regole", + "statusTipTitle": "Barra di filtro", + "statusTipMsg": "Fare clic sulla barra di filtro qui per filtrare sui valori in ${0}.", + "anycolumn": "qualsiasi colonna", + "statusTipTitleNoFilter": "Barra di filtro", + "statusTipTitleHasFilter": "Filtro", + "statusTipRelAny": "Corrispondenza con qualsiasi regola.", + "statusTipRelAll": "Corrispondenza con tutte le regole.", + + "defaultItemsName": "elementi", + "filterBarMsgHasFilterTemplate": "${0} di ${1} ${2} visualizzati.", + "filterBarMsgNoFilterTemplate": "Nessun filtro applicato", + + "filterBarDefButton": "Definisci filtro", + "waiFilterBarDefButton": "Filtra la tabella", + "a11yFilterBarDefButton": "Filtro...", + "filterBarClearButton": "Cancella filtro", + "waiFilterBarClearButton": "Cancella il filtro", + "closeFilterBarBtn": "Chiudi barra di filtro", + + "clearFilterMsg": "Questo rimuoverà il filtro e visualizzerà tutti i record disponibili.", + "anyColumnOption": "Qualsiasi colonna", + + "trueLabel": "Vero", + "falseLabel": "Falso" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js new file mode 100644 index 0000000..96d042c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/it/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} di ${1} ${0}", + "firstTip": "Prima pagina", + "lastTip": "Ultima pagina", + "nextTip": "Pagina successiva ", + "prevTip": "Pagina precedente ", + "itemTitle": "elementi ", + "singularItemTitle": "elemento", + "pageStepLabelTemplate": "Pagina ${0}", + "pageSizeLabelTemplate": "${0} elementi per pagina ", + "allItemsLabelTemplate": "Tutti gli elementi", + "gotoButtonTitle": "Vai a una pagina specifica ", + "dialogTitle": "Vai a pagina ", + "dialogIndication": "Specificare il numero di pagina", + "pageCountIndication": " (${0} pagine)", + "dialogConfirm": "Vai", + "dialogCancel": "Annulla", + "all": "tutte" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js new file mode 100644 index 0000000..851e550 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js @@ -0,0 +1,16 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ja/EnhancedGrid", //begin v1.x content +({ + singleSort: "単一ソート", + nestedSort: "ネスト・ソート", + ascending: "昇順", + descending: "降順", + sortingState: "${0} - ${1}", + unsorted: "この列をソートしない", + indirectSelectionRadio: "行 ${0}、単一選択、ラジオ・ボックス", + indirectSelectionCheckBox: "行 ${0}、複数選択、チェック・ボックス", + selectAll: "すべてを選択" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js new file mode 100644 index 0000000..0366bfc --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ja/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "フィルターのクリア", + "filterDefDialogTitle": "フィルター", + "ruleTitleTemplate": "ルール ${0}", + + "conditionEqual": "等しい", + "conditionNotEqual": "等しくない", + "conditionLess": "より小", + "conditionLessEqual": "より小または等しい", + "conditionLarger": "より大", + "conditionLargerEqual": "より大または等しい", + "conditionContains": "含む", + "conditionIs": "該当する", + "conditionStartsWith": "先頭", + "conditionEndWith": "末尾", + "conditionNotContain": "含まない", + "conditionIsNot": "該当しない", + "conditionNotStartWith": "先頭が異なる", + "conditionNotEndWith": "末尾が異なる", + "conditionBefore": "より前", + "conditionAfter": "より後", + "conditionRange": "範囲", + "conditionIsEmpty": "空である", + + "all": "すべて", + "any": "いずれか", + "relationAll": "すべてのルール", + "waiRelAll": "次のルールのすべてに一致:", + "relationAny": "いずれかのルール", + "waiRelAny": "次のルールのいずれかに一致:", + "relationMsgFront": "一致", + "relationMsgTail": "", + "and": "かつ", + "or": "または", + + "addRuleButton": "ルールの追加", + "waiAddRuleButton": "新規ルールの追加", + "removeRuleButton": "ルールの削除", + "waiRemoveRuleButtonTemplate": "ルール ${0} の削除", + + "cancelButton": "キャンセル", + "waiCancelButton": "このダイアログをキャンセル", + "clearButton": "クリア", + "waiClearButton": "フィルターのクリア", + "filterButton": "フィルター", + "waiFilterButton": "フィルターの実行依頼", + + "columnSelectLabel": "列", + "waiColumnSelectTemplate": "ルール ${0} の列", + "conditionSelectLabel": "条件", + "waiConditionSelectTemplate": "ルール ${0} の条件", + "valueBoxLabel": "値", + "waiValueBoxTemplate": "ルール ${0} を検出するフィルター操作のための値を入力", + + "rangeTo": "範囲", + "rangeTemplate": "${0} から ${1} まで", + + "statusTipHeaderColumn": "列", + "statusTipHeaderCondition": "ルール", + "statusTipTitle": "フィルター・バー", + "statusTipMsg": "このフィルター・バーをクリックして、${0} の値にフィルターを適用します。", + "anycolumn": "いずれかの列", + "statusTipTitleNoFilter": "フィルター・バー", + "statusTipTitleHasFilter": "フィルター", + "statusTipRelAny": "いずれかのルールに一致。", + "statusTipRelAll": "すべてのルールに一致。", + + "defaultItemsName": "項目", + "filterBarMsgHasFilterTemplate": "${0}/${1} ${2} が表示されました。", + "filterBarMsgNoFilterTemplate": "フィルターが適用されていません", + + "filterBarDefButton": "フィルターの定義", + "waiFilterBarDefButton": "表のフィルタリング", + "a11yFilterBarDefButton": "フィルター...", + "filterBarClearButton": "フィルターのクリア", + "waiFilterBarClearButton": "フィルターのクリア", + "closeFilterBarBtn": "フィルター・バーを閉じる", + + "clearFilterMsg": "これによりフィルターが解除され、使用可能なレコードがすべて表示されます。", + "anyColumnOption": "いずれかの列", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js new file mode 100644 index 0000000..90cd698 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ja/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3}/${1} ${0}", + "firstTip": "最初のページ", + "lastTip": "最後のページ", + "nextTip": "次のページ", + "prevTip": "前のページ", + "itemTitle": "項目", + "singularItemTitle": "項目", + "pageStepLabelTemplate": "ページ ${0}", + "pageSizeLabelTemplate": "ページ当たり ${0} 項目", + "allItemsLabelTemplate": "すべての項目", + "gotoButtonTitle": "特定のページに移動", + "dialogTitle": "ページの移動", + "dialogIndication": "ページ番号を指定してください", + "pageCountIndication": " (${0} ページ)", + "dialogConfirm": "実行", + "dialogCancel": "キャンセル", + "all": "すべて" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js new file mode 100644 index 0000000..d1aeac2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/kk/EnhancedGrid", //begin v1.x content +({ + singleSort: "Бір рет сұрыптау", + nestedSort: "Кірістірілген сұрыптау", + ascending: "Артуы бойынша", + descending: "Кемуі бойынша", + sortingState: "${0} - ${1}", + unsorted: "Бұл бағанды сұрыптамау", + indirectSelectionRadio: "${0}-жол, жалғыз элементті таңдау, бір түймешікті таңдау тақтасы", + indirectSelectionCheckBox: "${0}-жол, бірнеше элементті таңдау, құсбелгі", + selectAll: "Барлығын таңдау" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js new file mode 100644 index 0000000..fbe4cd2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/kk/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Сүзгіні тазалау", + "filterDefDialogTitle": "Сүзгі", + "ruleTitleTemplate": "${0} ережесі", + + "conditionEqual": "тең", + "conditionNotEqual": "тең емес", + "conditionLess": "аздау", + "conditionLessEqual": "аздау немесе тең", + "conditionLarger": "үлкендеу", + "conditionLargerEqual": "үлкендеу немесе тең", + "conditionContains": "құрамында бар", + "conditionIs": "–", + "conditionStartsWith": "басталады", + "conditionEndWith": "аяқталады", + "conditionNotContain": "құрамында жоқ", + "conditionIsNot": "емес", + "conditionNotStartWith": "басталмайды", + "conditionNotEndWith": "аяқталмайды", + "conditionBefore": "алдында", + "conditionAfter": "артында", + "conditionRange": "ауқым", + "conditionIsEmpty": "– бос", + + "all": "барлығы", + "any": "кез келген", + "relationAll": "барлық ережелер", + "waiRelAll": "Барлық мына ережелерге сәйкес:", + "relationAny": "кез келген ереже", + "waiRelAny": "Мына ережелерге сәйкес:", + "relationMsgFront": "Сәйкес келу", + "relationMsgTail": "", + "and": "және", + "or": "немесе", + + "addRuleButton": "Ереже қосу", + "waiAddRuleButton": "Жаңа ереже қосу", + "removeRuleButton": "Ережені алып тастау", + "waiRemoveRuleButtonTemplate": "${0} ережесін алып тастау", + + "cancelButton": "Болдырмау", + "waiCancelButton": "Осы тілқатысу терезесін болдырмау", + "clearButton": "Тазалау ", + "waiClearButton": "Сүзгіні тазалау", + "filterButton": "Сүзгі", + "waiFilterButton": "Сүзгіні жіберу", + + "columnSelectLabel": "Баған", + "waiColumnSelectTemplate": "${0} ережесінің бағаны", + "conditionSelectLabel": "Шарт", + "waiConditionSelectTemplate": "${0} ережесінің шарты", + "valueBoxLabel": "Мән", + "waiValueBoxTemplate": "${0} ережесін сүзу үшін мәнді енгізу", + + "rangeTo": "неге", + "rangeTemplate": "${0} мәнінен ${1} мәніне", + + "statusTipHeaderColumn": "Баған", + "statusTipHeaderCondition": "Ережелер", + "statusTipTitle": "Сүзгі тақтасы", + "statusTipMsg": "${0} ішіндегі мәндер бойынша сүзу үшін сүзгі тақтасын нұқыңыз.", + "anycolumn": "кез келген баған", + "statusTipTitleNoFilter": "Сүзгі тақтасы", + "statusTipTitleHasFilter": "Сүзгі", + "statusTipRelAny": "Кез келген ережелерді сәйкестендіріңіз.", + "statusTipRelAll": "Барлық ережелерді сәйкестендіріңіз.", + + "defaultItemsName": "элементтер", + "filterBarMsgHasFilterTemplate": "${1} ${2} ішінен ${0} көрсетілді.", + "filterBarMsgNoFilterTemplate": "Сүзгі қолданылмады", + + "filterBarDefButton": "Сүзгіні анықтау", + "waiFilterBarDefButton": "Кестені сүзу", + "a11yFilterBarDefButton": "Сүзгі...", + "filterBarClearButton": "Сүзгіні тазалау", + "waiFilterBarClearButton": "Сүзгіні тазалау", + "closeFilterBarBtn": "Сүзгі тақтасын жабу", + + "clearFilterMsg": "Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.", + "anyColumnOption": "Кез келген баған", + + "trueLabel": "Шын", + "falseLabel": "Жалған" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js new file mode 100644 index 0000000..baa56fe --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/kk/Pagination", //begin v1.x content +({ + "descTemplate": "${1} ${0} элементтің ${2} - ${3} элементі", + "firstTip": "Бірінші бет", + "lastTip": "Соңғы бет", + "nextTip": "Келесі бет", + "prevTip": "Алдыңғы бет", + "itemTitle": "элементтер", + "singularItemTitle": "элемент", + "pageStepLabelTemplate": "Бет ${0}", + "pageSizeLabelTemplate": "Бетіне ${0} элемент", + "allItemsLabelTemplate": "Барлық элементтер", + "gotoButtonTitle": "Белгілі бір бетке өту", + "dialogTitle": "Бетке өту", + "dialogIndication": "Бет нөмірін көрсету", + "pageCountIndication": " (${0} бет)", + "dialogConfirm": "Өту", + "dialogCancel": "Болдырмау", + "all": "барлығы" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js new file mode 100644 index 0000000..9e0d07b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ko/EnhancedGrid", //begin v1.x content +({ + singleSort: "단일 정렬", + nestedSort: "중첩된 정렬", + ascending: "오름차순", + descending: "내림차순", + sortingState: "${0} - ${1}", + unsorted: "이 컬럼은 정렬하지 마십시오", + indirectSelectionRadio: "행 ${0}, 단일 선택, 라디오 상자", + indirectSelectionCheckBox: "행 ${0}, 다중 선택, 선택란", + selectAll: "모두 선택" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js new file mode 100644 index 0000000..0b909b2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ko/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "필터 지우기", + "filterDefDialogTitle": "필터", + "ruleTitleTemplate": "규칙 ${0}", + + "conditionEqual": "같음", + "conditionNotEqual": "같지 않음", + "conditionLess": "미만", + "conditionLessEqual": "이하", + "conditionLarger": "초과", + "conditionLargerEqual": "이상", + "conditionContains": "포함", + "conditionIs": "다음과 같음", + "conditionStartsWith": "다음으로 시작", + "conditionEndWith": "다음으로 종료", + "conditionNotContain": "포함하지 않음", + "conditionIsNot": "다음이 아님", + "conditionNotStartWith": "다음으로 시작하지 않음", + "conditionNotEndWith": "다음으로 종료하지 않음", + "conditionBefore": "이전", + "conditionAfter": "이후", + "conditionRange": "범위", + "conditionIsEmpty": "다음이 비어있음", + + "all": "모두", + "any": "임의", + "relationAll": "모든 규칙", + "waiRelAll": "다음 규칙에 모두 일치:", + "relationAny": "임의 규칙", + "waiRelAny": "다음 규칙 중에 일치:", + "relationMsgFront": "일치", + "relationMsgTail": "", + "and": "및", + "or": "또는", + + "addRuleButton": "규칙 추가", + "waiAddRuleButton": "새 규칙 추가", + "removeRuleButton": "규칙 제거", + "waiRemoveRuleButtonTemplate": "${0} 규칙 제거", + + "cancelButton": "취소", + "waiCancelButton": "이 대화 상자 취소", + "clearButton": "지우기", + "waiClearButton": "해당 필터 지우기", + "filterButton": "필터", + "waiFilterButton": "필터 제출", + + "columnSelectLabel": "컬럼", + "waiColumnSelectTemplate": "${0} 규칙에 대한 컬럼", + "conditionSelectLabel": "조건", + "waiConditionSelectTemplate": "${0} 규칙에 대한 조건", + "valueBoxLabel": "값", + "waiValueBoxTemplate": "${0} 규칙에 대해 필터링할 값 입력", + + "rangeTo": "다음에서 종료", + "rangeTemplate": "${0}에서 ${1}까지", + + "statusTipHeaderColumn": "컬럼", + "statusTipHeaderCondition": "규칙", + "statusTipTitle": "필터 표시줄", + "statusTipMsg": "${0}의 값을 필터링하려면 이 필터 표시줄을 클릭하십시오.", + "anycolumn": "임의의 컬럼", + "statusTipTitleNoFilter": "필터 표시줄", + "statusTipTitleHasFilter": "필터", + "statusTipRelAny": "임의 규칙과 일치.", + "statusTipRelAll": "모든 규칙과 일치.", + + "defaultItemsName": "항목", + "filterBarMsgHasFilterTemplate": "${0}/${1} ${2} 표시됨", + "filterBarMsgNoFilterTemplate": "적용된 필터 없음", + + "filterBarDefButton": "필터 정의", + "waiFilterBarDefButton": "표 필터링", + "a11yFilterBarDefButton": "필터...", + "filterBarClearButton": "필터 지우기", + "waiFilterBarClearButton": "해당 필터 지우기", + "closeFilterBarBtn": "필터 표시줄 닫기", + + "clearFilterMsg": "이로 인해 해당 필터가 제거되며 사용 가능한 모든 레코드가 표시됩니다.", + "anyColumnOption": "임의의 컬럼", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js new file mode 100644 index 0000000..39c88b1 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ko/Pagination", //begin v1.x content +({ + "descTemplate": "${1} ${0} 중 ${2} - ${3}", + "firstTip": "첫 번째 페이지", + "lastTip": "마지막 페이지", + "nextTip": "다음 페이지", + "prevTip": "이전 페이지", + "itemTitle": "항목", + "singularItemTitle": "항목", + "pageStepLabelTemplate": "페이지 ${0}", + "pageSizeLabelTemplate": "페이지 당 ${0} 항목", + "allItemsLabelTemplate": "모든 항목", + "gotoButtonTitle": "특정 페이지로 이동", + "dialogTitle": "페이지로 이동", + "dialogIndication": "페이지 번호 지정", + "pageCountIndication": " (${0} 페이지)", + "dialogConfirm": "이동", + "dialogCancel": "취소", + "all": "모두" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js new file mode 100644 index 0000000..660d223 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/nb/EnhancedGrid", //begin v1.x content +({ + singleSort: "Enkeltsortering", + nestedSort: "Nestet sortering", + ascending: "Stigende", + descending: "Synkende", + sortingState: "${0} - ${1}", + unsorted: "Ikke sorter denne kolonnen", + indirectSelectionRadio: "Rad ${0}, enkeltvalg, valgknapp", + indirectSelectionCheckBox: "Rad ${0}, flervalg, avmerkingsboks", + selectAll: "Velg alle" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js new file mode 100644 index 0000000..5a58363 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/nb/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Tøm filter", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Regel ${0}", + + "conditionEqual": "er lik", + "conditionNotEqual": "er ikke lik", + "conditionLess": "er mindre enn", + "conditionLessEqual": "mindre enn eller lik", + "conditionLarger": "er større enn", + "conditionLargerEqual": "større enn eller lik", + "conditionContains": "inneholder", + "conditionIs": "er", + "conditionStartsWith": "starter med", + "conditionEndWith": "slutter med", + "conditionNotContain": "inneholder ikke", + "conditionIsNot": "er ikke", + "conditionNotStartWith": "starter ikke med", + "conditionNotEndWith": "slutter ikke med", + "conditionBefore": "før", + "conditionAfter": "etter", + "conditionRange": "område", + "conditionIsEmpty": "er tom", + + "all": "alle", + "any": "minst en", + "relationAll": "alle regler", + "waiRelAll": "Samsvar med alle disse reglene:", + "relationAny": "minst en regel", + "waiRelAny": "Samsvar med minst en av disse reglene:", + "relationMsgFront": "Samsvar med", + "relationMsgTail": "", + "and": "og", + "or": "eller", + + "addRuleButton": "Legg til regel", + "waiAddRuleButton": "Legg til en ny regel", + "removeRuleButton": "Fjern regel", + "waiRemoveRuleButtonTemplate": "Fjern regel ${0}", + + "cancelButton": "Avbryt", + "waiCancelButton": "Avbryt denne dialogboksen", + "clearButton": "Tøm", + "waiClearButton": "Tøm filteret", + "filterButton": "Filtrer", + "waiFilterButton": "Send filteret", + + "columnSelectLabel": "Kolonne", + "waiColumnSelectTemplate": "Kolonne for regel ${0}", + "conditionSelectLabel": "Betingelse", + "waiConditionSelectTemplate": "Betingelse for regel ${0}", + "valueBoxLabel": "Verdi", + "waiValueBoxTemplate": "Oppgi verdi som skal filtreres for regel ${0}", + + "rangeTo": "til", + "rangeTemplate": "fra ${0} til ${1}", + + "statusTipHeaderColumn": "Kolonne", + "statusTipHeaderCondition": "Regler", + "statusTipTitle": "Filterlinje", + "statusTipMsg": "Klikk på filterlinjen her for å filtrere på verdiene i ${0}.", + "anycolumn": "enhver kolonne", + "statusTipTitleNoFilter": "Filterlinje", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Samsvar med minst en regel.", + "statusTipRelAll": "Samsvar med alle regler.", + + "defaultItemsName": "elementer", + "filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} vist.", + "filterBarMsgNoFilterTemplate": "Ikke brukt filter", + + "filterBarDefButton": "Definer filter", + "waiFilterBarDefButton": "Filtrer tabellen", + "a11yFilterBarDefButton": "Filtrer...", + "filterBarClearButton": "Tøm filter", + "waiFilterBarClearButton": "Tøm filteret", + "closeFilterBarBtn": "Lukk filterlinjen", + + "clearFilterMsg": "Dette fjerner filteret og viser alle tilgjengelige poster.", + "anyColumnOption": "Minst en kolonne", + + "trueLabel": "Sann", + "falseLabel": "Usann" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js new file mode 100644 index 0000000..ae43787 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/nb/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} av ${1} ${0}", + "firstTip": "Første side", + "lastTip": "Siste side", + "nextTip": "Neste side", + "prevTip": "Forrige side", + "itemTitle": "elementer", + "singularItemTitle": "element", + "pageStepLabelTemplate": "Side ${0}", + "pageSizeLabelTemplate": "${0} elementer per side", + "allItemsLabelTemplate": "Alle elementer", + "gotoButtonTitle": "Gå til en bestemt side", + "dialogTitle": "Gå til side", + "dialogIndication": "Oppgi sidetallet", + "pageCountIndication": " (${0} sider)", + "dialogConfirm": "Utfør", + "dialogCancel": "Avbryt", + "all": "alle" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js new file mode 100644 index 0000000..d74e154 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/nl/EnhancedGrid", //begin v1.x content +({ + singleSort: "Enkelvoudig sorteren", + nestedSort: "Genest sorteren", + ascending: "Oplopend", + descending: "Aflopend", + sortingState: "${0} - ${1}", + unsorted: "Deze kolom niet sorteren", + indirectSelectionRadio: "Rij ${0}, enkele selectie, keuzerondje", + indirectSelectionCheckBox: "Rij ${0}, meerdere selecties, selectievakje", + selectAll: "Alles selecteren" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js new file mode 100644 index 0000000..4456d4b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/nl/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Filter wissen", + "filterDefDialogTitle": "Filteren", + "ruleTitleTemplate": "Regel ${0}", + + "conditionEqual": "gelijk aan", + "conditionNotEqual": "niet gelijk aan", + "conditionLess": "is kleiner dan", + "conditionLessEqual": "kleiner dan of gelijk aan", + "conditionLarger": "is groter dan", + "conditionLargerEqual": "groter dan of gelijk aan", + "conditionContains": "bevat", + "conditionIs": "is", + "conditionStartsWith": "begint met", + "conditionEndWith": "eindigt op", + "conditionNotContain": "bevat niet", + "conditionIsNot": "is niet", + "conditionNotStartWith": "begint niet met", + "conditionNotEndWith": "eindigt niet op", + "conditionBefore": "voor", + "conditionAfter": "na", + "conditionRange": "bereik", + "conditionIsEmpty": "is leeg", + + "all": "alle", + "any": "een of meer", + "relationAll": "alle regels", + "waiRelAll": "Voldoen aan al deze regels:", + "relationAny": "een of meer regels", + "waiRelAny": "Voldoen aan een van deze regels:", + "relationMsgFront": "Voldoen aan", + "relationMsgTail": "", + "and": "en", + "or": "of", + + "addRuleButton": "Regel toevoegen", + "waiAddRuleButton": "Een nieuwe regel toevoegen", + "removeRuleButton": "Regel verwijderen", + "waiRemoveRuleButtonTemplate": "Regel ${0} verwijderen", + + "cancelButton": "Annuleren", + "waiCancelButton": "Dit dialoogvenster annuleren", + "clearButton": "Leegmaken", + "waiClearButton": "Het filter wissen", + "filterButton": "Filteren", + "waiFilterButton": "Het filter verzenden", + + "columnSelectLabel": "Kolom", + "waiColumnSelectTemplate": "Kolom voor regel ${0}", + "conditionSelectLabel": "Voorwaarde", + "waiConditionSelectTemplate": "Voorwaarde voor regel ${0}", + "valueBoxLabel": "Waarde", + "waiValueBoxTemplate": "Geef een filterwaarde op voor regel ${0}", + + "rangeTo": "tot", + "rangeTemplate": "van ${0} tot ${1}", + + "statusTipHeaderColumn": "Kolom", + "statusTipHeaderCondition": "Regels", + "statusTipTitle": "Filterbalk", + "statusTipMsg": "Klik hier op de filterbalk om te filteren op waarden in ${0}.", + "anycolumn": "een kolom", + "statusTipTitleNoFilter": "Filterbalk", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Voldoen aan een van de regels.", + "statusTipRelAll": "Voldoen aan alle regels.", + + "defaultItemsName": "items", + "filterBarMsgHasFilterTemplate": "${0} van ${1} ${2} afgebeeld.", + "filterBarMsgNoFilterTemplate": "Geen filter toegepast", + + "filterBarDefButton": "Filter definiëren", + "waiFilterBarDefButton": "De tabel filteren", + "a11yFilterBarDefButton": "Filteren...", + "filterBarClearButton": "Filter wissen", + "waiFilterBarClearButton": "Het filter wissen", + "closeFilterBarBtn": "Filterbalk sluiten", + + "clearFilterMsg": "Hiermee verwijdert u het filter en worden alle beschikbare records afgebeeld.", + "anyColumnOption": "Een kolom", + + "trueLabel": "Waar", + "falseLabel": "Onwaar" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js new file mode 100644 index 0000000..c18a2ea --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/nl/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} van ${1} ${0}", + "firstTip": "Eerste pagina", + "lastTip": "Laatste pagina", + "nextTip": "Volgende pagina", + "prevTip": "Vorige pagina", + "itemTitle": "items", + "singularItemTitle": "item", + "pageStepLabelTemplate": "Pagina ${0}", + "pageSizeLabelTemplate": "${0} items per pagina", + "allItemsLabelTemplate": "Alle items", + "gotoButtonTitle": "Ga naar bepaalde pagina", + "dialogTitle": "Ga naar pagina", + "dialogIndication": "Geef het paginanummer op", + "pageCountIndication": " (${0} pagina's)", + "dialogConfirm": "Go", + "dialogCancel": "Annuleren", + "all": "alle" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js new file mode 100644 index 0000000..0fe4701 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pl/EnhancedGrid", //begin v1.x content +({ + singleSort: "Pojedyncze sortowanie", + nestedSort: "Zagnieżdżone sortowanie", + ascending: "Rosnąco", + descending: "Malejąco", + sortingState: "${0} - ${1}", + unsorted: "Nie sortuj tej kolumny", + indirectSelectionRadio: "Wiersz ${0}, pojedynczy wybór, zestaw przełączników", + indirectSelectionCheckBox: "Wiersz ${0}, wybór wielokrotny, pole wyboru", + selectAll: "Wybierz wszystko" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js new file mode 100644 index 0000000..16737ae --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pl/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Wyczyść filtr", + "filterDefDialogTitle": "Filtr", + "ruleTitleTemplate": "Reguła ${0}", + + "conditionEqual": "równe", + "conditionNotEqual": "różne od", + "conditionLess": "mniejsze od", + "conditionLessEqual": "mniejsze lub równe", + "conditionLarger": "większe od", + "conditionLargerEqual": "większe lub równe", + "conditionContains": "zawiera", + "conditionIs": "jest", + "conditionStartsWith": "zaczyna się od", + "conditionEndWith": "kończy się na", + "conditionNotContain": "nie zawiera", + "conditionIsNot": "nie jest", + "conditionNotStartWith": "nie zaczyna się od", + "conditionNotEndWith": "nie kończy się na", + "conditionBefore": "przed", + "conditionAfter": "po", + "conditionRange": "zakres", + "conditionIsEmpty": "jest pusty", + + "all": "wszystkie", + "any": "dowolne", + "relationAll": "wszystkie reguły", + "waiRelAll": "Dopasuj wszystkie poniższe reguły:", + "relationAny": "dowolna reguła", + "waiRelAny": "Dopasuj dowolną z poniższych reguł:", + "relationMsgFront": "Dopasuj", + "relationMsgTail": "", + "and": "i", + "or": "lub", + + "addRuleButton": "Dodaj regułę", + "waiAddRuleButton": "Dodaj nową regułę", + "removeRuleButton": "Usuń regułę", + "waiRemoveRuleButtonTemplate": "Usuń regułę ${0}", + + "cancelButton": "Anuluj", + "waiCancelButton": "Anuluj to okno dialogowe", + "clearButton": "Wyczyść", + "waiClearButton": "Wyczyść filtr", + "filterButton": "Filtruj", + "waiFilterButton": "Wprowadź ten filtr", + + "columnSelectLabel": "Kolumna", + "waiColumnSelectTemplate": "Kolumna dla reguły ${0}", + "conditionSelectLabel": "Warunek", + "waiConditionSelectTemplate": "Warunek dla reguły ${0}", + "valueBoxLabel": "Wartość", + "waiValueBoxTemplate": "Wprowadź wartość, aby filtrować dla reguły ${0}", + + "rangeTo": "do", + "rangeTemplate": "od ${0} do ${1}", + + "statusTipHeaderColumn": "Kolumna", + "statusTipHeaderCondition": "Reguły", + "statusTipTitle": "Pasek filtru", + "statusTipMsg": "Kliknij pasek filtru tutaj, aby filtrować według wartości w ${0}.", + "anycolumn": "dowolna kolumna", + "statusTipTitleNoFilter": "Pasek filtru", + "statusTipTitleHasFilter": "Filtr", + "statusTipRelAny": "Dopasuj do dowolnej z reguł.", + "statusTipRelAll": "Dopasuj do wszystkich reguł.", + + "defaultItemsName": "elementy", + "filterBarMsgHasFilterTemplate": "Wyświetlane ${0} z ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "Filtr wyłączony", + + "filterBarDefButton": "Zdefiniuj filtr", + "waiFilterBarDefButton": "Filtruj tabelę", + "a11yFilterBarDefButton": "Filtruj...", + "filterBarClearButton": "Wyczyść filtr", + "waiFilterBarClearButton": "Wyczyść filtr", + "closeFilterBarBtn": "Zamknij pasek filtru", + + "clearFilterMsg": "Filtr zostanie usunięty i wyświetlone będą wszystkie dostępne rekordy.", + "anyColumnOption": "Dowolna kolumna", + + "trueLabel": "Prawda", + "falseLabel": "Fałsz" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js new file mode 100644 index 0000000..c8db8df --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pl/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} z ${1} ${0}", + "firstTip": "Pierwsza strona", + "lastTip": "Ostatnia strona", + "nextTip": "Następna strona", + "prevTip": "Poprzednia strona", + "itemTitle": "poz.", + "singularItemTitle": "pozycja", + "pageStepLabelTemplate": "Strona ${0}", + "pageSizeLabelTemplate": "${0} poz. na stronę", + "allItemsLabelTemplate": "Wszystkie pozycje", + "gotoButtonTitle": "Idź do konkretnej strony", + "dialogTitle": "Idź do strony", + "dialogIndication": "Podaj numer strony", + "pageCountIndication": " (${0} str.)", + "dialogConfirm": "Wykonaj", + "dialogCancel": "Anuluj", + "all": "wszystkie" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js new file mode 100644 index 0000000..093461c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js @@ -0,0 +1,16 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt-br/EnhancedGrid", ({ + singleSort: "Classificação Única", + nestedSort: "Classificação Aninhada", + ascending: "Crescente", + descending: "Decrescente", + sortingState: "${0} - ${1}", + unsorted: "Não classificar esta coluna", + indirectSelectionRadio: "Linha ${0}, seleção única, caixa de opção", + indirectSelectionCheckBox: "Linha ${0}, seleção múltipla, caixa de seleção", + selectAll: "Selecionar todos" +}) + + +);
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js new file mode 100644 index 0000000..dcc9553 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt-br/Filter", ({ + "clearFilterDialogTitle": "Limpar Filtro", + "filterDefDialogTitle": "Filtrar", + "ruleTitleTemplate": "Regra ${0}", + + "conditionEqual": "igual", + "conditionNotEqual": "não é igual", + "conditionLess": "é menor que", + "conditionLessEqual": "menor que ou igual", + "conditionLarger": "é maior que", + "conditionLargerEqual": "maior que ou igual", + "conditionContains": "contém", + "conditionIs": "é", + "conditionStartsWith": "começa com", + "conditionEndWith": "termina com", + "conditionNotContain": "não contém", + "conditionIsNot": "não é", + "conditionNotStartWith": "não começa com", + "conditionNotEndWith": "não termina com", + "conditionBefore": "antes", + "conditionAfter": "após", + "conditionRange": "intervalo", + "conditionIsEmpty": "está vazio", + + "all": "todos", + "any": "qualquer", + "relationAll": "todas as regras", + "waiRelAll": "Corresponder todas as regras a seguir:", + "relationAny": "quaisquer regras", + "waiRelAny": "Corresponder qualquer uma das regras a seguir:", + "relationMsgFront": "Corresponder", + "relationMsgTail": "", + "and": "e", + "or": "ou", + + "addRuleButton": "Incluir Regra", + "waiAddRuleButton": "Incluir uma nova regra", + "removeRuleButton": "Remover Regra", + "waiRemoveRuleButtonTemplate": "Remover regra ${0}", + + "cancelButton": "Cancelar", + "waiCancelButton": "cancelar este diálogo", + "clearButton": "Limpar", + "waiClearButton": "Limpar o filtro", + "filterButton": "Filtrar", + "waiFilterButton": "Submeter o filtro", + + "columnSelectLabel": "Coluna", + "waiColumnSelectTemplate": "Coluna para a regra ${0}", + "conditionSelectLabel": "Condição", + "waiConditionSelectTemplate": "Condição para a regra ${0}", + "valueBoxLabel": "Valor", + "waiValueBoxTemplate": "Inserir o valor para filtro para a regra ${0}", + + "rangeTo": "para", + "rangeTemplate": "de ${0} para ${1}", + + "statusTipHeaderColumn": "Coluna", + "statusTipHeaderCondition": "Regras", + "statusTipTitle": "Barra de Filtro", + "statusTipMsg": "Clique aqui na barra de filtro para filtrar os valores em ${0}.", + "anycolumn": "qualquer coluna", + "statusTipTitleNoFilter": "Barra de Filtro", + "statusTipTitleHasFilter": "Filtrar", + + "defaultItemsName": "itens", + "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrado.", + "filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado", + + "filterBarDefButton": "Definir filtro", + "waiFilterBarDefButton": "Filtrar a tabela", + "a11yFilterBarDefButton": "Filtrar...", + "filterBarClearButton": "Limpar Filtro", + "waiFilterBarClearButton": "Limpar o filtro", + "closeFilterBarBtn": "Fechar a barra de filtro", + + "clearFilterMsg": "Isso removerá o filtro e mostrará todos os registros disponíveis.", + "anyColumnOption": "Qualquer Coluna", + + "trueLabel": "Verdadeiro", + "falseLabel": "Falso" +}) + + + + +);
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js new file mode 100644 index 0000000..25bf82b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js @@ -0,0 +1,36 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt-br/Pagination", ({ + // ${0}: string + // unit of item, identified by "itemTitle" + // ${2}: number + // start item index of current page + // ${3}: number + // end item index of current page + // ${1}: number + // total number of all items + // example: + // the total number is 200, the unit of item is "items" + // rows per page is 20, current page is 1, then the description + // would be looked as below: + // | 1 - 20 of 200 items + "descTemplate": "${2} - ${3} de ${1} ${0}", + "firstTip": "Primeira Página", + "lastTip": "Última Página", + "nextTip": "Próxima Página", + "prevTip": "Página Anterior", + "itemTitle": "itens", + "singularItemTitle": "item", + "pageStepLabelTemplate": "Página ${0}", + "pageSizeLabelTemplate": "${0} itens por página", + "allItemsLabelTemplate": "Todos os itens", + "gotoButtonTitle": "Ir para uma página específica", + "dialogTitle": "Ir para a página", + "dialogIndication": "Especificar o número da página", + "pageCountIndication": " (${0} páginas)", + "dialogConfirm": "Ir", + "dialogCancel": "Cancelar", + "all": "todos" +}) + +);
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js new file mode 100644 index 0000000..f5c5340 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt-pt/EnhancedGrid", //begin v1.x content +({ + singleSort: "Ordenação única", + nestedSort: "Ordenação imbricada", + ascending: "Ascendente", + descending: "Descendente", + sortingState: "${0} - ${1}", + unsorted: "Não ordenar esta coluna", + indirectSelectionRadio: "Fila ${0}, selecção única, caixa de opção", + indirectSelectionCheckBox: "Fila ${0}, selecção múltipla, quadrado de confirmação", + selectAll: "Seleccionar tudo" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js new file mode 100644 index 0000000..beb4937 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js @@ -0,0 +1,90 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt-pt/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Limpar filtro", + "filterDefDialogTitle": "Filtro", + "ruleTitleTemplate": "Regra ${0}", + + "conditionEqual": "igual", + "conditionNotEqual": "não é igual", + "conditionLess": "é menor do que", + "conditionLessEqual": "menor ou igual", + "conditionLarger": "é maior do que", + "conditionLargerEqual": "maior ou igual", + "conditionContains": "contém", + "conditionIs": "é", + "conditionStartsWith": "começa com", + "conditionEndWith": "termina com", + "conditionNotContain": "não contém", + "conditionIsNot": "não é", + "conditionNotStartWith": "não começa com", + "conditionNotEndWith": "não termina com", + "conditionBefore": "antes", + "conditionAfter": "após", + "conditionRange": "intervalo", + "conditionIsEmpty": "está vazio", + + "all": "tudo", + "any": "qualquer", + "relationAll": "todas as regras", + "waiRelAll": "Corresponder a todas as seguintes regras:", + "relationAny": "quaisquer regras", + "waiRelAny": "Corresponder a qualquer uma das seguintes regras:", + "relationMsgFront": "Corresponder", + "relationMsgTail": "", + "and": "and", + "or": "or", + + "addRuleButton": "Adicionar regra", + "waiAddRuleButton": "Adicionar uma nova regra", + "removeRuleButton": "Remover regra", + "waiRemoveRuleButtonTemplate": "Remover regra ${0}", + + "cancelButton": "Cancelar", + "waiCancelButton": "Cancelar esta caixa de diálogo", + "clearButton": "Limpar", + "waiClearButton": "Limpar o filtro", + "filterButton": "Filtro", + "waiFilterButton": "Submeter o filtro", + + "columnSelectLabel": "Coluna", + "waiColumnSelectTemplate": "Coluna para a regra ${0}", + "conditionSelectLabel": "Condição", + "waiConditionSelectTemplate": "Condição para a regra ${0}", + "valueBoxLabel": "Valor", + "waiValueBoxTemplate": "Introduzir valor para filtrar para a regra ${0}", + + "rangeTo": "a", + "rangeTemplate": "de ${0} a ${1}", + + "statusTipHeaderColumn": "Coluna", + "statusTipHeaderCondition": "Regras", + "statusTipTitle": "Barra do filtro", + "statusTipMsg": "Faça clique na barra de filtro para filtrar os valores em ${0}.", + "anycolumn": "qualquer coluna", + "statusTipTitleNoFilter": "Barra do filtro", + "statusTipTitleHasFilter": "Filtro", + + "defaultItemsName": "itens", + "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} apresentado(s).", + "filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado", + + "filterBarDefButton": "Definir filtro", + "waiFilterBarDefButton": "Filtrar a tabela", + "a11yFilterBarDefButton": "Filtrar...", + "filterBarClearButton": "Limpar filtro", + "waiFilterBarClearButton": "Limpar o filtro", + "closeFilterBarBtn": "Fechar barra de filtro", + + "clearFilterMsg": "Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.", + "anyColumnOption": "Qualquer coluna", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); + + + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js new file mode 100644 index 0000000..ac54ab0 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt-pt/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} de ${1} ${0}", + "firstTip": "Primeira página", + "lastTip": "Última página", + "nextTip": "Página seguinte", + "prevTip": "Página anterior", + "itemTitle": "itens", + "pageStepLabelTemplate": "Página ${0}", + "pageSizeLabelTemplate": "${0} itens por página", + "allItemsLabelTemplate": "Todos os itens", + "gotoButtonTitle": "Avançar para uma página específica", + "dialogTitle": "Avançar para a página", + "dialogIndication": "Especificar o número de página", + "pageCountIndication": " (${0} páginas)", + "dialogConfirm": "Ir", + "dialogCancel": "Cancelar", + "all": "tudo" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js new file mode 100644 index 0000000..b09ab48 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt/EnhancedGrid", //begin v1.x content +({ + singleSort: "Classificação Única", + nestedSort: "Classificação Aninhada", + ascending: "Ascendente", + descending: "Descendente", + sortingState: "${0} - ${1}", + unsorted: "Não classificar esta coluna", + indirectSelectionRadio: "Linha ${0}, seleção única, botão de seleção", + indirectSelectionCheckBox: "Linha ${0}, seleção múltipla, caixa de seleção", + selectAll: "Selecionar todos" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js new file mode 100644 index 0000000..7974304 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js @@ -0,0 +1,92 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Limpar Filtro", + "filterDefDialogTitle": "Filtrar", + "ruleTitleTemplate": "Regra ${0}", + + "conditionEqual": "igual", + "conditionNotEqual": "não é igual", + "conditionLess": "é menor que", + "conditionLessEqual": "menor ou igual a", + "conditionLarger": "é maior que", + "conditionLargerEqual": "maior ou igual a", + "conditionContains": "contém", + "conditionIs": "é", + "conditionStartsWith": "inicia com", + "conditionEndWith": "termina com", + "conditionNotContain": "não contém", + "conditionIsNot": "não é", + "conditionNotStartWith": "não inicia com", + "conditionNotEndWith": "não termina com", + "conditionBefore": "antes", + "conditionAfter": "depois", + "conditionRange": "intervalo", + "conditionIsEmpty": "está vazio", + + "all": "todos", + "any": "qualquer um", + "relationAll": "todas as regras", + "waiRelAll": "Corresponder a todas as seguintes regras:", + "relationAny": "qualquer regra", + "waiRelAny": "Corresponder a qualquer uma das seguintes regras:", + "relationMsgFront": "Corresponder", + "relationMsgTail": "", + "and": "e", + "or": "ou", + + "addRuleButton": "Incluir Regra", + "waiAddRuleButton": "Incluir uma nova regra", + "removeRuleButton": "Remover Regra", + "waiRemoveRuleButtonTemplate": "Remover regra ${0}", + + "cancelButton": "Cancelar", + "waiCancelButton": "Cancelar este diálogo", + "clearButton": "Limpar", + "waiClearButton": "Limpar o filtro", + "filterButton": "Filtrar", + "waiFilterButton": "Enviar o filtro", + + "columnSelectLabel": "Coluna", + "waiColumnSelectTemplate": "Coluna para a regra ${0}", + "conditionSelectLabel": "Condição", + "waiConditionSelectTemplate": "Condição para a regra ${0}", + "valueBoxLabel": "Valor", + "waiValueBoxTemplate": "Insira o valor para filtragem da regra ${0}", + + "rangeTo": "a", + "rangeTemplate": "de ${0} a ${1}", + + "statusTipHeaderColumn": "Coluna", + "statusTipHeaderCondition": "Regras", + "statusTipTitle": "Barra de Filtragem", + "statusTipMsg": "Clique na barra de filtragem aqui para filtrar os valores de ${0}.", + "anycolumn": "qualquer coluna", + "statusTipTitleNoFilter": "Barra de Filtragem", + "statusTipTitleHasFilter": "Filtrar", + "statusTipRelAny": "Quaisquer Regras.", + "statusTipRelAll": "Todas as Regras.", + + "defaultItemsName": "itens", + "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.", + "filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado", + + "filterBarDefButton": "Definir filtro", + "waiFilterBarDefButton": "Filtrar a tabela", + "a11yFilterBarDefButton": "Filtrar...", + "filterBarClearButton": "Limpar filtro", + "waiFilterBarClearButton": "Limpar o filtro", + "closeFilterBarBtn": "Fechar a barra de filtragem", + + "clearFilterMsg": "Isso removerá o filtro e mostrará todos os registros disponíveis.", + "anyColumnOption": "Qualquer Coluna", + + "trueLabel": "Verdadeiro", + "falseLabel": "Falso" +}) +//end v1.x content +); + + + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js new file mode 100644 index 0000000..5a1320d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/pt/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} de ${1} ${0}", + "firstTip": "Primeira Página", + "lastTip": "Última Página", + "nextTip": "Próxima página", + "prevTip": "Página anterior", + "itemTitle": "itens", + "singularItemTitle": "item", + "pageStepLabelTemplate": "Página ${0}", + "pageSizeLabelTemplate": "${0} itens por página", + "allItemsLabelTemplate": "Todos os itens", + "gotoButtonTitle": "Acesse uma página específica", + "dialogTitle": "Acesse a Página", + "dialogIndication": "Especifique o número da página", + "pageCountIndication": " (${0} páginas)", + "dialogConfirm": "Ir", + "dialogCancel": "Cancelar", + "all": "todos" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js new file mode 100644 index 0000000..0415b11 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ro/EnhancedGrid", //begin v1.x content +({ + singleSort: "Sortare singulară", + nestedSort: "Sortare imbricată", + ascending: "Crescător", + descending: "Descrescător", + sortingState: "${0} - ${1}", + unsorted: "Nu se sortează această coloană", + indirectSelectionRadio: "Rândul ${0}, selecţie singulară, casetă radio", + indirectSelectionCheckBox: "Rândul ${0}, selecţie multiplă, casetă de bifare", + selectAll: "Selectare tot" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js new file mode 100644 index 0000000..ba2879c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ro/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Ştergere filtru", + "filterDefDialogTitle": "Filtru", + "ruleTitleTemplate": "Regulă ${0}", + + "conditionEqual": "egal", + "conditionNotEqual": "nu este egal", + "conditionLess": "este mai mic decât", + "conditionLessEqual": "mai mic sau egal", + "conditionLarger": "este mai mare decât", + "conditionLargerEqual": "mai mare sau egal", + "conditionContains": "conţine", + "conditionIs": "este", + "conditionStartsWith": "începe cu", + "conditionEndWith": "se termină cu", + "conditionNotContain": "nu conţine", + "conditionIsNot": "nu este", + "conditionNotStartWith": "nu începe cu", + "conditionNotEndWith": "nu se termină cu", + "conditionBefore": "înaintea", + "conditionAfter": "după", + "conditionRange": "interval", + "conditionIsEmpty": "este gol", + + "all": "toate", + "any": "oricare", + "relationAll": "toate regulile", + "waiRelAll": "Răspundeţi tuturor regulilor următoare:", + "relationAny": "oricare reguli", + "waiRelAny": "Răspundeţi oricărei dintre regulile următoare:", + "relationMsgFront": "Răspuns", + "relationMsgTail": "", + "and": "şi", + "or": "sau", + + "addRuleButton": "Adăugare regulă", + "waiAddRuleButton": "Adăugare regulă nouă", + "removeRuleButton": "Înlăturare regulă", + "waiRemoveRuleButtonTemplate": "Înlăturare regulă ${0}", + + "cancelButton": "Anulare", + "waiCancelButton": "Anulaţi acest dialog", + "clearButton": "Ştergere", + "waiClearButton": "Ştergeţi filtrul", + "filterButton": "Filtru", + "waiFilterButton": "Lansaţi în execuţie filtrul", + + "columnSelectLabel": "Coloană", + "waiColumnSelectTemplate": "Coloană pentru regulă ${0}", + "conditionSelectLabel": "Condiţie", + "waiConditionSelectTemplate": "Condiţie pentru regula ${0}", + "valueBoxLabel": "Valoare", + "waiValueBoxTemplate": "Introduceţi valoarea pentru filtrarea pentru regulă ${0}", + + "rangeTo": "la", + "rangeTemplate": "din ${0} la ${1}", + + "statusTipHeaderColumn": "Coloană", + "statusTipHeaderCondition": "Reguli", + "statusTipTitle": "Bară de filtru", + "statusTipMsg": "Faceţi clic pe bara de filtru aici pentru a filtra valorile în ${0}.", + "anycolumn": "orice coloană", + "statusTipTitleNoFilter": "Bară de filtru", + "statusTipTitleHasFilter": "Filtru", + "statusTipRelAny": "Potrivire orice regulă.", + "statusTipRelAll": "Potrivire toate regulile.", + + "defaultItemsName": "articole", + "filterBarMsgHasFilterTemplate": "${0} din ${1} ${2} afişate.", + "filterBarMsgNoFilterTemplate": "Niciun filtru nu este aplicat", + + "filterBarDefButton": "Definire filtru", + "waiFilterBarDefButton": "Filtrare tabelă", + "a11yFilterBarDefButton": "Filtru...", + "filterBarClearButton": "Ştergere filtru", + "waiFilterBarClearButton": "Ştergeţi filtrul", + "closeFilterBarBtn": "Închidere bară de filtru", + + "clearFilterMsg": "Aceasta va înlătura filtrul şi va afişa toate înregistrările disponibile.", + "anyColumnOption": "Orice coloană", + + "trueLabel": "Adevărat", + "falseLabel": "Fals" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js new file mode 100644 index 0000000..633a192 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ro/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} din ${1} ${0}", + "firstTip": "Prima pagină", + "lastTip": "Ultima pagină", + "nextTip": "Următoarea pagină", + "prevTip": "Pagina anterioarp", + "itemTitle": "articole", + "singularItemTitle": "articol", + "pageStepLabelTemplate": "Pagina ${0}", + "pageSizeLabelTemplate": "${0} articole pe pagină", + "allItemsLabelTemplate": "Toate articolele", + "gotoButtonTitle": "Deplasare la o pagină anumită", + "dialogTitle": "Deplasare la pagină", + "dialogIndication": "Specificaţi numărul de pagină", + "pageCountIndication": " (${0} pagini)", + "dialogConfirm": "Deplasare", + "dialogCancel": "Anulare", + "all": "toate" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js new file mode 100644 index 0000000..cdb44ac --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ru/EnhancedGrid", //begin v1.x content +({ + singleSort: "Простая сортировка", + nestedSort: "Вложенная сортировка", + ascending: "По возрастанию", + descending: "По убыванию", + sortingState: "${0} - ${1}", + unsorted: "Не сортировать этот столбец", + indirectSelectionRadio: "Строка ${0}, один выбор, радиокнопка", + indirectSelectionCheckBox: "Строка ${0}, несколько выборов, переключатель", + selectAll: "Выбрать все" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js new file mode 100644 index 0000000..ea9567d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ru/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Удалить фильтр", + "filterDefDialogTitle": "Фильтр", + "ruleTitleTemplate": "Правило ${0}", + + "conditionEqual": "равно", + "conditionNotEqual": "не равно", + "conditionLess": "меньше, чем", + "conditionLessEqual": "меньше или равно", + "conditionLarger": "больше, чем", + "conditionLargerEqual": "больше или равно", + "conditionContains": "содержит", + "conditionIs": "является", + "conditionStartsWith": "начинается с", + "conditionEndWith": "заканчивается на", + "conditionNotContain": "не содержит", + "conditionIsNot": "не является", + "conditionNotStartWith": "не начинается с", + "conditionNotEndWith": "не заканчивается на", + "conditionBefore": "до", + "conditionAfter": "после", + "conditionRange": "диапазон", + "conditionIsEmpty": "пустое", + + "all": "все", + "any": "любое", + "relationAll": "все правила", + "waiRelAll": "Соответствие всем следующим правилам:", + "relationAny": "любое правило", + "waiRelAny": "Соответствие любому из следующих правил:", + "relationMsgFront": "Соответствие", + "relationMsgTail": "", + "and": "и", + "or": "или", + + "addRuleButton": "Добавить правило", + "waiAddRuleButton": "Добавить новое правило", + "removeRuleButton": "Удалить правило", + "waiRemoveRuleButtonTemplate": "Удалить правило ${0}", + + "cancelButton": "Отмена", + "waiCancelButton": "Отменить этот диалог", + "clearButton": "Удалить", + "waiClearButton": "Удалить фильтр", + "filterButton": "Фильтр", + "waiFilterButton": "Передать фильтр", + + "columnSelectLabel": "Столбец", + "waiColumnSelectTemplate": "Столбец для правила ${0}", + "conditionSelectLabel": "Условие", + "waiConditionSelectTemplate": "Условие для правила ${0}", + "valueBoxLabel": "Значение", + "waiValueBoxTemplate": "Задайте значение фильтра для правила ${0}", + + "rangeTo": "до", + "rangeTemplate": "от ${0} до ${1}", + + "statusTipHeaderColumn": "Столбец", + "statusTipHeaderCondition": "Правила", + "statusTipTitle": "Панель фильтра", + "statusTipMsg": "Щелкните по панели фильтра, чтобы применить фильтр к значениям в ${0}.", + "anycolumn": "любой столбец", + "statusTipTitleNoFilter": "Панель фильтра", + "statusTipTitleHasFilter": "Фильтр", + "statusTipRelAny": "Соответствует любому из правил.", + "statusTipRelAll": "Соответствует всем правилам.", + + "defaultItemsName": "элементов", + "filterBarMsgHasFilterTemplate": "Показано ${0} из ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "Фильтр не применен", + + "filterBarDefButton": "Задать фильтр", + "waiFilterBarDefButton": "Применить фильтр к таблице", + "a11yFilterBarDefButton": "Фильтр...", + "filterBarClearButton": "Удалить фильтр", + "waiFilterBarClearButton": "Удалить фильтр", + "closeFilterBarBtn": "Закрыть панель фильтра", + + "clearFilterMsg": "Фильтр будет удален, и будут показаны все записи.", + "anyColumnOption": "Любой столбец", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js new file mode 100644 index 0000000..db662ca --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/ru/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} из ${1} ${0}", + "firstTip": "Первая страница", + "lastTip": "Последняя страница", + "nextTip": "Следующая страница", + "prevTip": "Предыдущая страница", + "itemTitle": "элементов", + "singularItemTitle": "элемент", + "pageStepLabelTemplate": "Страница ${0}", + "pageSizeLabelTemplate": "${0} элементов на странице", + "allItemsLabelTemplate": "Все элементы", + "gotoButtonTitle": "Перейти на определенную страницу", + "dialogTitle": "Перейти на страницу", + "dialogIndication": "Задайте номер страницы", + "pageCountIndication": " (${0} страниц)", + "dialogConfirm": "Перейти", + "dialogCancel": "Отмена", + "all": "все" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js new file mode 100644 index 0000000..9338e81 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sk/EnhancedGrid", //begin v1.x content +({ + singleSort: "Jednoduché triedenie", + nestedSort: "Vnorené triedenie", + ascending: "Vzostupne", + descending: "Zostupne", + sortingState: "${0} - ${1}", + unsorted: "Netriediť tento stĺpec", + indirectSelectionRadio: "Riadok ${0}, jednoduchý výber, prepínač", + indirectSelectionCheckBox: "Riadok ${0}, viacnásobný výber, začiarkavacie políčko", + selectAll: "Vybrať všetko" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js new file mode 100644 index 0000000..8d83150 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sk/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Zrušiť filter", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Pravidlo ${0}", + + "conditionEqual": "rovné", + "conditionNotEqual": "nerovné", + "conditionLess": "menšie ako", + "conditionLessEqual": "menšie ako alebo rovné", + "conditionLarger": "väčšie ako", + "conditionLargerEqual": "väčšie ako alebo rovné", + "conditionContains": "obsahuje", + "conditionIs": "je", + "conditionStartsWith": "začína s", + "conditionEndWith": "končí s", + "conditionNotContain": "neobsahuje", + "conditionIsNot": "nie je", + "conditionNotStartWith": "nezačína s", + "conditionNotEndWith": "nekončí s", + "conditionBefore": "pred", + "conditionAfter": "za", + "conditionRange": "rozsah", + "conditionIsEmpty": "je prázdne", + + "all": "všetko", + "any": "žiadne", + "relationAll": "všetky pravidlá", + "waiRelAll": "Vyhovovať všetkým týmto pravidlám:", + "relationAny": "ľubovoľné pravidlá", + "waiRelAny": "Vyhovovať ľubovoľným z týchto pravidiel:", + "relationMsgFront": "Vyhovieť", + "relationMsgTail": "", + "and": "a", + "or": "alebo", + + "addRuleButton": "Pridať pravidlo", + "waiAddRuleButton": "Pridať nové pravidlo", + "removeRuleButton": "Odstrániť pravidlo", + "waiRemoveRuleButtonTemplate": "Odstrániť pravidlo ${0}", + + "cancelButton": "Zrušiť", + "waiCancelButton": "Zrušiť toto dialógové okno", + "clearButton": "Zrušiť", + "waiClearButton": "Zrušiť filter", + "filterButton": "Filtrovať", + "waiFilterButton": "Odoslať filter", + + "columnSelectLabel": "Stĺpec", + "waiColumnSelectTemplate": "Stĺpec pre pravidlo ${0}", + "conditionSelectLabel": "Podmienka", + "waiConditionSelectTemplate": "Podmienka pre pravidlo ${0}", + "valueBoxLabel": "Hodnota", + "waiValueBoxTemplate": "Zadajte hodnotu na filtrovanie pre pravidlo ${0}", + + "rangeTo": "do", + "rangeTemplate": "od ${0} do ${1}", + + "statusTipHeaderColumn": "Stĺpec", + "statusTipHeaderCondition": "Pravidlá", + "statusTipTitle": "Lišta filtra", + "statusTipMsg": "Kliknite na lištu filtra, ak chcete filtrovať podľa hodnôt v ${0}.", + "anycolumn": "ľubovoľný stĺpec", + "statusTipTitleNoFilter": "Lišta filtra", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Zhoda s akýmikoľvek pravidlami.", + "statusTipRelAll": "Zhoda so všetkými pravidlami.", + + "defaultItemsName": "položky", + "filterBarMsgHasFilterTemplate": "Zobrazuje sa ${0} z ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "Nepoužíva sa žiadny filter", + + "filterBarDefButton": "Definovať filter", + "waiFilterBarDefButton": "Filtrovať tabuľku", + "a11yFilterBarDefButton": "Filtrovať...", + "filterBarClearButton": "Zrušiť filter", + "waiFilterBarClearButton": "Zrušiť filter", + "closeFilterBarBtn": "Zatvoriť lištu filtra", + + "clearFilterMsg": "Toto odstráni filter a zobrazí všetky dostupné záznamy", + "anyColumnOption": "Ľubovoľný stĺpec", + + "trueLabel": "Pravda", + "falseLabel": "Nepravda" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js new file mode 100644 index 0000000..ec6cb2e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sk/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} z ${1} ${0}", + "firstTip": "Prvá strana", + "lastTip": "Posledná strana", + "nextTip": "Ďalšia strana", + "prevTip": "Predošlá strana", + "itemTitle": "položiek", + "singularItemTitle": "položka", + "pageStepLabelTemplate": "Strana ${0}", + "pageSizeLabelTemplate": "${0} položiek na strane", + "allItemsLabelTemplate": "Všetky položky", + "gotoButtonTitle": "Prejsť na špecifickú stranu", + "dialogTitle": "Prejsť na stranu", + "dialogIndication": "Zadajte číslo strany", + "pageCountIndication": " (${0} strán)", + "dialogConfirm": "Prejsť", + "dialogCancel": "Zrušiť", + "all": "všetko" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js new file mode 100644 index 0000000..f2a3d6c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sl/EnhancedGrid", //begin v1.x content +({ + singleSort: "Enostavno razvrščanje", + nestedSort: "Ugnezdeno razvrščanje", + ascending: "Naraščajoče", + descending: "Padajoče", + sortingState: "${0} - ${1}", + unsorted: "Ne razvrščaj tega stolpca", + indirectSelectionRadio: "Vrstica ${0}, izbira enega elementa, okence z izbirnim gumbom", + indirectSelectionCheckBox: "Vrstica ${0}, izbira več elementov, okence s potrditvenimi polji", + selectAll: "Izberi vse" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js new file mode 100644 index 0000000..283b9c7 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sl/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Počisti filter", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Pravilo ${0}", + + "conditionEqual": "je enako", + "conditionNotEqual": "ni enako", + "conditionLess": "je manjše kot", + "conditionLessEqual": "je manjše kot ali enako", + "conditionLarger": "je večje kot", + "conditionLargerEqual": "je večje kot ali enako", + "conditionContains": "vsebuje", + "conditionIs": "je", + "conditionStartsWith": "se začne s", + "conditionEndWith": "se konča s", + "conditionNotContain": "ne vsebuje", + "conditionIsNot": "ni", + "conditionNotStartWith": "se ne začne s", + "conditionNotEndWith": "se ne konča s", + "conditionBefore": "pred", + "conditionAfter": "za", + "conditionRange": "obseg", + "conditionIsEmpty": "je prazno", + + "all": "vse", + "any": "karkoli", + "relationAll": "vsa pravila", + "waiRelAll": "Ujema se z vsemi od naslednjih pravil:", + "relationAny": "katerakoli pravila", + "waiRelAny": "Ujema se s katerimkoli od naslednjih pravil:", + "relationMsgFront": "Ujemanje", + "relationMsgTail": "", + "and": "in", + "or": "ali", + + "addRuleButton": "Dodaj pravilo", + "waiAddRuleButton": "Dodaj novo pravilo", + "removeRuleButton": "Odstrani pravilo", + "waiRemoveRuleButtonTemplate": "Odstrani pravilo ${0}", + + "cancelButton": "Prekliči", + "waiCancelButton": "Prekliči to pogovorno okno", + "clearButton": "Počisti", + "waiClearButton": "Počisti filter", + "filterButton": "Filter", + "waiFilterButton": "Predloži filter", + + "columnSelectLabel": "Stolpec", + "waiColumnSelectTemplate": "Stolpec za pravilo ${0}", + "conditionSelectLabel": "Pogoj", + "waiConditionSelectTemplate": "Pogoj za pravilo ${0}", + "valueBoxLabel": "Vrednost", + "waiValueBoxTemplate": "Vnesite vrednost za filter pravila ${0}", + + "rangeTo": "do", + "rangeTemplate": "od ${0} do ${1}", + + "statusTipHeaderColumn": "Stolpec", + "statusTipHeaderCondition": "Pravila", + "statusTipTitle": "Vrstica za filtriranje", + "statusTipMsg": "Kliknite vrstico za filtriranje tukaj, da prefiltrirate vrednosti v ${0}.", + "anycolumn": "katerikoli stolpec", + "statusTipTitleNoFilter": "Vrstica za filtriranje", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Ujemanje s katerimkoli pravilom.", + "statusTipRelAll": "Ujemanje z vsemi pravili.", + + "defaultItemsName": "postavke", + "filterBarMsgHasFilterTemplate": "Prikazanih je ${0} od ${1} ${2}.", + "filterBarMsgNoFilterTemplate": "Uveljavljen ni noben filter.", + + "filterBarDefButton": "Definiraj filter", + "waiFilterBarDefButton": "Filtriraj tabelo", + "a11yFilterBarDefButton": "Filtriraj ...", + "filterBarClearButton": "Počisti filter", + "waiFilterBarClearButton": "Počisti filter", + "closeFilterBarBtn": "Zapri vrstico za filtriranje", + + "clearFilterMsg": "S tem boste odstranili filter in prikazali se bodo vsi razpoložljivi zapisi.", + "anyColumnOption": "Katerikoli stolpec", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js new file mode 100644 index 0000000..5ea9222 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sl/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} od ${1} ${0}", + "firstTip": "Prva stran", + "lastTip": "Zadnja stran", + "nextTip": "Naslednja stran", + "prevTip": "Prejšnja stran", + "itemTitle": "postavke", + "singularItemTitle": "postavka", + "pageStepLabelTemplate": "Stran ${0}", + "pageSizeLabelTemplate": "${0} postavk na stran", + "allItemsLabelTemplate": "Vse postavke", + "gotoButtonTitle": "Pojdi na specifično stran", + "dialogTitle": "Pojdi na stran", + "dialogIndication": "Podajte številko strani", + "pageCountIndication": " (${0} strani)", + "dialogConfirm": "Pojdi", + "dialogCancel": "Prekliči", + "all": "vse" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js new file mode 100644 index 0000000..dd6d606 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sv/EnhancedGrid", //begin v1.x content +({ + singleSort: "Enkel sortering", + nestedSort: "Nästlad sortering", + ascending: "Stigande", + descending: "Fallande", + sortingState: "${0} - ${1}", + unsorted: "Sortera inte den här kolumnen", + indirectSelectionRadio: "Rad ${0}, ett enda val, alternativruta", + indirectSelectionCheckBox: "Rad ${0}, flera val, kryssruta", + selectAll: "Markera alla " +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js new file mode 100644 index 0000000..2a58c48 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sv/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Rensa filter", + "filterDefDialogTitle": "Filter", + "ruleTitleTemplate": "Regel ${0}", + + "conditionEqual": "lika med", + "conditionNotEqual": "inte lika med", + "conditionLess": "är mindre än", + "conditionLessEqual": "mindre eller lika med", + "conditionLarger": "är större än", + "conditionLargerEqual": "större än eller lika med", + "conditionContains": "innehåller", + "conditionIs": "är", + "conditionStartsWith": "börjar med", + "conditionEndWith": "slutar med", + "conditionNotContain": "innehåller inte", + "conditionIsNot": "är inte", + "conditionNotStartWith": "börjar inte med", + "conditionNotEndWith": "slutar inte med", + "conditionBefore": "före", + "conditionAfter": "efter", + "conditionRange": "intervall", + "conditionIsEmpty": "är tom", + + "all": "alla", + "any": "någon", + "relationAll": "alla regler", + "waiRelAll": "Matcha alla följande regler:", + "relationAny": "någon regel", + "waiRelAny": "Matcha någon av följande regler:", + "relationMsgFront": "Matcha", + "relationMsgTail": "", + "and": "och", + "or": "eller", + + "addRuleButton": "Lägg till regel", + "waiAddRuleButton": "Lägg till en ny regel", + "removeRuleButton": "Ta bort regel", + "waiRemoveRuleButtonTemplate": "Ta bort regel ${0}", + + "cancelButton": "Avbryt", + "waiCancelButton": "Avbryt dialogen", + "clearButton": "Rensa", + "waiClearButton": "Rensa filtret", + "filterButton": "Filtrera", + "waiFilterButton": "Filtrera", + + "columnSelectLabel": "Kolumn", + "waiColumnSelectTemplate": "Kolumn för regel ${0}", + "conditionSelectLabel": "Villkor", + "waiConditionSelectTemplate": "Villkor för regel ${0}", + "valueBoxLabel": "Värde", + "waiValueBoxTemplate": "Ange värde för filtrering efter regeln ${0}", + + "rangeTo": "till", + "rangeTemplate": "från ${0} till ${1}", + + "statusTipHeaderColumn": "Kolumn", + "statusTipHeaderCondition": "Regler", + "statusTipTitle": "Filterfält", + "statusTipMsg": "Klicka på filterfältet om du vill filtrera värden i ${0}.", + "anycolumn": "alla kolumner", + "statusTipTitleNoFilter": "Filterfält", + "statusTipTitleHasFilter": "Filter", + "statusTipRelAny": "Matcha någon regel.", + "statusTipRelAll": "Matcha alla regler.", + + "defaultItemsName": "objekt", + "filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} visas.", + "filterBarMsgNoFilterTemplate": "Inget filter tillämpat", + + "filterBarDefButton": "Definiera filter", + "waiFilterBarDefButton": "Filtrera tabellen", + "a11yFilterBarDefButton": "Filter...", + "filterBarClearButton": "Rensa filter", + "waiFilterBarClearButton": "Rensa filtret", + "closeFilterBarBtn": "Stäng filterfält", + + "clearFilterMsg": "Tar bort filtret och visar alla tillgängliga poster.", + "anyColumnOption": "Alla kolumner", + + "trueLabel": "Sant", + "falseLabel": "Falskt" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js new file mode 100644 index 0000000..472d5e8 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/sv/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} av ${1} ${0}", + "firstTip": "Första sidan", + "lastTip": "Sista sidan", + "nextTip": "Nästa sida", + "prevTip": "Föregående sida", + "itemTitle": "objekt", + "singularItemTitle": "objekt", + "pageStepLabelTemplate": "Sida ${0}", + "pageSizeLabelTemplate": "${0} objekt per sida", + "allItemsLabelTemplate": "Alla objekt", + "gotoButtonTitle": "Gå till en viss sida", + "dialogTitle": "Gå till sidan", + "dialogIndication": "Ange sidnummer", + "pageCountIndication": " (${0} sidor)", + "dialogConfirm": "Gå", + "dialogCancel": "Avbryt", + "all": "alla" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js new file mode 100644 index 0000000..d0bd82c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/th/EnhancedGrid", //begin v1.x content +({ + singleSort: "เรียงลำดับแบบเดี่ยว", + nestedSort: "เรียงลำดับที่ซับซ้อน", + ascending: "จากน้อยไปหามาก", + descending: "จากมากไปหาน้อย", + sortingState: "${0} - ${1}", + unsorted: "ห้ามเรียงลำดับคอลัมน์นี้", + indirectSelectionRadio: "แถว ${0}, การเลือกเดียว, กล่องวิทยุ", + indirectSelectionCheckBox: "แถว ${0}, การเลือกจำนวนมาก, เช็กบ็อกซ์", + selectAll: "เลือกทั้งหมด" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js new file mode 100644 index 0000000..cb3f948 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/th/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "ลบตัวกรอง", + "filterDefDialogTitle": "ตัวกรอง", + "ruleTitleTemplate": "กฏ ${0}", + + "conditionEqual": "เท่ากับ", + "conditionNotEqual": "ไม่เท่ากับ", + "conditionLess": "น้อยกว่า", + "conditionLessEqual": "น้อยกว่าหรือเท่ากับ", + "conditionLarger": "มากกว่า", + "conditionLargerEqual": "มากกว่าหรือเท่ากับ", + "conditionContains": "ประกอบด้วย", + "conditionIs": "เป็น", + "conditionStartsWith": "เริ่มต้นด้วย", + "conditionEndWith": "ลงท้ายด้วย", + "conditionNotContain": "ไม่ประกอบด้วย", + "conditionIsNot": "ไม่", + "conditionNotStartWith": "ไม่เริ่มต้นด้วย", + "conditionNotEndWith": "ไม่ลงท้ายด้วย", + "conditionBefore": "ก่อน", + "conditionAfter": "หลัง", + "conditionRange": "ช่วง", + "conditionIsEmpty": "ว่างอยู่", + + "all": "ทั้งหมด", + "any": "ใด", + "relationAll": "กฏทั้งหมด", + "waiRelAll": "ตรงกับกฏทั้งหมดต่อไปนี้:", + "relationAny": "กฏใดๆ", + "waiRelAny": "ตรงกับกฏใดๆต่อไปนี้:", + "relationMsgFront": "ตรงกับ", + "relationMsgTail": "", + "and": "และ", + "or": "หรือ", + + "addRuleButton": "เพิ่มกฏ", + "waiAddRuleButton": "เพิ่มกฏใหม่", + "removeRuleButton": "ลบกฏ", + "waiRemoveRuleButtonTemplate": "ลบกฏ ${0}", + + "cancelButton": "ยกเลิก", + "waiCancelButton": "ยกเลิกไดอะล็อกนี้", + "clearButton": "ลบ", + "waiClearButton": "ลบตัวกรอง", + "filterButton": "ตัวกรอง", + "waiFilterButton": "ส่งตัวกรอง", + + "columnSelectLabel": "คอลัมน์", + "waiColumnSelectTemplate": "คอลัมน์สำหรับกฏ ${0}", + "conditionSelectLabel": "เงื่อนไข", + "waiConditionSelectTemplate": "เงื่อนไขสำหรับกฏ ${0}", + "valueBoxLabel": "ค่า", + "waiValueBoxTemplate": "ป้อนค่าให้กับตัวกรองสำหรับกฏ ${0}", + + "rangeTo": "ถึง", + "rangeTemplate": "จาก ${0} ถึง ${1}", + + "statusTipHeaderColumn": "คอลัมน์", + "statusTipHeaderCondition": "กฏ", + "statusTipTitle": "แถบตัวกรอง", + "statusTipMsg": "คลิกที่แถบตัวกรองที่นี่เพื่อกรองค่าใน ${0}", + "anycolumn": "คอลัมน์ใดๆ", + "statusTipTitleNoFilter": "แถบตัวกรอง", + "statusTipTitleHasFilter": "ตัวกรอง", + "statusTipRelAny": "ตรงกับกฏใดๆ", + "statusTipRelAll": "ตรงกับทุกกฏ", + + "defaultItemsName": "ไอเท็ม", + "filterBarMsgHasFilterTemplate": "${0} ของ ${1} ${2} จะถูกแสดง", + "filterBarMsgNoFilterTemplate": "ไม่นำตัวกรองไปใช้", + + "filterBarDefButton": "กำหนดตัวกรอง", + "waiFilterBarDefButton": "กรองตาราง", + "a11yFilterBarDefButton": "ตัวกรอง...", + "filterBarClearButton": "ลบตัวกรอง", + "waiFilterBarClearButton": "ลบตัวกรอง", + "closeFilterBarBtn": "ปิดแถบตัวกรอง", + + "clearFilterMsg": "ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด", + "anyColumnOption": "คอลัมน์ใดๆ", + + "trueLabel": "จริง", + "falseLabel": "เท็จ" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js new file mode 100644 index 0000000..b3d536e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/th/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} จาก ${1} ${0}", + "firstTip": "หน้าแรก", + "lastTip": "หน้าสุดท้าย", + "nextTip": "หน้าถัดไป", + "prevTip": "หน้าก่อนหน้านี้", + "itemTitle": "ไอเท็ม", + "singularItemTitle": "ไอเท็ม", + "pageStepLabelTemplate": "หน้า ${0}", + "pageSizeLabelTemplate": "${0} ไอเท็มต่อหน้า", + "allItemsLabelTemplate": "รายการ ทั้งหมด", + "gotoButtonTitle": "ไปที่หน้าที่ระบุ", + "dialogTitle": "ไปที่หน้า", + "dialogIndication": "ระบุหมายเลขหน้า", + "pageCountIndication": " (${0} หน้า)", + "dialogConfirm": "ไปที่", + "dialogCancel": "ยกเลิก", + "all": "ทั้งหมด" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js new file mode 100644 index 0000000..78c566b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/tr/EnhancedGrid", //begin v1.x content +({ + singleSort: "Tekli Sıralama", + nestedSort: "İç İçe Sıralama", + ascending: "Artan Düzende", + descending: "Azalan Düzende", + sortingState: "${0} - ${1}", + unsorted: "Bu sütunu sıralama", + indirectSelectionRadio: "Satır ${0}, tek seçimli, radyo düğmesi", + indirectSelectionCheckBox: "Satır ${0}, çok seçimli, radyo düğmesi", + selectAll: "Tümünü seç" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js new file mode 100644 index 0000000..06ed5e7 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/tr/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "Süzgeci Kaldır", + "filterDefDialogTitle": "Süzgeç", + "ruleTitleTemplate": "Kural ${0}", + + "conditionEqual": "eşittir", + "conditionNotEqual": "eşit değildir", + "conditionLess": "küçüktür", + "conditionLessEqual": "küçüktür veya eşittir", + "conditionLarger": "büyüktür", + "conditionLargerEqual": "büyüktür veya eşittir", + "conditionContains": "içerir", + "conditionIs": "şudur", + "conditionStartsWith": "şununla başlar", + "conditionEndWith": "şununla biter", + "conditionNotContain": "içermez", + "conditionIsNot": "şu değildir", + "conditionNotStartWith": "şununla başlamaz", + "conditionNotEndWith": "şununla bitmez", + "conditionBefore": "önce", + "conditionAfter": "sonra", + "conditionRange": "aralık", + "conditionIsEmpty": "boş", + + "all": "tümü", + "any": "herhangi biri", + "relationAll": "tüm kurallar", + "waiRelAll": "Aşağıdaki tüm kurallarla eşleştir", + "relationAny": "kuralların herhangi biri", + "waiRelAny": "Aşağıdaki kuralların herhangi biri ile eşleştir", + "relationMsgFront": "Eşleştir", + "relationMsgTail": "", + "and": "ve", + "or": "veya", + + "addRuleButton": "Kural Ekle", + "waiAddRuleButton": "Yeni bir kural ekle", + "removeRuleButton": "Kuralı Kaldır", + "waiRemoveRuleButtonTemplate": "${0} kuralını kaldır", + + "cancelButton": "İptal", + "waiCancelButton": "Bu iletişim kutusunu iptal et", + "clearButton": "Kaldır", + "waiClearButton": "Süzgeci kaldır", + "filterButton": "Süzgeç", + "waiFilterButton": "Süzgeci gönder", + + "columnSelectLabel": "Sütun", + "waiColumnSelectTemplate": "${0} kuralı için sütun", + "conditionSelectLabel": "Koşul", + "waiConditionSelectTemplate": "${0} kuralı için koşul", + "valueBoxLabel": "Değer", + "waiValueBoxTemplate": "${0} kuralı için süzülecek değeri girin", + + "rangeTo": "bitiş", + "rangeTemplate": "${0} - ${1}", + + "statusTipHeaderColumn": "Sütun", + "statusTipHeaderCondition": "Kurallar", + "statusTipTitle": "Süzgeç Çubuğu", + "statusTipMsg": "${0} içindeki değerlere göre süzmek için burada süzgeç çubuğunu tıklatın.", + "anycolumn": "herhangi bir sütun", + "statusTipTitleNoFilter": "Süzgeç Çubuğu", + "statusTipTitleHasFilter": "Süzgeç", + "statusTipRelAny": "Herhangi bir kuralı eşleştir.", + "statusTipRelAll": "Bütün kuralları eşleştir.", + + "defaultItemsName": "öğe", + "filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} gösteriliyor.", + "filterBarMsgNoFilterTemplate": "Süzgeç uygulanmadı", + + "filterBarDefButton": "Süzgeç tanımla", + "waiFilterBarDefButton": "Tabloyu süz", + "a11yFilterBarDefButton": "Süz...", + "filterBarClearButton": "Süzgeci kaldır", + "waiFilterBarClearButton": "Süzgeci kaldır", + "closeFilterBarBtn": "Süzgeç çubuğunu kapat", + + "clearFilterMsg": "Bu seçenek süzgeci kaldırır ve tüm kullanılabilir kayıtları gösterir.", + "anyColumnOption": "Herhangi Bir Sütun", + + "trueLabel": "Doğru", + "falseLabel": "Yanlış" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js new file mode 100644 index 0000000..94eb9a2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js @@ -0,0 +1,24 @@ +//>>built +define( +"dojox/grid/enhanced/nls/tr/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} / ${1} ${0}", + "firstTip": "İlk Sayfa", + "lastTip": "Son Sayfa", + "nextTip": "Sonraki Sayfa", + "prevTip": "Önceki Sayfa", + "itemTitle": "öğe", + "singularItemTitle": "öğe", + "pageStepLabelTemplate": "Sayfa ${0}", + "pageSizeLabelTemplate": "Sayfa başına ${0} öğe", + "allItemsLabelTemplate": "Tüm öğeler", + "gotoButtonTitle": "Belirli bir sayfaya git", + "dialogTitle": "Sayfaya Git", + "dialogIndication": "Sayfa numarasını belirtin", + "pageCountIndication": " (${0} sayfa)", + "dialogConfirm": "Git", + "dialogCancel": "İptal", + "all": "tümü" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js new file mode 100644 index 0000000..d25ffdb --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/zh-tw/EnhancedGrid", //begin v1.x content +({ + singleSort: "單一排序", + nestedSort: "巢狀排序", + ascending: "遞增", + descending: "降冪", + sortingState: "${0} - ${1}", + unsorted: "請勿對此欄執行排序", + indirectSelectionRadio: "第 ${0} 行,單一選項,圓鈕框", + indirectSelectionCheckBox: "第 ${0} 行,多重選項,勾選框", + selectAll: "全選" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js new file mode 100644 index 0000000..4488b78 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/zh-tw/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "清除過濾器", + "filterDefDialogTitle": "過濾器", + "ruleTitleTemplate": "規則 ${0}", + + "conditionEqual": "等於", + "conditionNotEqual": "不等於", + "conditionLess": "是小於", + "conditionLessEqual": "小於或等於", + "conditionLarger": "是大於", + "conditionLargerEqual": "大於或等於", + "conditionContains": "內容", + "conditionIs": "是", + "conditionStartsWith": "開始於", + "conditionEndWith": "結束於", + "conditionNotContain": "不包含", + "conditionIsNot": "不是", + "conditionNotStartWith": "不開始於", + "conditionNotEndWith": "不結束於", + "conditionBefore": "之前", + "conditionAfter": "之後", + "conditionRange": "範圍", + "conditionIsEmpty": "為空", + + "all": "全部", + "any": "任何", + "relationAll": "所有規則", + "waiRelAll": "符合下列所有規則:", + "relationAny": "任何規則", + "waiRelAny": "符合下列任何規則:", + "relationMsgFront": "符合", + "relationMsgTail": "", + "and": "和", + "or": "或", + + "addRuleButton": "新增規則", + "waiAddRuleButton": "新增規則", + "removeRuleButton": "移除規則", + "waiRemoveRuleButtonTemplate": "移除規則 ${0}", + + "cancelButton": "取消", + "waiCancelButton": "取消此對話", + "clearButton": "清除", + "waiClearButton": "清除過濾器", + "filterButton": "過濾器", + "waiFilterButton": "提交過濾器", + + "columnSelectLabel": "直欄", + "waiColumnSelectTemplate": "規則 ${0} 的直欄", + "conditionSelectLabel": "條件", + "waiConditionSelectTemplate": "規則 ${0} 的條件", + "valueBoxLabel": "值", + "waiValueBoxTemplate": "輸入要針對規則 ${0} 過濾的值", + + "rangeTo": "至", + "rangeTemplate": "從 ${0} 至 ${1}", + + "statusTipHeaderColumn": "直欄", + "statusTipHeaderCondition": "規則", + "statusTipTitle": "過濾器列", + "statusTipMsg": "按一下這裡的過濾器列以過濾 ${0} 中的值。", + "anycolumn": "任何直欄", + "statusTipTitleNoFilter": "過濾器列", + "statusTipTitleHasFilter": "過濾器", + "statusTipRelAny": "符合任何規則。", + "statusTipRelAll": "符合所有規則。", + + "defaultItemsName": "項目", + "filterBarMsgHasFilterTemplate": "顯示 ${1} ${2} 之 ${0}。", + "filterBarMsgNoFilterTemplate": "未套用過濾器", + + "filterBarDefButton": "定義過濾器", + "waiFilterBarDefButton": "過濾表格", + "a11yFilterBarDefButton": "過濾器...", + "filterBarClearButton": "清除過濾器", + "waiFilterBarClearButton": "清除過濾器", + "closeFilterBarBtn": "關閉過濾器列", + + "clearFilterMsg": "這將會移除過濾器並顯示所有的可用記錄。", + "anyColumnOption": "任何直欄", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js new file mode 100644 index 0000000..8f29af0 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/zh-tw/Pagination", //begin v1.x content +({ + "descTemplate": "${2} - ${3} / ${1} ${0}", + "firstTip": "首頁", + "lastTip": "末頁", + "nextTip": "下一頁", + "prevTip": "上一頁", + "itemTitle": "項目", + "singularItemTitle": "項目", + "pageStepLabelTemplate": "第 ${0} 頁", + "pageSizeLabelTemplate": "每頁 ${0} 個項目", + "allItemsLabelTemplate": "所有項目", + "gotoButtonTitle": "跳至特定頁面", + "dialogTitle": "跳至頁面", + "dialogIndication": "指定頁碼", + "pageCountIndication": "(${0} 頁)", + "dialogConfirm": "執行", + "dialogCancel": "取消", + "all": "全部" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js new file mode 100644 index 0000000..6494ae4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js @@ -0,0 +1,17 @@ +//>>built +define( +"dojox/grid/enhanced/nls/zh/EnhancedGrid", //begin v1.x content +({ + singleSort: "单层排序", + nestedSort: "嵌套排序", + ascending: "升序", + descending: "降序", + sortingState: "${0} - ${1}", + unsorted: "请勿对此列进行排序", + indirectSelectionRadio: "第 ${0} 行,单选,单选框", + indirectSelectionCheckBox: "第 ${0} 行,多选,复选框", + selectAll: "全部选中" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js new file mode 100644 index 0000000..f0f9f2b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js @@ -0,0 +1,89 @@ +//>>built +define( +"dojox/grid/enhanced/nls/zh/Filter", //begin v1.x content +({ + "clearFilterDialogTitle": "清除过滤器", + "filterDefDialogTitle": "过滤器", + "ruleTitleTemplate": "规则 ${0}", + + "conditionEqual": "等于", + "conditionNotEqual": "不等于", + "conditionLess": "小于", + "conditionLessEqual": "小于或等于", + "conditionLarger": "大于", + "conditionLargerEqual": "大于或等于", + "conditionContains": "包含", + "conditionIs": "是", + "conditionStartsWith": "开始于", + "conditionEndWith": "结束于", + "conditionNotContain": "不包含", + "conditionIsNot": "非", + "conditionNotStartWith": "不是开始于", + "conditionNotEndWith": "不是结束于", + "conditionBefore": "先于", + "conditionAfter": "后于", + "conditionRange": "范围", + "conditionIsEmpty": "为空", + + "all": "全部", + "any": "任何", + "relationAll": "所有规则", + "waiRelAll": "符合以下所有规则:", + "relationAny": "任何规则", + "waiRelAny": "符合以下任何规则:", + "relationMsgFront": "符合", + "relationMsgTail": "", + "and": "和", + "or": "或", + + "addRuleButton": "添加规则", + "waiAddRuleButton": "添加新规则", + "removeRuleButton": "除去规则", + "waiRemoveRuleButtonTemplate": "除去规则 ${0}", + + "cancelButton": "取消", + "waiCancelButton": "取消该对话", + "clearButton": "清除", + "waiClearButton": "清除过滤器", + "filterButton": "过滤器", + "waiFilterButton": "提交过滤器", + + "columnSelectLabel": "列", + "waiColumnSelectTemplate": "规则 ${0} 的列", + "conditionSelectLabel": "条件", + "waiConditionSelectTemplate": "规则 ${0} 的条件", + "valueBoxLabel": "值", + "waiValueBoxTemplate": "将规则 ${0} 的值输入过滤器", + + "rangeTo": "到", + "rangeTemplate": "从 ${0} 到 ${1}", + + "statusTipHeaderColumn": "列", + "statusTipHeaderCondition": "规则", + "statusTipTitle": "过滤器栏", + "statusTipMsg": "单击此处的过滤器栏以过滤 ${0} 中的值。", + "anycolumn": "任何列", + "statusTipTitleNoFilter": "过滤器栏", + "statusTipTitleHasFilter": "过滤器", + "statusTipRelAny": "与任何规则匹配。", + "statusTipRelAll": "与所有规则匹配。", + + "defaultItemsName": "项目", + "filterBarMsgHasFilterTemplate": "显示的 ${1} ${2} 的 ${0}。", + "filterBarMsgNoFilterTemplate": "未使用过滤器", + + "filterBarDefButton": "定义过滤器", + "waiFilterBarDefButton": "过滤表", + "a11yFilterBarDefButton": "过滤器...", + "filterBarClearButton": "清除过滤器", + "waiFilterBarClearButton": "清除过滤器", + "closeFilterBarBtn": "关闭过滤器栏", + + "clearFilterMsg": "该操作将除去过滤器并显示所有现有记录。", + "anyColumnOption": "任何列", + + "trueLabel": "True", + "falseLabel": "False" +}) +//end v1.x content +); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js new file mode 100644 index 0000000..1e1b5c6 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js @@ -0,0 +1,25 @@ +//>>built +define( +"dojox/grid/enhanced/nls/zh/Pagination", //begin v1.x content +({ + "descTemplate": "${1} 个${0}中的 ${2} - ${3}", + "firstTip": "第一页", + "lastTip": "最后一页", + "nextTip": "下一页", + "prevTip": "上一页", + "itemTitle": "项目", + "singularItemTitle": "项", + "pageStepLabelTemplate": "第 ${0} 页", + "pageSizeLabelTemplate": "每页的 ${0} 项目", + "allItemsLabelTemplate": "所有项目", + "gotoButtonTitle": "转到指定页面", + "dialogTitle": "转到页面", + "dialogIndication": "指定页数", + "pageCountIndication": "(${0} 页)", + "dialogConfirm": "确定", + "dialogCancel": "取消", + "all": "全部" +}) +//end v1.x content +); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js new file mode 100644 index 0000000..0dcb466 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js @@ -0,0 +1,182 @@ +//>>built +define("dojox/grid/enhanced/plugins/AutoScroll", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/html", + "dojo/_base/window", + "../_Plugin", + "../../_RowSelector", + "../../EnhancedGrid" +], function(declare, array, lang, html, win, _Plugin, _RowSelector, EnhancedGrid){ + +var AutoScroll = declare("dojox.grid.enhanced.plugins.AutoScroll", _Plugin, { + // summary: + // Provides horizontal and vertical auto-scroll for grid. + + // name: String + // Plugin name + name: "autoScroll", + + // autoScrollInterval: Integer + // The time interval (in miliseconds) between 2 scrolling. + autoScrollInterval: 1000, + + // autoScrollMargin: Integer + // The width (in pixel) of the margin area where autoscroll can be triggered. + autoScrollMargin: 30, + + constructor: function(grid, args){ + this.grid = grid; + this.readyForAutoScroll = false; + this._scrolling = false; + args = lang.isObject(args) ? args : {}; + if("interval" in args){ + this.autoScrollInterval = args.interval; + } + if("margin" in args){ + this.autoScrollMargin = args.margin; + } + this._initEvents(); + this._mixinGrid(); + }, + _initEvents: function(){ + var g = this.grid; + this.connect(g, "onCellMouseDown", function(){ + this.readyForAutoScroll = true; + }); + this.connect(g, "onHeaderCellMouseDown", function(){ + this.readyForAutoScroll = true; + }); + this.connect(g, "onRowSelectorMouseDown", function(){ + this.readyForAutoScroll = true; + }); + this.connect(win.doc, "onmouseup", function(evt){ + this._manageAutoScroll(true); + this.readyForAutoScroll = false; + }); + this.connect(win.doc, "onmousemove", function(evt){ + if(this.readyForAutoScroll){ + this._event = evt; + var gridPos = html.position(g.domNode), + hh = g._getHeaderHeight(), + margin = this.autoScrollMargin, + ey = evt.clientY, ex = evt.clientX, + gy = gridPos.y, gx = gridPos.x, + gh = gridPos.h, gw = gridPos.w; + if(ex >= gx && ex <= gx + gw){ + if(ey >= gy + hh && ey < gy + hh + margin){ + this._manageAutoScroll(false, true, false); + return; + }else if(ey > gy + gh - margin && ey <= gy + gh){ + this._manageAutoScroll(false, true, true); + return; + }else if(ey >= gy && ey <= gy + gh){ + var withinSomeview = array.some(g.views.views, function(view, i){ + if(view instanceof _RowSelector){ + return false; + } + var viewPos = html.position(view.domNode); + if(ex < viewPos.x + margin && ex >= viewPos.x){ + this._manageAutoScroll(false, false, false, view); + return true; + }else if(ex > viewPos.x + viewPos.w - margin && ex < viewPos.x + viewPos.w){ + this._manageAutoScroll(false, false, true, view); + return true; + } + return false; + }, this); + if(withinSomeview){ + return; + } + } + } + //stop autoscroll. + this._manageAutoScroll(true); + } + }); + }, + _mixinGrid: function(){ + var g = this.grid; + g.onStartAutoScroll = function(/*isVertical, isForward*/){}; + g.onEndAutoScroll = function(/*isVertical, isForward, view, scrollToRowIndex, event*/){}; + }, + _fireEvent: function(eventName, args){ + var g = this.grid; + switch(eventName){ + case "start": + g.onStartAutoScroll.apply(g, args); + break; + case "end": + g.onEndAutoScroll.apply(g, args); + break; + } + }, + _manageAutoScroll: function(toStop, isVertical, isForward, view){ + if(toStop){ + this._scrolling = false; + clearInterval(this._handler); + }else if(!this._scrolling){ + this._scrolling = true; + this._fireEvent("start", [isVertical, isForward, view]); + this._autoScroll(isVertical, isForward, view); + this._handler = setInterval(lang.hitch(this, "_autoScroll", isVertical, isForward, view), this.autoScrollInterval); + } + }, + _autoScroll: function(isVertical, isForward, view){ + var g = this.grid, + target = null; + if(isVertical){ + var targetRow = g.scroller.firstVisibleRow + (isForward ? 1 : -1); + if(targetRow >= 0 && targetRow < g.rowCount){ + g.scrollToRow(targetRow); + target = targetRow; + } + }else{ + target = this._scrollColumn(isForward, view); + } + if(target !== null){ + this._fireEvent("end", [isVertical, isForward, view, target, this._event]); + } + }, + _scrollColumn: function(isForward, view){ + var node = view.scrollboxNode, + target = null; + if(node.clientWidth < node.scrollWidth){ + var cells = array.filter(this.grid.layout.cells, function(cell){ + return !cell.hidden; + }); + var viewPos = html.position(view.domNode); + var limit, edge, headerPos, i; + if(isForward){ + limit = node.clientWidth; + for(i = 0; i < cells.length; ++i){ + headerPos = html.position(cells[i].getHeaderNode()); + edge = headerPos.x - viewPos.x + headerPos.w; + if(edge > limit){ + target = cells[i].index; + node.scrollLeft += edge - limit + 10; + break; + } + } + }else{ + limit = 0; + for(i = cells.length - 1; i >= 0; --i){ + headerPos = html.position(cells[i].getHeaderNode()); + edge = headerPos.x - viewPos.x; + if(edge < limit){ + target = cells[i].index; + node.scrollLeft += edge - limit - 10; + break; + } + } + } + } + return target; + } +}); + +EnhancedGrid.registerPlugin(AutoScroll); + +return AutoScroll; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js new file mode 100644 index 0000000..7284ace --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js @@ -0,0 +1,276 @@ +//>>built +define("dojox/grid/enhanced/plugins/CellMerge", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/html", + "../_Plugin", + "../../EnhancedGrid" +], function(declare, array, lang, html, _Plugin, EnhancedGrid){ + +var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, { + // summary: + // This plugin provides functions to merge(un-merge) adjacent cells within one row. + // Acceptable plugin paramters: + // 1. mergedCells: Array + // An array of objects with structure: + // { + // row: function(Integer)|Integer + // If it's a function, it's a predicate to decide which rows are to be merged. + // It takes an integer (the row index), and should return true or false; + // start: Integer + // The column index of the left most cell that shall be merged. + // end: Integer + // The column index of the right most cell that shall be merged. + // major: Integer + // The column index of the cell whose content should be used as the content of the merged cell. + // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex. + // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used. + // } + + // name: String + // Plugin name + name: "cellMerge", + + constructor: function(grid, args){ + this.grid = grid; + this._records = []; + this._merged = {}; + if(args && lang.isObject(args)){ + this._setupConfig(args.mergedCells); + } + this._initEvents(); + this._mixinGrid(); + }, + //----------------Public---------------------------- + mergeCells: function(rowTester, startColumnIndex, endColumnIndex, majorColumnIndex){ + // summary: + // Merge cells from *startColumnIndex* to *endColumnIndex* at rows that make *rowTester* return true, + // using the content of the cell at *majorColumnIndex* + // tags: + // public + // rowTester: function(Integer)|Integer + // If it's a function, it's a predicate to decide which rows are to be merged. + // It takes an integer (the row index), and should return true or false; + // startColumnIndex: Integer + // The column index of the left most cell that shall be merged. + // endColumnIndex: Integer + // The column index of the right most cell that shall be merged. + // majorColumnIndex: Integer? + // The column index of the cell whose content should be used as the content of the merged cell. + // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex. + // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used. + // return: Object | null + // A handler for the merged cells created by a call of this function. + // This handler can be used later to unmerge cells using the function unmergeCells + // If the merge is not valid, returns null; + var item = this._createRecord({ + "row": rowTester, + "start": startColumnIndex, + "end": endColumnIndex, + "major": majorColumnIndex + }); + if(item){ + this._updateRows(item); + } + return item; + }, + unmergeCells: function(mergeHandler){ + // summary: + // Unmerge the cells that are merged by the *mergeHandler*, which represents a call to the function mergeCells. + // tags: + // public + // mergeHandler: object + // A handler for the merged cells created by a call of function mergeCells. + var idx; + if(mergeHandler && (idx = array.indexOf(this._records, mergeHandler)) >= 0){ + this._records.splice(idx, 1); + this._updateRows(mergeHandler); + } + }, + getMergedCells: function(){ + // summary: + // Get all records of currently merged cells. + // tags: + // public + // return: Array + // An array of records for merged-cells. + // The record has the following structure: + // { + // "row": 1, //the row index + // "start": 2, //the start column index + // "end": 4, //the end column index + // "major": 3, //the major column index + // "handle": someHandle, //The handler that covers this merge cell record. + // } + var res = []; + for(var i in this._merged){ + res = res.concat(this._merged[i]); + } + return res; + }, + getMergedCellsByRow: function(rowIndex){ + // summary: + // Get the records of currently merged cells at the given row. + // tags: + // public + // return: Array + // An array of records for merged-cells. See docs of getMergedCells. + return this._merged[rowIndex] || []; + }, + + //----------------Private-------------------------- + _setupConfig: function(config){ + array.forEach(config, this._createRecord, this); + }, + _initEvents: function(){ + array.forEach(this.grid.views.views, function(view){ + this.connect(view, "onAfterRow", lang.hitch(this, "_onAfterRow", view.index)); + }, this); + }, + _mixinGrid: function(){ + var g = this.grid; + g.mergeCells = lang.hitch(this, "mergeCells"); + g.unmergeCells = lang.hitch(this, "unmergeCells"); + g.getMergedCells = lang.hitch(this, "getMergedCells"); + g.getMergedCellsByRow = lang.hitch(this, "getMergedCellsByRow"); + }, + _getWidth: function(colIndex){ + var node = this.grid.layout.cells[colIndex].getHeaderNode(); + return html.position(node).w; + }, + _onAfterRow: function(viewIdx, rowIndex, subrows){ + try{ + if(rowIndex < 0){ + return; + } + var result = [], i, j, len = this._records.length, + cells = this.grid.layout.cells; + //Apply merge-cell requests one by one. + for(i = 0; i < len; ++i){ + var item = this._records[i]; + var storeItem = this.grid._by_idx[rowIndex]; + if(item.view == viewIdx && item.row(rowIndex, storeItem && storeItem.item, this.grid.store)){ + var res = { + record: item, + hiddenCells: [], + totalWidth: 0, + majorNode: cells[item.major].getNode(rowIndex), + majorHeaderNode: cells[item.major].getHeaderNode() + }; + //Calculated the width of merged cell. + for(j = item.start; j <= item.end; ++j){ + var w = this._getWidth(j, rowIndex); + res.totalWidth += w; + if(j != item.major){ + res.hiddenCells.push(cells[j].getNode(rowIndex)); + } + } + //If width is valid, remember it. There may be multiple merges within one row. + if(subrows.length != 1 || res.totalWidth > 0){ + //Remove conflicted merges. + for(j = result.length - 1; j >= 0; --j){ + var r = result[j].record; + if((r.start >= item.start && r.start <= item.end) || + (r.end >= item.start && r.end <= item.end)){ + result.splice(j, 1); + } + } + result.push(res); + } + } + } + this._merged[rowIndex] = []; + array.forEach(result, function(res){ + array.forEach(res.hiddenCells, function(node){ + html.style(node, "display", "none"); + }); + var pbm = html.marginBox(res.majorHeaderNode).w - html.contentBox(res.majorHeaderNode).w; + var tw = res.totalWidth; + + //Tricky for WebKit. + if(!html.isWebKit){ + tw -= pbm; + } + + html.style(res.majorNode, "width", tw + "px"); + //In case we're dealing with multiple subrows. + res.majorNode.setAttribute("colspan", res.hiddenCells.length + 1); + + this._merged[rowIndex].push({ + "row": rowIndex, + "start": res.record.start, + "end": res.record.end, + "major": res.record.major, + "handle": res.record + }); + }, this); + }catch(e){ + console.warn("CellMerge._onAfterRow() error: ", rowIndex, e); + } + }, + _createRecord: function(item){ + if(this._isValid(item)){ + item = { + "row": item.row, + "start": item.start, + "end": item.end, + "major": item.major + }; + var cells = this.grid.layout.cells; + item.view = cells[item.start].view.index; + item.major = typeof item.major == "number" && !isNaN(item.major) ? item.major : item.start; + if(typeof item.row == "number"){ + var r = item.row; + item.row = function(rowIndex){ + return rowIndex === r; + }; + }else if(typeof item.row == "string"){ + var id = item.row; + item.row = function(rowIndex, storeItem, store){ + try{ + if(store && storeItem && store.getFeatures()['dojo.data.api.Identity']){ + return store.getIdentity(storeItem) == id; + } + }catch(e){ + console.error(e); + } + return false; + }; + } + if(lang.isFunction(item.row)){ + this._records.push(item); + return item; + } + } + return null; + }, + _isValid: function(item){ + var cells = this.grid.layout.cells, + colCount = cells.length; + return (lang.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) && + item.start >= 0 && item.start < colCount && + item.end > item.start && item.end < colCount && + cells[item.start].view.index == cells[item.end].view.index && + cells[item.start].subrow == cells[item.end].subrow && + !(typeof item.major == "number" && (item.major < item.start || item.major > item.end))); + }, + _updateRows: function(item){ + var min = null; + for(var i = 0, count = this.grid.rowCount; i < count; ++i){ + var storeItem = this.grid._by_idx[i]; + if(storeItem && item.row(i, storeItem && storeItem.item, this.grid.store)){ + this.grid.views.updateRow(i); + if(min === null){ min = i; } + } + } + if(min >= 0){ + this.grid.scroller.rowHeightChanged(min); + } + } +}); + +EnhancedGrid.registerPlugin(CellMerge); + +return CellMerge; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js new file mode 100644 index 0000000..d0160f7 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js @@ -0,0 +1,362 @@ +//>>built +define("dojox/grid/enhanced/plugins/Cookie", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/sniff", + "dojo/_base/html", + "dojo/_base/json", + "dojo/_base/window", + "dojo/_base/unload", + "dojo/cookie", + "../_Plugin", + "../../_RowSelector", + "../../EnhancedGrid", + "../../cells/_base" +], function(declare, array, lang, has, html, json, win, unload, cookie, _Plugin, _RowSelector, EnhancedGrid){ + + var gridCells = lang.getObject("dojox.grid.cells"); + + // Generate a cookie key for the given grid. + var _cookieKeyBuilder = function(grid){ + return window.location + "/" + grid.id; + }; + + //Utilities: + var _getCellsFromStructure = function(structure){ + var cells = []; + if(!lang.isArray(structure)){ + structure = [structure]; + } + array.forEach(structure,function(viewDef){ + if(lang.isArray(viewDef)){ + viewDef = {"cells" : viewDef}; + } + var rows = viewDef.rows || viewDef.cells; + if(lang.isArray(rows)){ + if(!lang.isArray(rows[0])){ + rows = [rows]; + } + array.forEach(rows, function(row){ + if(lang.isArray(row)){ + array.forEach(row, function(cell){ + cells.push(cell); + }); + } + }); + } + }); + return cells; + }; + + // Persist column width + var _loadColWidth = function(colWidths, grid){ + if(lang.isArray(colWidths)){ + var oldFunc = grid._setStructureAttr; + grid._setStructureAttr = function(structure){ + if(!grid._colWidthLoaded){ + grid._colWidthLoaded = true; + var cells = _getCellsFromStructure(structure); + for(var i = cells.length - 1; i >= 0; --i){ + if(typeof colWidths[i] == "number"){ + cells[i].width = colWidths[i] + "px"; + }else if(colWidths[i] == 'hidden'){ + cells[i].hidden = true; + } + } + } + oldFunc.call(grid, structure); + grid._setStructureAttr = oldFunc; + }; + } + }; + + + var _saveColWidth = function(grid){ + return array.map(array.filter(grid.layout.cells, function(cell){ + return !(cell.isRowSelector || cell instanceof gridCells.RowIndex); + }), function(cell){ + return cell.hidden ? 'hidden' : html[has("webkit") ? "marginBox" : "contentBox"](cell.getHeaderNode()).w; + }); + }; + + // Persist column order + var _loadColumnOrder = function(colOrder, grid){ + if(colOrder && array.every(colOrder, function(viewInfo){ + return lang.isArray(viewInfo) && array.every(viewInfo, function(subrowInfo){ + return lang.isArray(subrowInfo) && subrowInfo.length > 0; + }); + })){ + var oldFunc = grid._setStructureAttr; + var isCell = function(def){ + return ("name" in def || "field" in def || "get" in def); + }; + var isView = function(def){ + return (def !== null && lang.isObject(def) && + ("cells" in def || "rows" in def || ("type" in def && !isCell(def)))); + }; + grid._setStructureAttr = function(structure){ + if(!grid._colOrderLoaded){ + grid._colOrderLoaded = true; + grid._setStructureAttr = oldFunc; + structure = lang.clone(structure); + if(lang.isArray(structure) && !array.some(structure, isView)){ + structure = [{ cells: structure }]; + }else if(isView(structure)){ + structure = [structure]; + } + var cells = _getCellsFromStructure(structure); + array.forEach(lang.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){ + var cellArray = viewDef; + if(lang.isArray(viewDef)){ + viewDef.splice(0, viewDef.length); + }else{ + delete viewDef.rows; + cellArray = viewDef.cells = []; + } + array.forEach(colOrder[viewIdx], function(subrow){ + array.forEach(subrow, function(cellInfo){ + var i, cell; + for(i = 0; i < cells.length; ++i){ + cell = cells[i]; + if(json.toJson({'name':cell.name,'field':cell.field}) == json.toJson(cellInfo)){ + break; + } + } + if(i < cells.length){ + cellArray.push(cell); + } + }); + }); + }); + } + oldFunc.call(grid, structure); + }; + } + }; + + var _saveColumnOrder = function(grid){ + var colOrder = array.map(array.filter(grid.views.views, function(view){ + return !(view instanceof _RowSelector); + }), function(view){ + return array.map(view.structure.cells, function(subrow){ + return array.map(array.filter(subrow, function(cell){ + return !(cell.isRowSelector || cell instanceof gridCells.RowIndex); + }), function(cell){ + return { + "name": cell.name, + "field": cell.field + }; + }); + }); + }); + return colOrder; + }; + + // Persist sorting order + var _loadSortOrder = function(sortOrder, grid){ + try{ + if(lang.isObject(sortOrder)){ + grid.setSortIndex(sortOrder.idx, sortOrder.asc); + } + }catch(e){ + //setSortIndex will finally call _fetch, some exceptions will be throw + //'cause the grid hasn't be fully loaded now. Just ignore them. + } + }; + + var _saveSortOrder = function(grid){ + return { + idx: grid.getSortIndex(), + asc: grid.getSortAsc() + }; + }; + + if(!has("ie")){ + // Now in non-IE, widgets are no longer destroyed on page unload, + // so we have to destroy it manually to trigger saving cookie. + unload.addOnWindowUnload(function(){ + array.forEach(dijit.findWidgets(win.body()), function(widget){ + if(widget instanceof EnhancedGrid && !widget._destroyed){ + widget.destroyRecursive(); + } + }); + }); + } + + var Cookie = declare("dojox.grid.enhanced.plugins.Cookie", _Plugin, { + // summary: + // This plugin provides a way to persist some grid features in cookie. + // Default persistable features are: + // column width: "columnWidth" (handler name) + // column order: "columnOrder" + // sorting order: "sortOrder" + // + // Grid users can define new persistable features + // by calling the following before grid is initialized (that is, during "preInit"); + // | grid.addCookieHandler({ + // | name: "a name for the new persistable feature", + // | onLoad: function(savedObject, grid){ + // | //load the cookie. + // | }, + // | onSave: function(grid){ + // | //save the cookie. + // | } + // | }); + + // name: String + // Plugin name + name: "cookie", + + _cookieEnabled: true, + + constructor: function(grid, args){ + this.grid = grid; + args = (args && lang.isObject(args)) ? args : {}; + this.cookieProps = args.cookieProps; + this._cookieHandlers = []; + this._mixinGrid(); + + //Column width & simple sorting & column reorder are base grid features, so they must be supported. + this.addCookieHandler({ + name: "columnWidth", + onLoad: _loadColWidth, + onSave: _saveColWidth + }); + this.addCookieHandler({ + name: "columnOrder", + onLoad: _loadColumnOrder, + onSave: _saveColumnOrder + }); + this.addCookieHandler({ + name: "sortOrder", + onLoad: _loadSortOrder, + onSave: _saveSortOrder + }); + + array.forEach(this._cookieHandlers, function(handler){ + if(args[handler.name] === false){ + handler.enable = false; + } + }, this); + }, + destroy:function(){ + this._saveCookie(); + this._cookieHandlers = null; + this.inherited(arguments); + }, + _mixinGrid: function(){ + var g = this.grid; + g.addCookieHandler = lang.hitch(this, "addCookieHandler"); + g.removeCookie = lang.hitch(this, "removeCookie"); + g.setCookieEnabled = lang.hitch(this, "setCookieEnabled"); + g.getCookieEnabled = lang.hitch(this, "getCookieEnabled"); + }, + _saveCookie: function(){ + if(this.getCookieEnabled()){ + var ck = {}, + chs = this._cookieHandlers, + cookieProps = this.cookieProps, + cookieKey = _cookieKeyBuilder(this.grid); + for(var i = chs.length-1; i >= 0; --i){ + if(chs[i].enabled){ + //Do the real saving work here. + ck[chs[i].name] = chs[i].onSave(this.grid); + } + } + cookieProps = lang.isObject(this.cookieProps) ? this.cookieProps : {}; + cookie(cookieKey, json.toJson(ck), cookieProps); + }else{ + this.removeCookie(); + } + }, + onPreInit: function(){ + var grid = this.grid, + chs = this._cookieHandlers, + cookieKey = _cookieKeyBuilder(grid), + ck = cookie(cookieKey); + if(ck){ + ck = json.fromJson(ck); + for(var i = 0; i < chs.length; ++i){ + if(chs[i].name in ck && chs[i].enabled){ + //Do the real loading work here. + chs[i].onLoad(ck[chs[i].name], grid); + } + } + } + this._cookie = ck || {}; + this._cookieStartedup = true; + }, + addCookieHandler: function(args){ + // summary: + // If a grid plugin wants cookie service, call this. + // This must be called during preInit. + // args: Object + // An object with the following structure: + // | { + // | name: "some-string", + // | onLoad: /* void */ function(/* object */partOfCookie, /* EDG */grid){...}, + // | onSave: /* object */ function(/* EDG */grid){...} + // | } + if(args.name){ + var dummy = function(){}; + args.onLoad = args.onLoad || dummy; + args.onSave = args.onSave || dummy; + if(!("enabled" in args)){ + args.enabled = true; + } + for(var i = this._cookieHandlers.length - 1; i >= 0; --i){ + if(this._cookieHandlers[i].name == args.name){ + this._cookieHandlers.splice(i, 1); + } + } + this._cookieHandlers.push(args); + if(this._cookieStartedup && args.name in this._cookie){ + args.onLoad(this._cookie[args.name], this.grid); + } + } + }, + removeCookie: function(){ + // summary: + // Remove cookie for this grid. + var key = _cookieKeyBuilder(this.grid); + cookie(key, null, {expires: -1}); + }, + setCookieEnabled: function(cookieName, enabled){ + // summary: + // A setter to enable|disable cookie support for a particular Grid feature. + // cookieName: String? + // Name of a cookie handler if provided, otherwise for all cookies. + // enabled: Boolean + if(typeof cookieName == 'string'){ + var chs = this._cookieHandlers; + for(var i = chs.length - 1; i >= 0; --i){ + if(chs[i].name === cookieName){ + chs[i].enabled = !!enabled; + } + } + }else{ + this._cookieEnabled = !!cookieName; + if(!this._cookieEnabled){ this.removeCookie(); } + } + }, + getCookieEnabled: function(cookieName){ + // summary: + // A getter to check cookie support of a particular Grid feature. + // cookieName: String? + // Name of a cookie handler if provided, otherwise for all cookies. + if(lang.isString(cookieName)){ + var chs = this._cookieHandlers; + for(var i = chs.length - 1; i >= 0; --i){ + if(chs[i].name == cookieName){ return chs[i].enabled; } + } + return false; + } + return this._cookieEnabled; + } + }); + + EnhancedGrid.registerPlugin(Cookie, {"preInit": true}); + + return Cookie; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js new file mode 100644 index 0000000..97dbbd4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js @@ -0,0 +1,40 @@ +//>>built +define("dojox/grid/enhanced/plugins/Dialog", [ + "dojo/_base/declare", + "dojo/_base/html", + "dojo/window", + "dijit/Dialog" +], function(declare, html, win, Dialog){ + +return declare("dojox.grid.enhanced.plugins.Dialog", Dialog, { + refNode: null, + _position: function(){ + if(this.refNode && !this._relativePosition){ + var refPos = html.position(html.byId(this.refNode)), + thisPos = html.position(this.domNode), + viewPort = win.getBox(); + if(thisPos.w && thisPos.h){ + if(refPos.x < 0){ + refPos.x = 0; + } + if(refPos.x + refPos.w > viewPort.w){ + refPos.w = viewPort.w - refPos.x; + } + if(refPos.y < 0){ + refPos.y = 0; + } + if(refPos.y + refPos.h > viewPort.h){ + refPos.h = viewPort.h - refPos.y; + } + refPos.x = refPos.x + refPos.w / 2 - thisPos.w / 2; + refPos.y = refPos.y + refPos.h / 2 - thisPos.h / 2; + if(refPos.x >= 0 && refPos.x + thisPos.w <= viewPort.w && + refPos.y >= 0 && refPos.y + thisPos.h <= viewPort.h){ + this._relativePosition = refPos; + } + } + } + this.inherited(arguments); + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js new file mode 100644 index 0000000..e9306ed --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js @@ -0,0 +1,1094 @@ +//>>built +define("dojox/grid/enhanced/plugins/DnD", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/_base/connect", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/html", + "dojo/_base/json", + "dojo/_base/window", + "dojo/query", + "dojo/keys", + "dojo/dnd/Source", + "dojo/dnd/Avatar", + "../_Plugin", + "../../EnhancedGrid", + "./Selector", + "./Rearrange", + "dojo/dnd/Manager" +], function(dojo, declare, connect, array, lang, html, json, win, query, keys, Source, Avatar, _Plugin, EnhancedGrid){ + +var _devideToArrays = function(a){ + a.sort(function(v1, v2){ + return v1 - v2; + }); + var arr = [[a[0]]]; + for(var i = 1, j = 0; i < a.length; ++i){ + if(a[i] == a[i-1] + 1){ + arr[j].push(a[i]); + }else{ + arr[++j] = [a[i]]; + } + } + return arr; + }, + _joinToArray = function(arrays){ + var a = arrays[0]; + for(var i = 1; i < arrays.length; ++i){ + a = a.concat(arrays[i]); + } + return a; + }; +var GridDnDElement = declare("dojox.grid.enhanced.plugins.GridDnDElement", null, { + constructor: function(dndPlugin){ + this.plugin = dndPlugin; + this.node = html.create("div"); + this._items = {}; + }, + destroy: function(){ + this.plugin = null; + html.destroy(this.node); + this.node = null; + this._items = null; + }, + createDnDNodes: function(dndRegion){ + this.destroyDnDNodes(); + var acceptType = ["grid/" + dndRegion.type + "s"]; + var itemNodeIdBase = this.plugin.grid.id + "_dndItem"; + array.forEach(dndRegion.selected, function(range, i){ + var id = itemNodeIdBase + i; + this._items[id] = { + "type": acceptType, + "data": range, + "dndPlugin": this.plugin + }; + this.node.appendChild(html.create("div", { + "id": id + })); + }, this); + }, + getDnDNodes: function(){ + return array.map(this.node.childNodes, function(node){ + return node; + }); + }, + destroyDnDNodes: function(){ + html.empty(this.node); + this._items = {}; + }, + getItem: function(nodeId){ + return this._items[nodeId]; + } +}); +var GridDnDSource = declare("dojox.grid.enhanced.plugins.GridDnDSource", Source,{ + accept: ["grid/cells", "grid/rows", "grid/cols"], + constructor: function(node, param){ + this.grid = param.grid; + this.dndElem = param.dndElem; + this.dndPlugin = param.dnd; + this.sourcePlugin = null; + }, + destroy: function(){ + this.inherited(arguments); + this.grid = null; + this.dndElem = null; + this.dndPlugin = null; + this.sourcePlugin = null; + }, + getItem: function(nodeId){ + return this.dndElem.getItem(nodeId); + }, + checkAcceptance: function(source, nodes){ + if(this != source && nodes[0]){ + var item = source.getItem(nodes[0].id); + if(item.dndPlugin){ + var type = item.type; + for(var j = 0; j < type.length; ++j){ + if(type[j] in this.accept){ + if(this.dndPlugin._canAccept(item.dndPlugin)){ + this.sourcePlugin = item.dndPlugin; + }else{ + return false; + } + break; + } + } + }else if("grid/rows" in this.accept){ + var rows = []; + array.forEach(nodes, function(node){ + var item = source.getItem(node.id); + if(item.data && array.indexOf(item.type, "grid/rows") >= 0){ + var rowData = item.data; + if(typeof item.data == "string"){ + rowData = json.fromJson(item.data); + } + if(rowData){ + rows.push(rowData); + } + } + }); + if(rows.length){ + this.sourcePlugin = { + _dndRegion: { + type: "row", + selected: [rows] + } + }; + }else{ + return false; + } + } + } + return this.inherited(arguments); + }, + onDraggingOver: function(){ + this.dndPlugin.onDraggingOver(this.sourcePlugin); + }, + onDraggingOut: function(){ + this.dndPlugin.onDraggingOut(this.sourcePlugin); + }, + onDndDrop: function(source, nodes, copy, target){ + //this.inherited(arguments); + this.onDndCancel(); + if(this != source && this == target){ + this.dndPlugin.onDragIn(this.sourcePlugin, copy); + } + } +}); + +var GridDnDAvatar = declare("dojox.grid.enhanced.plugins.GridDnDAvatar", Avatar, { + construct: function(){ + // summary: + // constructor function; + // it is separate so it can be (dynamically) overwritten in case of need + this._itemType = this.manager._dndPlugin._dndRegion.type; + this._itemCount = this._getItemCount(); + + this.isA11y = html.hasClass(win.body(), "dijit_a11y"); + var a = html.create("table", { + "border": "0", + "cellspacing": "0", + "class": "dojoxGridDndAvatar", + "style": { + position: "absolute", + zIndex: "1999", + margin: "0px" + } + }), + source = this.manager.source, + b = html.create("tbody", null, a), + tr = html.create("tr", null, b), + td = html.create("td", { + "class": "dojoxGridDnDIcon" + }, tr); + if(this.isA11y){ + html.create("span", { + "id" : "a11yIcon", + "innerHTML" : this.manager.copy ? '+' : "<" + }, td); + } + td = html.create("td", { + "class" : "dojoxGridDnDItemIcon " + this._getGridDnDIconClass() + }, tr); + td = html.create("td", null, tr); + html.create("span", { + "class": "dojoxGridDnDItemCount", + "innerHTML": source.generateText ? this._generateText() : "" + }, td); + // we have to set the opacity on IE only after the node is live + html.style(tr, { + "opacity": 0.9 + }); + this.node = a; + }, + _getItemCount: function(){ + var selected = this.manager._dndPlugin._dndRegion.selected, + count = 0; + switch(this._itemType){ + case "cell": + selected = selected[0]; + var cells = this.manager._dndPlugin.grid.layout.cells, + colCount = selected.max.col - selected.min.col + 1, + rowCount = selected.max.row - selected.min.row + 1; + if(colCount > 1){ + for(var i = selected.min.col; i <= selected.max.col; ++i){ + if(cells[i].hidden){ + --colCount; + } + } + } + count = colCount * rowCount; + break; + case "row": + case "col": + count = _joinToArray(selected).length; + } + return count; + }, + _getGridDnDIconClass: function(){ + return { + "row": ["dojoxGridDnDIconRowSingle", "dojoxGridDnDIconRowMulti"], + "col": ["dojoxGridDnDIconColSingle", "dojoxGridDnDIconColMulti"], + "cell": ["dojoxGridDnDIconCellSingle", "dojoxGridDnDIconCellMulti"] + }[this._itemType][this._itemCount == 1 ? 0 : 1]; + }, + _generateText: function(){ + // summary: + // generates a proper text to reflect copying or moving of items + return "(" + this._itemCount + ")"; + } +}); +var DnD = declare("dojox.grid.enhanced.plugins.DnD", _Plugin, { + // summary: + // Provide drag and drop for grid columns/rows/cells within grid and out of grid. + // The store of grid must implement dojo.data.api.Write. + // DnD selected columns: + // Support moving within grid, moving/copying out of grid to a non-grid DnD target. + // DnD selected rows: + // Support moving within grid, moving/copying out of grid to any DnD target. + // DnD selected cells (in rectangle shape only): + // Support moving/copying within grid, moving/copying out of grid to any DnD target. + // + + // name: String, + // plugin name; + name: "dnd", + + _targetAnchorBorderWidth: 2, + _copyOnly: false, + _config: { + "row":{ + "within":true, + "in":true, + "out":true + }, + "col":{ + "within":true, + "in":true, + "out":true + }, + "cell":{ + "within":true, + "in":true, + "out":true + } + }, + constructor: function(grid, args){ + this.grid = grid; + this._config = lang.clone(this._config); + args = lang.isObject(args) ? args : {}; + this.setupConfig(args.dndConfig); + this._copyOnly = !!args.copyOnly; + + //Get the plugins we are dependent on. + this._mixinGrid(); + this.selector = grid.pluginMgr.getPlugin("selector"); + this.rearranger = grid.pluginMgr.getPlugin("rearrange"); + //TODO: waiting for a better plugin framework to pass args to dependent plugins. + this.rearranger.setArgs(args); + + //Initialized the components we need. + this._clear(); + this._elem = new GridDnDElement(this); + this._source = new GridDnDSource(this._elem.node, { + "grid": grid, + "dndElem": this._elem, + "dnd": this + }); + this._container = query(".dojoxGridMasterView", this.grid.domNode)[0]; + this._initEvents(); + }, + destroy: function(){ + this.inherited(arguments); + this._clear(); + this._source.destroy(); + this._elem.destroy(); + this._container = null; + this.grid = null; + this.selector = null; + this.rearranger = null; + this._config = null; + }, + _mixinGrid: function(){ + // summary: + // Provide APIs for grid. + this.grid.setupDnDConfig = lang.hitch(this, "setupConfig"); + this.grid.dndCopyOnly = lang.hitch(this, "copyOnly"); + }, + setupConfig: function(config){ + // summary: + // Configure which DnD functionalities are needed. + // Combination of any item from type set ("row", "col", "cell") + // and any item from mode set("within", "in", "out") is configurable. + // + // "row", "col", "cell" are straitforward, while the other 3 are explained below: + // "within": DnD within grid, that is, column/row reordering and cell moving/copying. + // "in": Whether allowed to accept rows/cells (currently not support columns) from another grid. + // "out": Whether allowed to drag out of grid, to another grid or even to any other DnD target. + // + // If not provided in the config, will use the default. + // When declared together, Mode set has higher priority than type set. + // config: Object + // DnD configuration object. + // See the examples below. + // example: + // The following code disables row DnD within grid, + // but still can drag rows out of grid or drag rows from other gird. + // | setUpConfig({ + // | "row": { + // | "within": false + // | } + // | }); + // + // The opposite way is also okay: + // | setUpConfig({ + // | "within": { + // | "row": false + // | } + // | }); + // + // And if you'd like to disable/enable a whole set, here's a shortcut: + // | setUpConfig({ + // | "cell", true, + // | "out": false + // | }); + // + // Because mode has higher priority than type, the following will disable row dnd within grid: + // | setUpConfig({ + // | "within", { + // | "row": false; + // | }, + // | "row", { + // | "within": true + // | } + // | }); + if(config && lang.isObject(config)){ + var firstLevel = ["row", "col", "cell"], + secondLevel = ["within", "in", "out"], + cfg = this._config; + array.forEach(firstLevel, function(type){ + if(type in config){ + var t = config[type]; + if(t && lang.isObject(t)){ + array.forEach(secondLevel, function(mode){ + if(mode in t){ + cfg[type][mode] = !!t[mode]; + } + }); + }else{ + array.forEach(secondLevel, function(mode){ + cfg[type][mode] = !!t; + }); + } + } + }); + array.forEach(secondLevel, function(mode){ + if(mode in config){ + var m = config[mode]; + if(m && lang.isObject(m)){ + array.forEach(firstLevel, function(type){ + if(type in m){ + cfg[type][mode] = !!m[type]; + } + }); + }else{ + array.forEach(firstLevel, function(type){ + cfg[type][mode] = !!m; + }); + } + } + }); + } + }, + copyOnly: function(isCopyOnly){ + // summary: + // Setter/getter of this._copyOnly. + if(typeof isCopyOnly != "undefined"){ + this._copyOnly = !!isCopyOnly; + } + return this._copyOnly; + }, + _isOutOfGrid: function(evt){ + var gridPos = html.position(this.grid.domNode), x = evt.clientX, y = evt.clientY; + return y < gridPos.y || y > gridPos.y + gridPos.h || + x < gridPos.x || x > gridPos.x + gridPos.w; + }, + _onMouseMove: function(evt){ + if(this._dndRegion && !this._dnding && !this._externalDnd){ + this._dnding = true; + this._startDnd(evt); + }else{ + if(this._isMouseDown && !this._dndRegion){ + delete this._isMouseDown; + this._oldCursor = html.style(win.body(), "cursor"); + html.style(win.body(), "cursor", "not-allowed"); + } + //TODO: should implement as mouseenter/mouseleave + //But we have an avatar under mouse when dnd, and this will cause a lot of mouseenter in FF. + var isOut = this._isOutOfGrid(evt); + if(!this._alreadyOut && isOut){ + this._alreadyOut = true; + if(this._dnding){ + this._destroyDnDUI(true, false); + } + this._moveEvent = evt; + this._source.onOutEvent(); + }else if(this._alreadyOut && !isOut){ + this._alreadyOut = false; + if(this._dnding){ + this._createDnDUI(evt, true); + } + this._moveEvent = evt; + this._source.onOverEvent(); + } + } + }, + _onMouseUp: function(){ + if(!this._extDnding && !this._isSource){ + var isInner = this._dnding && !this._alreadyOut; + if(isInner && this._config[this._dndRegion.type]["within"]){ + this._rearrange(); + } + this._endDnd(isInner); + } + html.style(win.body(), "cursor", this._oldCursor || ""); + delete this._isMouseDown; + }, + _initEvents: function(){ + var g = this.grid, s = this.selector; + this.connect(win.doc, "onmousemove", "_onMouseMove"); + this.connect(win.doc, "onmouseup", "_onMouseUp"); + + this.connect(g, "onCellMouseOver", function(evt){ + if(!this._dnding && !s.isSelecting() && !evt.ctrlKey){ + this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index); + s.selectEnabled(!this._dndReady); + } + }); + this.connect(g, "onHeaderCellMouseOver", function(evt){ + if(this._dndReady){ + s.selectEnabled(true); + } + }); + this.connect(g, "onRowMouseOver", function(evt){ + if(this._dndReady && !evt.cell){ + s.selectEnabled(true); + } + }); + this.connect(g, "onCellMouseDown", function(evt){ + if(!evt.ctrlKey && this._dndReady){ + this._dndRegion = this._getDnDRegion(evt.rowIndex, evt.cell.index); + this._isMouseDown = true; + } + }); + this.connect(g, "onCellMouseUp", function(evt){ + if(!this._dndReady && !s.isSelecting() && evt.cell){ + this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index); + s.selectEnabled(!this._dndReady); + } + }); + this.connect(g, "onCellClick", function(evt){ + if(this._dndReady && !evt.ctrlKey && !evt.shiftKey){ + s.select("cell", evt.rowIndex, evt.cell.index); + } + }); + this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target, evt){ + if(this._dnding){ + this._markTargetAnchor(evt); + } + }); + this.connect(win.doc, "onkeydown", function(evt){ + if(evt.keyCode == keys.ESCAPE){ + this._endDnd(false); + }else if(evt.keyCode == keys.CTRL){ + s.selectEnabled(true); + this._isCopy = true; + } + }); + this.connect(win.doc, "onkeyup", function(evt){ + if(evt.keyCode == keys.CTRL){ + s.selectEnabled(!this._dndReady); + this._isCopy = false; + } + }); + }, + _clear: function(){ + this._dndRegion = null; + this._target = null; + this._moveEvent = null; + this._targetAnchor = {}; + this._dnding = false; + this._externalDnd = false; + this._isSource = false; + this._alreadyOut = false; + this._extDnding = false; + }, + _getDnDRegion: function(rowIndex, colIndex){ + var s = this.selector, + selected = s._selected, + flag = (!!selected.cell.length) | (!!selected.row.length << 1) | (!!selected.col.length << 2), + type; + switch(flag){ + case 1: + type = "cell"; + if(!this._config[type]["within"] && !this._config[type]["out"]){ + return null; + } + var cells = this.grid.layout.cells, + getCount = function(range){ + var hiddenColCnt = 0; + for(var i = range.min.col; i <= range.max.col; ++i){ + if(cells[i].hidden){ + ++hiddenColCnt; + } + } + return (range.max.row - range.min.row + 1) * (range.max.col - range.min.col + 1 - hiddenColCnt); + }, + inRange = function(item, range){ + return item.row >= range.min.row && item.row <= range.max.row && + item.col >= range.min.col && item.col <= range.max.col; + }, + range = { + max: { + row: -1, + col: -1 + }, + min: { + row: Infinity, + col: Infinity + } + }; + + array.forEach(selected[type], function(item){ + if(item.row < range.min.row){ + range.min.row = item.row; + } + if(item.row > range.max.row){ + range.max.row = item.row; + } + if(item.col < range.min.col){ + range.min.col = item.col; + } + if(item.col > range.max.col){ + range.max.col = item.col; + } + }); + if(array.some(selected[type], function(item){ + return item.row == rowIndex && item.col == colIndex; + })){ + if(getCount(range) == selected[type].length && array.every(selected[type], function(item){ + return inRange(item, range); + })){ + return { + "type": type, + "selected": [range], + "handle": { + "row": rowIndex, + "col": colIndex + } + }; + } + } + return null; + case 2: case 4: + type = flag == 2 ? "row" : "col"; + if(!this._config[type]["within"] && !this._config[type]["out"]){ + return null; + } + var res = s.getSelected(type); + if(res.length){ + return { + "type": type, + "selected": _devideToArrays(res), + "handle": flag == 2 ? rowIndex : colIndex + }; + } + return null; + } + return null; + }, + _startDnd: function(evt){ + this._createDnDUI(evt); + }, + _endDnd: function(destroySource){ + this._destroyDnDUI(false, destroySource); + this._clear(); + }, + _createDnDUI: function(evt, isMovingIn){ + //By default the master view of grid do not have height, because the children in it are all positioned absolutely. + //But we need it to contain avatars. + var viewPos = html.position(this.grid.views.views[0].domNode); + html.style(this._container, "height", viewPos.h + "px"); + try{ + //If moving in from out side, dnd source is already created. + if(!isMovingIn){ + this._createSource(evt); + } + this._createMoveable(evt); + this._oldCursor = html.style(win.body(), "cursor"); + html.style(win.body(), "cursor", "default"); + }catch(e){ + console.warn("DnD._createDnDUI() error:", e); + } + }, + _destroyDnDUI: function(isMovingOut, destroySource){ + try{ + if(destroySource){ + this._destroySource(); + } + this._unmarkTargetAnchor(); + if(!isMovingOut){ + this._destroyMoveable(); + } + html.style(win.body(), "cursor", this._oldCursor); + }catch(e){ + console.warn("DnD._destroyDnDUI() error:", this.grid.id, e); + } + }, + _createSource: function(evt){ + this._elem.createDnDNodes(this._dndRegion); + var m = dojo.dnd.manager(); + var oldMakeAvatar = m.makeAvatar; + m._dndPlugin = this; + m.makeAvatar = function(){ + var avatar = new GridDnDAvatar(m); + delete m._dndPlugin; + return avatar; + }; + m.startDrag(this._source, this._elem.getDnDNodes(), evt.ctrlKey); + m.makeAvatar = oldMakeAvatar; + m.onMouseMove(evt); + }, + _destroySource: function(){ + connect.publish("/dnd/cancel"); + }, + _createMoveable: function(evt){ + if(!this._markTagetAnchorHandler){ + this._markTagetAnchorHandler = this.connect(win.doc, "onmousemove", "_markTargetAnchor"); + } + }, + _destroyMoveable: function(){ + this.disconnect(this._markTagetAnchorHandler); + delete this._markTagetAnchorHandler; + }, + _calcColTargetAnchorPos: function(evt, containerPos){ + // summary: + // Calculate the position of the column DnD avatar + var i, headPos, left, target, ex = evt.clientX, + cells = this.grid.layout.cells, + ltr = html._isBodyLtr(), + headers = this._getVisibleHeaders(); + for(i = 0; i < headers.length; ++i){ + headPos = html.position(headers[i].node); + if(ltr ? ((i === 0 || ex >= headPos.x) && ex < headPos.x + headPos.w) : + ((i === 0 || ex < headPos.x + headPos.w) && ex >= headPos.x)){ + left = headPos.x + (ltr ? 0 : headPos.w); + break; + }else if(ltr ? (i === headers.length - 1 && ex >= headPos.x + headPos.w) : + (i === headers.length - 1 && ex < headPos.x)){ + ++i; + left = headPos.x + (ltr ? headPos.w : 0); + break; + } + } + if(i < headers.length){ + target = headers[i].cell.index; + if(this.selector.isSelected("col", target) && this.selector.isSelected("col", target - 1)){ + var ranges = this._dndRegion.selected; + for(i = 0; i < ranges.length; ++i){ + if(array.indexOf(ranges[i], target) >= 0){ + target = ranges[i][0]; + headPos = html.position(cells[target].getHeaderNode()); + left = headPos.x + (ltr ? 0 : headPos.w); + break; + } + } + } + }else{ + target = cells.length; + } + this._target = target; + return left - containerPos.x; + }, + _calcRowTargetAnchorPos: function(evt, containerPos){ + // summary: + // Calculate the position of the row DnD avatar + var g = this.grid, top, i = 0, + cells = g.layout.cells; + while(cells[i].hidden){ ++i; } + var cell = g.layout.cells[i], + rowIndex = g.scroller.firstVisibleRow, + cellNode = cell.getNode(rowIndex); + if(!cellNode){ + //if the target grid is empty, set to -1 + //which will be processed in Rearrange + this._target = -1; + return 0; //position of the insert bar + } + var nodePos = html.position(cellNode); + while(nodePos.y + nodePos.h < evt.clientY){ + if(++rowIndex >= g.rowCount){ + break; + } + nodePos = html.position(cell.getNode(rowIndex)); + } + if(rowIndex < g.rowCount){ + if(this.selector.isSelected("row", rowIndex) && this.selector.isSelected("row", rowIndex - 1)){ + var ranges = this._dndRegion.selected; + for(i = 0; i < ranges.length; ++i){ + if(array.indexOf(ranges[i], rowIndex) >= 0){ + rowIndex = ranges[i][0]; + nodePos = html.position(cell.getNode(rowIndex)); + break; + } + } + } + top = nodePos.y; + }else{ + top = nodePos.y + nodePos.h; + } + this._target = rowIndex; + return top - containerPos.y; + }, + _calcCellTargetAnchorPos: function(evt, containerPos, targetAnchor){ + // summary: + // Calculate the position of the cell DnD avatar + var s = this._dndRegion.selected[0], + origin = this._dndRegion.handle, + g = this.grid, ltr = html._isBodyLtr(), + cells = g.layout.cells, headPos, + minPos, maxPos, headers, + height, width, left, top, + minCol, maxCol, i, + preSpan = origin.col - s.min.col, + postSpan = s.max.col - origin.col, + leftTopDiv, rightBottomDiv; + if(!targetAnchor.childNodes.length){ + leftTopDiv = html.create("div", { + "class": "dojoxGridCellBorderLeftTopDIV" + }, targetAnchor); + rightBottomDiv = html.create("div", { + "class": "dojoxGridCellBorderRightBottomDIV" + }, targetAnchor); + }else{ + leftTopDiv = query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0]; + rightBottomDiv = query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0]; + } + for(i = s.min.col + 1; i < origin.col; ++i){ + if(cells[i].hidden){ + --preSpan; + } + } + for(i = origin.col + 1; i < s.max.col; ++i){ + if(cells[i].hidden){ + --postSpan; + } + } + headers = this._getVisibleHeaders(); + //calc width + for(i = preSpan; i < headers.length - postSpan; ++i){ + headPos = html.position(headers[i].node); + if((evt.clientX >= headPos.x && evt.clientX < headPos.x + headPos.w) || //within in this column + //prior to this column, but within range + (i == preSpan && (ltr ? evt.clientX < headPos.x : evt.clientX >= headPos.x + headPos.w)) || + //post to this column, but within range + (i == headers.length - postSpan - 1 && (ltr ? evt.clientX >= headPos.x + headPos.w : evt < headPos.x))){ + minCol = headers[i - preSpan]; + maxCol = headers[i + postSpan]; + minPos = html.position(minCol.node); + maxPos = html.position(maxCol.node); + minCol = minCol.cell.index; + maxCol = maxCol.cell.index; + left = ltr ? minPos.x : maxPos.x; + width = ltr ? (maxPos.x + maxPos.w - minPos.x) : (minPos.x + minPos.w - maxPos.x); + break; + } + } + //calc height + i = 0; + while(cells[i].hidden){ ++i; } + var cell = cells[i], + rowIndex = g.scroller.firstVisibleRow, + nodePos = html.position(cell.getNode(rowIndex)); + while(nodePos.y + nodePos.h < evt.clientY){ + if(++rowIndex < g.rowCount){ + nodePos = html.position(cell.getNode(rowIndex)); + }else{ + break; + } + } + var minRow = rowIndex >= origin.row - s.min.row ? rowIndex - origin.row + s.min.row : 0; + var maxRow = minRow + s.max.row - s.min.row; + if(maxRow >= g.rowCount){ + maxRow = g.rowCount - 1; + minRow = maxRow - s.max.row + s.min.row; + } + minPos = html.position(cell.getNode(minRow)); + maxPos = html.position(cell.getNode(maxRow)); + top = minPos.y; + height = maxPos.y + maxPos.h - minPos.y; + this._target = { + "min":{ + "row": minRow, + "col": minCol + }, + "max":{ + "row": maxRow, + "col": maxCol + } + }; + var anchorBorderSize = (html.marginBox(leftTopDiv).w - html.contentBox(leftTopDiv).w) / 2; + var leftTopCellPos = html.position(cells[minCol].getNode(minRow)); + html.style(leftTopDiv, { + "width": (leftTopCellPos.w - anchorBorderSize) + "px", + "height": (leftTopCellPos.h - anchorBorderSize) + "px" + }); + var rightBottomCellPos = html.position(cells[maxCol].getNode(maxRow)); + html.style(rightBottomDiv, { + "width": (rightBottomCellPos.w - anchorBorderSize) + "px", + "height": (rightBottomCellPos.h - anchorBorderSize) + "px" + }); + return { + h: height, + w: width, + l: left - containerPos.x, + t: top - containerPos.y + }; + }, + _markTargetAnchor: function(evt){ + try{ + var t = this._dndRegion.type; + if(this._alreadyOut || (this._dnding && !this._config[t]["within"]) || (this._extDnding && !this._config[t]["in"])){ + return; + } + var height, width, left, top, + targetAnchor = this._targetAnchor[t], + pos = html.position(this._container); + if(!targetAnchor){ + targetAnchor = this._targetAnchor[t] = html.create("div", { + "class": (t == "cell") ? "dojoxGridCellBorderDIV" : "dojoxGridBorderDIV" + }); + html.style(targetAnchor, "display", "none"); + this._container.appendChild(targetAnchor); + } + switch(t){ + case "col": + height = pos.h; + width = this._targetAnchorBorderWidth; + left = this._calcColTargetAnchorPos(evt, pos); + top = 0; + break; + case "row": + height = this._targetAnchorBorderWidth; + width = pos.w; + left = 0; + top = this._calcRowTargetAnchorPos(evt, pos); + break; + case "cell": + var cellPos = this._calcCellTargetAnchorPos(evt, pos, targetAnchor); + height = cellPos.h; + width = cellPos.w; + left = cellPos.l; + top = cellPos.t; + } + if(typeof height == "number" && typeof width == "number" && typeof left == "number" && typeof top == "number"){ + html.style(targetAnchor, { + "height": height + "px", + "width": width + "px", + "left": left + "px", + "top": top + "px" + }); + html.style(targetAnchor, "display", ""); + }else{ + this._target = null; + } + }catch(e){ + console.warn("DnD._markTargetAnchor() error:",e); + } + }, + _unmarkTargetAnchor: function(){ + if(this._dndRegion){ + var targetAnchor = this._targetAnchor[this._dndRegion.type]; + if(targetAnchor){ + html.style(this._targetAnchor[this._dndRegion.type], "display", "none"); + } + } + }, + _getVisibleHeaders: function(){ + return array.map(array.filter(this.grid.layout.cells, function(cell){ + return !cell.hidden; + }), function(cell){ + return { + "node": cell.getHeaderNode(), + "cell": cell + }; + }); + }, + _rearrange: function(){ + if(this._target === null){ + return; + } + var t = this._dndRegion.type; + var ranges = this._dndRegion.selected; + if(t === "cell"){ + this.rearranger[(this._isCopy || this._copyOnly) ? "copyCells" : "moveCells"](ranges[0], this._target === -1 ? null : this._target); + }else{ + this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target === -1 ? null: this._target); + } + this._target = null; + }, + onDraggingOver: function(sourcePlugin){ + if(!this._dnding && sourcePlugin){ + sourcePlugin._isSource = true; + this._extDnding = true; + if(!this._externalDnd){ + this._externalDnd = true; + this._dndRegion = this._mapRegion(sourcePlugin.grid, sourcePlugin._dndRegion); + } + this._createDnDUI(this._moveEvent,true); + this.grid.pluginMgr.getPlugin("autoScroll").readyForAutoScroll = true; + } + }, + _mapRegion: function(srcGrid, dndRegion){ + if(dndRegion.type === "cell"){ + var srcRange = dndRegion.selected[0]; + var cells = this.grid.layout.cells; + var srcCells = srcGrid.layout.cells; + var c, cnt = 0; + for(c = srcRange.min.col; c <= srcRange.max.col; ++c){ + if(!srcCells[c].hidden){ + ++cnt; + } + } + for(c = 0; cnt > 0; ++c){ + if(!cells[c].hidden){ + --cnt; + } + } + var region = lang.clone(dndRegion); + region.selected[0].min.col = 0; + region.selected[0].max.col = c - 1; + for(c = srcRange.min.col; c <= dndRegion.handle.col; ++c){ + if(!srcCells[c].hidden){ + ++cnt; + } + } + for(c = 0; cnt > 0; ++c){ + if(!cells[c].hidden){ + --cnt; + } + } + region.handle.col = c; + } + return dndRegion; + }, + onDraggingOut: function(sourcePlugin){ + if(this._externalDnd){ + this._extDnding = false; + this._destroyDnDUI(true, false); + if(sourcePlugin){ + sourcePlugin._isSource = false; + } + } + }, + onDragIn: function(sourcePlugin, isCopy){ + var success = false; + if(this._target !== null){ + var type = sourcePlugin._dndRegion.type; + var ranges = sourcePlugin._dndRegion.selected; + switch(type){ + case "cell": + this.rearranger.changeCells(sourcePlugin.grid, ranges[0], this._target); + break; + case "row": + var range = _joinToArray(ranges); + this.rearranger.insertRows(sourcePlugin.grid, range, this._target); + break; + } + success = true; + } + this._endDnd(true); + if(sourcePlugin.onDragOut){ + sourcePlugin.onDragOut(success && !isCopy); + } + }, + onDragOut: function(isMove){ + if(isMove && !this._copyOnly){ + var type = this._dndRegion.type; + var ranges = this._dndRegion.selected; + switch(type){ + case "cell": + this.rearranger.clearCells(ranges[0]); + break; + case "row": + this.rearranger.removeRows(_joinToArray(ranges)); + break; + } + } + this._endDnd(true); + }, + _canAccept: function(sourcePlugin){ + if(!sourcePlugin){ + return false; + } + var srcRegion = sourcePlugin._dndRegion; + var type = srcRegion.type; + if(!this._config[type]["in"] || !sourcePlugin._config[type]["out"]){ + return false; + } + var g = this.grid; + var ranges = srcRegion.selected; + var colCnt = array.filter(g.layout.cells, function(cell){ + return !cell.hidden; + }).length; + var rowCnt = g.rowCount; + var res = true; + switch(type){ + case "cell": + ranges = ranges[0]; + res = g.store.getFeatures()["dojo.data.api.Write"] && + (ranges.max.row - ranges.min.row) <= rowCnt && + array.filter(sourcePlugin.grid.layout.cells, function(cell){ + return cell.index >= ranges.min.col && cell.index <= ranges.max.col && !cell.hidden; + }).length <= colCnt; + //intentional drop through - don't break + case "row": + if(sourcePlugin._allDnDItemsLoaded()){ + return res; + } + } + return false; + }, + _allDnDItemsLoaded: function(){ + if(this._dndRegion){ + var type = this._dndRegion.type, + ranges = this._dndRegion.selected, + rows = []; + switch(type){ + case "cell": + for(var i = ranges[0].min.row, max = ranges[0].max.row; i <= max; ++i){ + rows.push(i); + } + break; + case "row": + rows = _joinToArray(ranges); + break; + default: + return false; + } + var cache = this.grid._by_idx; + return array.every(rows, function(rowIndex){ + return !!cache[rowIndex]; + }); + } + return false; + } +}); + +EnhancedGrid.registerPlugin(DnD/*name:'dnd'*/, { + "dependency": ["selector", "rearrange"] +}); + +return DnD; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js new file mode 100644 index 0000000..fe12206 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js @@ -0,0 +1,243 @@ +//>>built +define("dojox/grid/enhanced/plugins/Exporter", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "../_Plugin", + "../../_RowSelector", + "../../EnhancedGrid", + "../../cells/_base" +], function(declare, array, lang, _Plugin, _RowSelector, EnhancedGrid){ + +var gridCells = lang.getObject("dojox.grid.cells"); + +var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, { + // summary: + // Provide functions to export the grid data into a given format. + // + // Acceptable plugin parameters: + // 1. exportFormatter: function(data, cell, rowIndex, item) + // Provide a way to customize how data should look in exported string. + // Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget). + // example: + // | function onExported(exported_text){ + // | //custom code here... + // | } + // | dijit.byId("my_grid_id").exportTo("csv", //registered export format, mandatory + // | { //the whole object is optional. + // | fetchArgs: {start:0,count:1000}, //keywordArgs for fetch, optional + // | writerArgs: {separator:';'}, //export writer specific arguments, optional + // | }, + // | function(str){ + // | //call back function, mandatory + // | }); + // | var result = dijit.byId("my_grid_id").exportSelectedTo("table", //registered export format, mandatory + // | {separator:'|'} //export writer specific arguments, optional + // | ); + // + + // name: String + // Plugin name. + name: "exporter", + + constructor: function(grid, args){ + // summary: + // only newed by _Plugin + // grid: EnhancedGrid + // The grid to plug in to. + this.grid = grid; + this.formatter = (args && lang.isObject(args)) && args.exportFormatter; + this._mixinGrid(); + }, + _mixinGrid: function(){ + var g = this.grid; + g.exportTo = lang.hitch(this, this.exportTo); + g.exportGrid = lang.hitch(this, this.exportGrid); + g.exportSelected = lang.hitch(this, this.exportSelected); + g.setExportFormatter = lang.hitch(this, this.setExportFormatter); + }, + setExportFormatter: function(formatter){ + this.formatter = formatter; + }, + exportGrid: function(type, args, onExported){ + // summary: + // Export required rows(fetchArgs) to a kind of format(type) + // using the corresponding writer with given arguments(writerArgs), + // then pass the exported text to a given function(onExported). + // tags: + // public + // type: string + // A registered export format name + // args: object? + // includes: + // { + // fetchArgs: object? + // Any arguments for store.fetch + // writerArgs: object? + // Arguments for the given format writer + // } + // onExported: function(string) + // Call back function when export result is ready + if(lang.isFunction(args)){ + onExported = args; + args = {}; + } + if(!lang.isString(type) || !lang.isFunction(onExported)){ + return; + } + args = args || {}; + var g = this.grid, _this = this, + writer = this._getExportWriter(type, args.writerArgs), + fetchArgs = (args.fetchArgs && lang.isObject(args.fetchArgs)) ? args.fetchArgs : {}, + oldFunc = fetchArgs.onComplete; + if(g.store){ + fetchArgs.onComplete = function(items, request){ + if(oldFunc){ + oldFunc(items, request); + } + onExported(_this._goThroughGridData(items, writer)); + }; + fetchArgs.sort = fetchArgs.sort || g.getSortProps(); + g._storeLayerFetch(fetchArgs); + }else{ + //Data is defined directly in the structure; + var start = fetchArgs.start || 0, + count = fetchArgs.count || -1, + items = []; + for(var i = start; i != start + count && i < g.rowCount; ++i){ + items.push(g.getItem(i)); + } + onExported(this._goThroughGridData(items, writer)); + } + }, + exportSelected: function(type, writerArgs){ + // summary: + // Only export selected rows. + // tags: + // public + // type: string + // A registered export format name + // writerArgs: object? + // Arguments for the given format writer + // returns: string + // The exported string + if(!lang.isString(type)){ + return ""; + } + var writer = this._getExportWriter(type, writerArgs); + return this._goThroughGridData(this.grid.selection.getSelected(), writer); //String + }, + _buildRow: function(/* object */arg_obj,/* ExportWriter */writer){ + // summary: + // Use the given export writer(writer) to go through a single row + // which is given in the context object(arg_obj). + // tags: + // private + // returns: + // undefined + var _this = this; + array.forEach(arg_obj._views, function(view, vIdx){ + arg_obj.view = view; + arg_obj.viewIdx = vIdx; + if(writer.beforeView(arg_obj)){ + array.forEach(view.structure.cells, function(subrow, srIdx){ + arg_obj.subrow = subrow; + arg_obj.subrowIdx = srIdx; + if(writer.beforeSubrow(arg_obj)){ + array.forEach(subrow, function(cell, cIdx){ + if(arg_obj.isHeader && _this._isSpecialCol(cell)){ + arg_obj.spCols.push(cell.index); + } + arg_obj.cell = cell; + arg_obj.cellIdx = cIdx; + writer.handleCell(arg_obj); + }); + writer.afterSubrow(arg_obj); + } + }); + writer.afterView(arg_obj); + } + }); + }, + _goThroughGridData: function(/* Array */items,/* ExportWriter */writer){ + // summary: + // Use the given export writer(writer) to go through the grid structure + // and the given rows(items), then return the writer output. + // tags: + // private + var grid = this.grid, + views = array.filter(grid.views.views, function(view){ + return !(view instanceof _RowSelector); + }), + arg_obj = { + 'grid': grid, + 'isHeader': true, + 'spCols': [], + '_views': views, + 'colOffset': (views.length < grid.views.views.length ? -1 : 0) + }; + //go through header + if(writer.beforeHeader(grid)){ + this._buildRow(arg_obj,writer); + writer.afterHeader(); + } + //go through content + arg_obj.isHeader = false; + if(writer.beforeContent(items)){ + array.forEach(items, function(item, rIdx){ + arg_obj.row = item; + arg_obj.rowIdx = rIdx; + if(writer.beforeContentRow(arg_obj)){ + this._buildRow(arg_obj, writer); + writer.afterContentRow(arg_obj); + } + }, this); + writer.afterContent(); + } + return writer.toString(); + }, + _isSpecialCol: function(/* dojox.grid.__CellDef */header_cell){ + // summary: + // Row selectors and row indexes should be recognized and handled separately. + // tags: + // private + return header_cell.isRowSelector || header_cell instanceof gridCells.RowIndex; //Boolean + }, + _getExportWriter: function(/* string */ fileType, /* object? */ writerArgs){ + // summary: + // Use the given export format type(fileType) + // and writer arguments(writerArgs) to create + // a ExportWriter and return it. + // tags: + // private + var writerName, cls, + expCls = Exporter; + if(expCls.writerNames){ + writerName = expCls.writerNames[fileType.toLowerCase()]; + cls = lang.getObject(writerName); + if(cls){ + var writer = new cls(writerArgs); + writer.formatter = this.formatter; + return writer; //ExportWriter + }else{ + throw new Error('Please make sure class "' + writerName + '" is required.'); + } + } + throw new Error('The writer for "' + fileType + '" has not been registered.'); + } +}); + +Exporter.registerWriter = function(/* string */fileType,/* string */writerClsName){ + // summary: + // Register a writer(writerClsName) to a export format type(fileType). + // This function separates the Exporter from all kinds of writers. + // tags: + // public + Exporter.writerNames = Exporter.writerNames || {}; + Exporter.writerNames[fileType] = writerClsName; +}; + +EnhancedGrid.registerPlugin(Exporter/*name:'exporter'*/); + +return Exporter; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js new file mode 100644 index 0000000..a68a00f --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js @@ -0,0 +1,173 @@ +//>>built +define("dojox/grid/enhanced/plugins/Filter", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/i18n", + "../_Plugin", + "./Dialog", + "./filter/FilterLayer", + "./filter/FilterBar", + "./filter/FilterDefDialog", + "./filter/FilterStatusTip", + "./filter/ClearFilterConfirm", + "../../EnhancedGrid", + "dojo/i18n!../nls/Filter" +], function(declare, lang, i18n, _Plugin, Dialog, layers, FilterBar, FilterDefDialog, FilterStatusTip, ClearFilterConfirm, EnhancedGrid){ + + var Filter = declare("dojox.grid.enhanced.plugins.Filter", _Plugin, { + // summary: + // Provide filter functionality for grid. + // + // Acceptable plugin parameters: + // 1. itemsName: string + // the name shown on the filter bar. + // 2. statusTipTimeout: number + // when does the status tip show. + // 3. ruleCount: number + // default to 3, should not change to more. The Claro theme limits it. + // 4. disabledConditions: object + // If you don't need all of the conditions provided for a data type, + // you can explicitly declare them here: + // e.g.: disabledConditions: {string: ["contains", "is"], number: ["equalto"], ...} + // 5. isServerSide: boolean + // Whether to use server side filtering. Default to false. + // 6. isStateful: boolean + // If isServerSide is true, set the server side filter to be stateful or not. default to false. + // 7. url: string + // If using stateful, this is the url to send commands. default to store.url. + // 8. ruleCountToConfirmClearFilter: Integer | null |Infinity + // If the filter rule count is larger than or equal to this value, then a confirm dialog will show when clearing filter. + // If set to less than 1 or null, then always show the confirm dialog. + // If set to Infinity, then never show the confirm dialog. + // Default value is 2. + // + // Acceptable cell parameters defined in layout: + // 1. filterable: boolean + // The column is not filterable only when this is set to false explicitly. + // 2. datatype: string + // The data type of this column. Can be "string", "number", "date", "time", "boolean". + // Default to "string". + // 3. autoComplete: boolean + // If need auto-complete in the ComboBox for String type, set this to true. + // 4. dataTypeArgs: object + // Some arguments helping convert store data to something the filter UI understands. + // Different data type arguments can be provided to different data types. + // For date/time, this is a dojo.date.locale.__FormatOptions, so the DataTimeBox can understand the store data. + // For boolean, this object contains: + // trueLabel: string + // A label to display in the filter definition dialog for true value. Default to "True". + // falseLable: string + // A label to display in the filter definition dialog for false value. Default to "False". + // 5. disabledConditions: object + // If you don't need all of the conditions provided by the filter UI on this column, you can explicitly say it out here. + // e.g.: disabledConditions: ["contains", "is"] + // This will disable the "contains" condition for this column, if this column is of string type. + // For full set of conditions, please refer to dojox.grid.enhanced.plugins.filter.FilterDefDialog._setupData. + // example: + // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: true}" ...></div> + // | or provide some parameters: + // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: {itemsName: 'songs'}}" ...></div> + // | Customize columns for filter: + // | var layout = [ + // | ... + // | //define a column to be un-filterable in layout/structure + // | {field: "Genre", filterable: false, ...} + // | //define a column of type string and supports autoComplete when you type in filter conditions. + // | {field: "Writer", datatype: "string", autoCommplete: true, ...} + // | //define a column of type date and the data in store has format: "yyyy/M/d" + // | {field: "Publish Date", datatype: "date", dataTypeArgs: {datePattern: "yyyy/M/d"}, ...} + // | //disable some conditions for a column + // | {field: "Track", disabledConditions: ["equalto","notequalto"], ...} + // | ... + // | ]; + + // name: String + // plugin name + name: "filter", + + constructor: function(grid, args){ + // summary: + // See constructor of dojox.grid.enhanced._Plugin. + this.grid = grid; + this.nls = i18n.getLocalization("dojox.grid.enhanced", "Filter"); + + args = this.args = lang.isObject(args) ? args : {}; + if(typeof args.ruleCount != 'number' || args.ruleCount < 0){ + args.ruleCount = 3; + } + var rc = this.ruleCountToConfirmClearFilter = args.ruleCountToConfirmClearFilter; + if(rc === undefined){ + this.ruleCountToConfirmClearFilter = 2; + } + + //Install filter layer + this._wrapStore(); + + //Install UI components + var obj = { "plugin": this }; + this.clearFilterDialog = new Dialog({ + refNode: this.grid.domNode, + title: this.nls["clearFilterDialogTitle"], + content: new ClearFilterConfirm(obj) + }); + this.filterDefDialog = new FilterDefDialog(obj); + this.filterBar = new FilterBar(obj); + this.filterStatusTip = new FilterStatusTip(obj); + + //Expose the layer event to grid. + grid.onFilterDefined = function(){}; + this.connect(grid.layer("filter"), "onFilterDefined", function(filter){ + grid.onFilterDefined(grid.getFilter(), grid.getFilterRelation()); + }); + }, + destroy: function(){ + this.inherited(arguments); + try{ + this.grid.unwrap("filter"); + this.filterBar.destroyRecursive(); + this.filterBar = null; + this.clearFilterDialog.destroyRecursive(); + this.clearFilterDialog = null; + this.filterStatusTip.destroy(); + this.filterStatusTip = null; + this.filterDefDialog.destroy(); + this.filterDefDialog = null; + this.grid = null; + this.nls = null; + this.args = null; + }catch(e){ + console.warn("Filter.destroy() error:",e); + } + }, + _wrapStore: function(){ + var g = this.grid; + var args = this.args; + var filterLayer = args.isServerSide ? new layers.ServerSideFilterLayer(args) : + new layers.ClientSideFilterLayer({ + cacheSize: args.filterCacheSize, + fetchAll: args.fetchAllOnFirstFilter, + getter: this._clientFilterGetter + }); + layers.wrap(g, "_storeLayerFetch", filterLayer); + + this.connect(g, "_onDelete", lang.hitch(filterLayer, "invalidate")); + }, + onSetStore: function(store){ + this.filterDefDialog.clearFilter(true); + }, + _clientFilterGetter: function(/* data item */ datarow,/* cell */cell, /* int */rowIndex){ + // summary: + // Define the grid-specific way to get data from a row. + // Argument "cell" is provided by FilterDefDialog when defining filter expressions. + // Argument "rowIndex" is provided by FilterLayer when checking a row. + // FilterLayer also provides a forth argument: "store", which is grid.store, + // but we don't need it here. + return cell.get(rowIndex, datarow); + } + }); + + EnhancedGrid.registerPlugin(Filter/*name:'filter'*/); + + return Filter; + +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js new file mode 100644 index 0000000..18c393c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js @@ -0,0 +1,155 @@ +//>>built +define("dojox/grid/enhanced/plugins/GridSource", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/dnd/Source", + "./DnD" +], function(declare, array, lang, Source, DnD){ + +var _joinToArray = function(arrays){ + var a = arrays[0]; + for(var i = 1; i < arrays.length; ++i){ + a = a.concat(arrays[i]); + } + return a; +}; + +var GridDnDSource = lang.getObject("dojox.grid.enhanced.plugins.GridDnDSource"); + +return declare("dojox.grid.enhanced.plugins.GridSource", Source, { + // summary: + // A special source that can accept grid contents. + // Only for non-grid widgets or domNodes. + accept: ["grid/cells", "grid/rows", "grid/cols", "text"], + + // insertNodesForGrid: + // If you'd like to insert some sort of nodes into your dnd source, turn this on, + // and override getCellContent/getRowContent/getColumnContent + // to populate the dnd data in your desired format. + insertNodesForGrid: false, + + markupFactory: function(params, node){ + cls = lang.getObject("dojox.grid.enhanced.plugins.GridSource"); + return new cls(node, params); + }, + checkAcceptance: function(source, nodes){ + if(source instanceof GridDnDSource){ + if(nodes[0]){ + var item = source.getItem(nodes[0].id); + if(item && (array.indexOf(item.type, "grid/rows") >= 0 || array.indexOf(item.type, "grid/cells") >= 0) && + !source.dndPlugin._allDnDItemsLoaded()){ + return false; + } + } + this.sourcePlugin = source.dndPlugin; + } + return this.inherited(arguments); + }, + onDraggingOver: function(){ + if(this.sourcePlugin){ + this.sourcePlugin._isSource = true; + } + }, + onDraggingOut: function(){ + if(this.sourcePlugin){ + this.sourcePlugin._isSource = false; + } + }, + onDropExternal: function(source, nodes, copy){ + if(source instanceof GridDnDSource){ + var ranges = array.map(nodes, function(node){ + return source.getItem(node.id).data; + }); + var item = source.getItem(nodes[0].id); + var grid = item.dndPlugin.grid; + var type = item.type[0]; + var range; + try{ + switch(type){ + case "grid/cells": + nodes[0].innerHTML = this.getCellContent(grid, ranges[0].min, ranges[0].max) || ""; + this.onDropGridCells(grid, ranges[0].min, ranges[0].max); + break; + case "grid/rows": + range = _joinToArray(ranges); + nodes[0].innerHTML = this.getRowContent(grid, range) || ""; + this.onDropGridRows(grid, range); + break; + case "grid/cols": + range = _joinToArray(ranges); + nodes[0].innerHTML = this.getColumnContent(grid, range) || ""; + this.onDropGridColumns(grid, range); + break; + } + if(this.insertNodesForGrid){ + this.selectNone(); + this.insertNodes(true, [nodes[0]], this.before, this.current); + } + item.dndPlugin.onDragOut(!copy); + }catch(e){ + console.warn("GridSource.onDropExternal() error:",e); + } + }else{ + this.inherited(arguments); + } + }, + getCellContent: function(grid, leftTopCell, rightBottomCell){ + // summary: + // Fill node innerHTML for dnd grid cells. + // sample code: + // var cells = grid.layout.cells; + // var store = grid.store; + // var cache = grid._by_idx; + // var res = "Grid Cells from " + grid.id + ":<br/>"; + // for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){ + // for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){ + // res += store.getValue(cache[r].item, cells[c].field) + ", "; + // } + // res = res.substring(0, res.length - 2) + ";<br/>"; + // } + // return res; + }, + getRowContent: function(grid, rowIndexes){ + // summary: + // Fill node innerHTML for dnd grid rows. + // sample code: + // var cells = grid.layout.cells; + // var store = grid.store; + // var cache = grid._by_idx; + // var res = "Grid Rows from " + grid.id + ":<br/>"; + // for(var i = 0; i < rowIndexes.length; ++i){ + // var r = rowIndexes[i]; + // res += "Row " + r + ": "; + // for(var j = 0; j < cells.length; ++j){ + // if(!cells[j].hidden){ + // res += store.getValue(cache[r].item, cells[j].field) + ", "; + // } + // } + // res = res.substring(0, res.length - 2) + ";<br/>"; + // } + // return res; + }, + getColumnContent: function(grid, colIndexes){ + // summary: + // Fill node innerHTML for dnd grid columns. + // sample code: + // var cells = grid.layout.cells; + // var res = "Grid Columns from " + grid.id + ":"; + // for(var i = 0; i < colIndexes.length; ++i){ + // var c = colIndexes[i]; + // res += (cells[c].name || cells[c].field) + ", "; + // } + // return res.substring(0, res.length - 2); + }, + onDropGridCells: function(grid, leftTopCell, rightBottomCell){ + + }, + onDropGridRows: function(grid, rowIndexes){ + + }, + onDropGridColumns: function(grid, colIndexes){ + + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js new file mode 100644 index 0000000..3b41e84 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js @@ -0,0 +1,626 @@ +//>>built +define("dojox/grid/enhanced/plugins/IndirectSelection", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/event", + "dojo/_base/lang", + "dojo/_base/html", + "dojo/_base/window", + "dojo/_base/connect", + "dojo/_base/sniff", + "dojo/query", + "dojo/keys", + "dojo/string", + "../_Plugin", + "../../EnhancedGrid", + "../../cells/dijit" +], function(declare, array, evt, lang, html, win, connect, has, query, keys, string, _Plugin, EnhancedGrid){ + +var gridCells = lang.getObject("dojox.grid.cells"); + +var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, { + // summary: + // Common attributes & functions for row selectors(Radio|CheckBox) + + //inputType: String + // Input type - Radio|CheckBox + inputType: "", + + //map: Object + // Cache div refs of radio|checkbox to avoid querying each time + map: null, + + //disabledMap: Object + // Cache index of disabled rows + disabledMap: null, + + //isRowSelector: Boolean + // Marker of indirectSelection cell(column) + isRowSelector: true, + + //_connects: Array + // List of all connections. + _connects: null, + + //_subscribes: Array + // List of all subscribes. + _subscribes: null, + + //checkedText: String + // Checked character for high contrast mode + checkedText: '✓', + + //unCheckedText: String + // Unchecked character for high contrast mode + unCheckedText: 'O', + + constructor: function(){ + this.map = {}; this.disabledMap = {}, this.disabledCount= 0; + this._connects = []; this._subscribes = []; + this.inA11YMode = html.hasClass(win.body(), "dijit_a11y"); + + this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType; + this.checkedClass = " dijit" + this.inputType + "Checked"; + this.disabledClass = " dijit" + this.inputType + "Disabled"; + this.checkedDisabledClass = " dijit" + this.inputType + "CheckedDisabled"; + this.statusTextClass = " dojoxGridRowSelectorStatusText";//a11y use + + this._connects.push(connect.connect(this.grid, 'dokeyup', this, '_dokeyup')); + this._connects.push(connect.connect(this.grid.selection, 'onSelected', this, '_onSelected')); + this._connects.push(connect.connect(this.grid.selection, 'onDeselected', this, '_onDeselected')); + this._connects.push(connect.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed')); + this._connects.push(connect.connect(this.grid, 'onCellClick', this, '_onClick')); + this._connects.push(connect.connect(this.grid, 'updateRow', this, '_onUpdateRow')); + }, + formatter: function(data, rowIndex, scope){ + // summary: + // Overwritten, see dojox.grid.cells._Widget + var _this = scope; + var clazz = _this.baseClass; + var checked = _this.getValue(rowIndex); + var disabled = !!_this.disabledMap[rowIndex];//normalize 'undefined' + + if(checked){ + clazz += _this.checkedClass; + if(disabled){ clazz += _this.checkedDisabledClass; } + }else if(disabled){ + clazz += _this.disabledClass; + } + return ["<div tabindex = -1 ", + "id = '" + _this.grid.id + "_rowSelector_" + rowIndex + "' ", + "name = '" + _this.grid.id + "_rowSelector' class = '" + clazz + "' ", + "role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled + + "' aria-label = '" + string.substitute(_this.grid._nls["indirectSelection" + _this.inputType], [rowIndex + 1]) + "'>", + "<span class = '" + _this.statusTextClass + "'>" + (checked ? _this.checkedText : _this.unCheckedText) + "</span>", + "</div>"].join(""); + }, + setValue: function(rowIndex, inValue){ + // summary: + // Overwritten, see dojox.grid.cells._Widget + // Simply return, no action + }, + getValue: function(rowIndex){ + // summary: + // Overwritten, see dojox.grid.cells._Widget + return this.grid.selection.isSelected(rowIndex); + }, + toggleRow: function(index, value){ + // summary: + // toggle checked | unchecked state for given row + // index: Integer + // Row index + // value: Boolean + // True - checked | False - unchecked + this._nativeSelect(index, value); + }, + setDisabled: function(index, disabled){ + // summary: + // toggle disabled | enabled state for given row + // idx: Integer + // Row index + // disabled: Boolean + // True - disabled | False - enabled + if(index < 0){ return; } + this._toggleDisabledStyle(index, disabled); + }, + disabled: function(index){ + // summary: + // Check if one row is disabled + return !!this.disabledMap[index]; + }, + _onClick: function(e){ + // summary: + // When mouse click on the selector cell, select/deselect the row. + if(e.cell === this){ + this._selectRow(e); + } + }, + _dokeyup: function(e){ + // summary: + // Event handler for key up event + // - from dojox.grid.enhanced._Events.dokeyup() + // e: Event + // Key up event + if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == keys.SPACE){ + this._selectRow(e); + } + }, + focus: function(rowIndex){ + // summary: + // Set focus to given row + // rowIndex: Integer + // Target row + var selector = this.map[rowIndex]; + if(selector){ selector.focus(); } + }, + _focusEndingCell: function(rowIndex, cellIndex){ + // summary: + // Set focus to the ending grid cell(rowIndex,cellIndex) when swipe selection finished + // rowIndex: Integer + // Row index + // cellIndex: Integer + // Column index + var cell = this.grid.getCell(cellIndex); + this.grid.focus.setFocusCell(cell, rowIndex); + }, + _nativeSelect: function(index, value){ + // summary: + // Use grid's native selection + this.grid.selection[value ? 'select' : 'deselect'](index); + }, + _onSelected: function(index){ + // summary: + // Triggered when a row is selected + this._toggleCheckedStyle(index, true); + }, + _onDeselected: function(index){ + // summary: + // Triggered when a row is deselected + this._toggleCheckedStyle(index, false); + }, + _onUpdateRow: function(index){ + // summary: + // Clear cache when row is re-built. + delete this.map[index]; + }, + _toggleCheckedStyle: function(index, value){ + // summary: + // Change css styles for checked | unchecked + var selector = this._getSelector(index); + if(selector){ + html.toggleClass(selector, this.checkedClass, value); + if(this.disabledMap[index]){ + html.toggleClass(selector, this.checkedDisabledClass, value); + } + selector.setAttribute("aria-pressed", value); + if(this.inA11YMode){ + selector.firstChild.innerHTML = (value ? this.checkedText : this.unCheckedText); + } + } + }, + _toggleDisabledStyle: function(index, disabled){ + // summary: + // Change css styles for disabled | enabled + var selector = this._getSelector(index); + if(selector){ + html.toggleClass(selector, this.disabledClass, disabled); + if(this.getValue(index)){ + html.toggleClass(selector, this.checkedDisabledClass, disabled); + } + selector.setAttribute("aria-disabled", disabled); + } + this.disabledMap[index] = disabled; + if(index >= 0){ + this.disabledCount += disabled ? 1 : -1; + } + }, + _getSelector: function(index){ + // summary: + // Find selector for given row caching it if 1st time found + var selector = this.map[index]; + if(!selector){//use accurate query for better performance + var rowNode = this.view.rowNodes[index]; + if(rowNode){ + selector = query('.dojoxGridRowSelector', rowNode)[0]; + if(selector){ this.map[index] = selector; } + } + } + return selector; + }, + _pageDestroyed: function(pageIndex){ + // summary: + // Explicitly empty map cache when a page destroyed + // See dojox.grid._Scroller.invalidatePageNode() + // pageIndex: Integer + // Index of destroyed page + var rowsPerPage = this.grid.scroller.rowsPerPage; + var start = pageIndex * rowsPerPage, end = start + rowsPerPage - 1; + for(var i = start; i <= end; i++){ + if(!this.map[i]){continue;} + html.destroy(this.map[i]); + delete this.map[i]; + } + //console.log("Page ",pageIndex, " destroyed, Map=",this.map); + }, + destroy: function(){ + for(var i in this.map){ + html.destroy(this.map[i]); + delete this.map[i]; + } + for(i in this.disabledMap){ delete this.disabledMap[i]; } + array.forEach(this._connects, connect.disconnect); + array.forEach(this._subscribes, connect.unsubscribe); + delete this._connects; + delete this._subscribes; + //console.log('Single(Multiple)RowSelector.destroy() executed!'); + } +}); + +var SingleRowSelector = declare("dojox.grid.cells.SingleRowSelector", RowSelector, { + // summary: + // IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton + inputType: "Radio", + + _selectRow: function(e){ + // summary: + // Select the target row + // e: Event + // Event fired on the target row + var index = e.rowIndex; + if(this.disabledMap[index]){ return; } + this._focusEndingCell(index, 0); + this._nativeSelect(index, !this.grid.selection.selected[index]); + } +}); + +var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSelector, { + // summary: + // Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox + inputType: "CheckBox", + + //swipeStartRowIndex: Integer + // Start row index for swipe selection + swipeStartRowIndex: -1, + + //swipeMinRowIndex: Integer + // Min row index for swipe selection + swipeMinRowIndex: -1, + + //swipeMinRowIndex: Integer + // Max row index for swipe selection + swipeMaxRowIndex: -1, + + //toSelect: Boolean + // new state for selection + toSelect: false, + + //lastClickRowIdx: Integer + // Row index for last click, used for range selection via Shift + click + lastClickRowIdx: -1, + + //toggleAllTrigerred: Boolean + // Whether toggle all has been triggered or not + toggleAllTrigerred: false, + + unCheckedText: '□', + + constructor: function(){ + this._connects.push(connect.connect(win.doc, 'onmouseup', this, '_domouseup')); + this._connects.push(connect.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver')); + this._connects.push(connect.connect(this.grid.focus, 'move', this, '_swipeByKey')); + this._connects.push(connect.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown')); + if(this.headerSelector){//option set by user to add a select-all checkbox in column header + this._connects.push(connect.connect(this.grid.views, 'render', this, '_addHeaderSelector')); + this._connects.push(connect.connect(this.grid, '_onFetchComplete', this, '_addHeaderSelector')); + this._connects.push(connect.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged')); + this._connects.push(connect.connect(this.grid, 'onKeyDown', this, function(e){ + if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == keys.SPACE){ + this._toggletHeader();//TBD - a better way + } + })); + } + }, + toggleAllSelection:function(checked){ + // summary: + // Toggle select all|deselect all + // checked: Boolean + // True - select all, False - deselect all + var grid = this.grid, selection = grid.selection; + if(checked){ + selection.selectRange(0, grid.rowCount-1); + }else{ + selection.deselectAll(); + } + this.toggleAllTrigerred = true; + }, + _onMouseDown: function(e){ + if(e.cell == this){ + this._startSelection(e.rowIndex); + evt.stop(e); + } + }, + _onRowMouseOver: function(e){ + // summary: + // Event fired when mouse moves over a data row(outside of this column). + // - from dojox.grid.enhanced._Events.onRowMouseOver() + // e: Event + // Decorated event object which contains reference to grid, cell, and rowIndex + this._updateSelection(e, 0); + }, + _domouseup: function(e){ + // summary: + // Event handler for mouse up event - from dojo.doc.domouseup() + // e: Event + // Mouse up event + if(has("ie")){ + this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decorated? + } + var inSwipeSelection = e.cellIndex >= 0 && this.inSwipeSelection() && !this.grid.edit.isEditRow(e.rowIndex); + if(inSwipeSelection){ + this._focusEndingCell(e.rowIndex, e.cellIndex); + } + this._finishSelect(); + }, + _dokeyup: function(e){ + // summary: + // Event handler for key up event + // - from dojox.grid.enhanced._Events.dokeyup() + // e: Event + // Key up event + this.inherited(arguments); + if(!e.shiftKey){ + this._finishSelect(); + } + }, + _startSelection: function(rowIndex){ + // summary: + // Initialize parameters to start a new swipe selection + // rowIndex: Integer + // Index of the start row + this.swipeStartRowIndex = this.swipeMinRowIndex = this.swipeMaxRowIndex = rowIndex; + this.toSelect = !this.getValue(rowIndex); + }, + _updateSelection: function(e, delta){ + // summary: + // Update row selections, fired during a swipe selection + // e: Event + // Event of the current row, + // delta: Integer + // Row index delta, used for swipe selection via Shift + Arrow key + // 0: not via key, -1 : Shift + Up, 1 : Shift + Down + if(!this.inSwipeSelection()){ return; } + + var byKey = delta !== 0;//whether via Shift + Arrow Key + var currRow = e.rowIndex, deltaRow = currRow - this.swipeStartRowIndex + delta; + if(deltaRow > 0 && this.swipeMaxRowIndex < currRow + delta){ + this.swipeMaxRowIndex = currRow + delta; + } + if(deltaRow < 0 && this.swipeMinRowIndex > currRow + delta){ + this.swipeMinRowIndex = currRow + delta; + } + + var min = deltaRow > 0 ? this.swipeStartRowIndex : currRow + delta; + var max = deltaRow > 0 ? currRow + delta : this.swipeStartRowIndex; + for(var i = this.swipeMinRowIndex; i <= this.swipeMaxRowIndex; i++){ + if(this.disabledMap[i] || i < 0){ continue; } + if(i >= min && i <= max){//deltaRow != 0 || this.toSelect + this._nativeSelect(i, this.toSelect); + }else if(!byKey){ + this._nativeSelect(i, !this.toSelect); + } + } + }, + _swipeByKey: function(rowOffset, colOffset, e){ + // summary: + // Update row selections, fired when Shift + Cursor is used for swipe selection + // See dojox.grid.enhanced._Events.onKeyDown + // e: Event + // Event of the current row, + // rowOffset: Integer + // Row offset, used for swipe selection via Shift + Cursor + // -1 : Shift + Up, 1 : Shift + Down + if(!e || rowOffset === 0 || !e.shiftKey || e.cellIndex != this.index || + this.grid.focus.rowIndex < 0){ //TBD - e.rowIndex == 0 && delta == -1 + return; + } + var rowIndex = e.rowIndex; + if(this.swipeStartRowIndex < 0){ + //A new swipe selection starts via Shift + Arrow key + this.swipeStartRowIndex = rowIndex; + if(rowOffset > 0){//Shift + Down + this.swipeMaxRowIndex = rowIndex + rowOffset; + this.swipeMinRowIndex = rowIndex; + }else{//Shift + UP + this.swipeMinRowIndex = rowIndex + rowOffset; + this.swipeMaxRowIndex = rowIndex; + } + this.toSelect = this.getValue(rowIndex); + } + this._updateSelection(e, rowOffset); + }, + _finishSelect: function(){ + // summary: + // Reset parameters to end a swipe selection + this.swipeStartRowIndex = -1; + this.swipeMinRowIndex = -1; + this.swipeMaxRowIndex = -1; + this.toSelect = false; + }, + inSwipeSelection: function(){ + // summary: + // Check if during a swipe selection + // return: Boolean + // Whether in swipe selection + return this.swipeStartRowIndex >= 0; + }, + _nativeSelect: function(index, value){ + // summary: + // Overwritten + this.grid.selection[value ? 'addToSelection' : 'deselect'](index); + }, + _selectRow: function(e){ + // summary: + // Select the target row or range or rows + // e: Event + // Event fired on the target row + var rowIndex = e.rowIndex; + if(this.disabledMap[rowIndex]){ return; } + evt.stop(e); + this._focusEndingCell(rowIndex, 0); + + var delta = rowIndex - this.lastClickRowIdx; + var newValue = !this.grid.selection.selected[rowIndex]; + if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){ + var min = delta > 0 ? this.lastClickRowIdx : rowIndex; + var max = delta > 0 ? rowIndex : this.lastClickRowIdx; + for(var i = min; i >= 0 && i <= max; i++){ + this._nativeSelect(i, newValue); + } + }else{ + this._nativeSelect(rowIndex, newValue); + } + this.lastClickRowIdx = rowIndex; + }, + getValue: function(rowIndex){ + // summary: + // Overwritten + if(rowIndex == -1){//header selector + var g = this.grid; + return g.rowCount > 0 && g.rowCount <= g.selection.getSelectedCount(); + } + return this.inherited(arguments); + }, + _addHeaderSelector: function(){ + // summary: + // Add selector in column header for selecting|deselecting all + var headerCellNode = this.view.getHeaderCellNode(this.index); + if(!headerCellNode){ return; } + html.empty(headerCellNode); + var g = this.grid; + var selector = headerCellNode.appendChild(html.create("div", { + 'aria-label': g._nls["selectAll"], + "tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "presentation", + "innerHTML": "<span class = '" + this.statusTextClass + + "'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" + + g._nls["selectAll"] + "</span>" + })); + this.map[-1] = selector; + var idx = this._headerSelectorConnectIdx; + if(idx !== undefined){ + connect.disconnect(this._connects[idx]); + this._connects.splice(idx, 1); + } + this._headerSelectorConnectIdx = this._connects.length; + this._connects.push(connect.connect(selector, 'onclick', this, '_toggletHeader')); + this._onSelectionChanged(); + }, + _toggletHeader: function(){ + // summary: + // Toggle state for head selector + if(!!this.disabledMap[-1]){ return; } + this.grid._selectingRange = true; + this.toggleAllSelection(!this.getValue(-1)); + this._onSelectionChanged(); + this.grid._selectingRange = false; + }, + _onSelectionChanged: function(){ + // summary: + // Update header selector anytime selection changed + var g = this.grid; + if(!this.map[-1] || g._selectingRange){ return; } + g.allItemsSelected = this.getValue(-1); + this._toggleCheckedStyle(-1, g.allItemsSelected); + }, + _toggleDisabledStyle: function(index, disabled){ + // summary: + // Overwritten + this.inherited(arguments); + if(this.headerSelector){ + var allDisabled = (this.grid.rowCount == this.disabledCount); + if(allDisabled != !!this.disabledMap[-1]){//only if needed + arguments[0] = -1; + arguments[1] = allDisabled; + this.inherited(arguments); + } + } + } +}); + +var IndirectSelection = declare("dojox.grid.enhanced.plugins.IndirectSelection", _Plugin, { + // summary: + // A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard) + + // description: + // For better rendering performance, div(images) are used to simulate radio button|check boxes + // + // example: + // <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div> + // or <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div> + + //name: String + // Plugin name + name: "indirectSelection", + + constructor: function(){ + //Hook layout.setStructure(), so that indirectSelection is always included + var layout = this.grid.layout; + this.connect(layout, 'setStructure', lang.hitch(layout, this.addRowSelectCell, this.option)); + }, + addRowSelectCell: function(option){ + // summary: + // Add indirectSelection cell(mapped to a column of radio button|check boxes) + if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){ + return; + } + var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'], + defaultCellDef = {type: MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'}; + if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs + + if(this.grid.rowSelectCell){//remove the existed one + this.grid.rowSelectCell.destroy(); + } + + array.forEach(this.structure, function(view){ + var cells = view.cells; + if(cells && cells.length > 0 && !rowSelectCellAdded){ + var firstRow = cells[0]; + if(firstRow[0] && firstRow[0].isRowSelector){ + console.debug('addRowSelectCell() - row selector cells already added, return.'); + rowSelectCellAdded = true; + return; + } + var selectDef, cellType = this.grid.selectionMode == 'single' ? SingleRowSelector : MultipleRowSelector; + selectDef = lang.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true}); + array.forEach(inValidFields, function(field){//remove invalid fields + if(field in selectDef){ delete selectDef[field]; } + }); + if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout + array.forEach(this.cells, function(cell, i){ + if(cell.index >= 0){ + cell.index += 1; + //console.debug('cell '+ (cell.index - 1) + ' is updated to index ' + cell.index); + }else{ + console.warn('Error:IndirectSelection.addRowSelectCell()- cell ' + i + ' has no index!'); + } + }); + var rowSelectCell = this.addCellDef(0, 0, selectDef); + rowSelectCell.index = 0; + firstRow.unshift(rowSelectCell); + this.cells.unshift(rowSelectCell); + this.grid.rowSelectCell = rowSelectCell; + rowSelectCellAdded = true; + } + }, this); + this.cellCount = this.cells.length; + }, + destroy: function(){ + this.grid.rowSelectCell.destroy(); + delete this.grid.rowSelectCell; + this.inherited(arguments); + } +}); + +EnhancedGrid.registerPlugin(IndirectSelection/*name:'indirectSelection'*/, {"preInit": true}); + +return IndirectSelection; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js new file mode 100644 index 0000000..e65ac7b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js @@ -0,0 +1,134 @@ +//>>built +define("dojox/grid/enhanced/plugins/Menu", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/html", + "dojo/_base/event", + "dojo/keys", + "../_Plugin", + "../../EnhancedGrid" +], function(declare, array, lang, html, evt, keys, _Plugin, EnhancedGrid){ + +var Menu = declare("dojox.grid.enhanced.plugins.Menu", _Plugin, { + // summary: + // Provides context menu support, including header menu, row menu, cell menu and selected region menu + // example: + // <div dojoType="dojox.grid.EnhancedGrid" + // plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId", + // selectedRegionMenu:"selectedRegionMenuId"}}" ...> + // </div> + + //name: String + // Plugin name + name: "menus", + + //name: [const] Array + // menu types + types: ['headerMenu', 'rowMenu', 'cellMenu', 'selectedRegionMenu'], + + constructor: function(){ + var g = this.grid; + g.showMenu = lang.hitch(g, this.showMenu); + g._setRowMenuAttr = lang.hitch(this, '_setRowMenuAttr'); + g._setCellMenuAttr = lang.hitch(this, '_setCellMenuAttr'); + g._setSelectedRegionMenuAttr = lang.hitch(this, '_setSelectedRegionMenuAttr'); + }, + onStartUp: function(){ + var type, option = this.option; + for(type in option){ + if(array.indexOf(this.types, type) >= 0 && option[type]){ + this._initMenu(type, option[type]); + } + } + }, + _initMenu: function(/*String*/menuType, /*String | Widget(dijit.Menu)*/menu){ + var g = this.grid; + if(!g[menuType]){//in case already created in _Grid.postCreate() + var m = this._getMenuWidget(menu); + if(!m){return;} + g.set(menuType, m); + if(menuType != "headerMenu"){ + m._scheduleOpen = function(){return;}; + }else{ + g.setupHeaderMenu(); + } + } + }, + _getMenuWidget: function(/*String|Widget(dijit.Menu)*/menu){ + // summary: + // Fetch the required menu widget(should already been created) + return (menu instanceof dijit.Menu) ? menu : dijit.byId(menu); + }, + _setRowMenuAttr: function(/*Widget(dijit.Menu)*/menu){ + // summary: + // Set row menu widget + this._setMenuAttr(menu, 'rowMenu'); + }, + _setCellMenuAttr: function(/*Widget(dijit.Menu)*/menu){ + // summary: + // Set cell menu widget + this._setMenuAttr(menu, 'cellMenu'); + }, + _setSelectedRegionMenuAttr: function(/*Widget(dijit.Menu)*/menu){ + // summary: + // Set row menu widget + this._setMenuAttr(menu, 'selectedRegionMenu'); + }, + _setMenuAttr: function(/*Widget(dijit.Menu)*/menu, /*String*/menuType){ + // summary: + // Bind menus to Grid. + var g = this.grid, n = g.domNode; + if(!menu || !(menu instanceof dijit.Menu)){ + console.warn(menuType, " of Grid ", g.id, " is not existed!"); + return; + } + if(g[menuType]){ + g[menuType].unBindDomNode(n); + } + g[menuType] = menu; + g[menuType].bindDomNode(n); + }, + showMenu: function(/*Event*/e){ + // summary: + // Show appropriate context menu + // Fired from dojox.grid.enhanced._Events.onRowContextMenu, 'this' scope - Grid + // TODO: test Shift-F10 + var inSelectedRegion = (e.cellNode && html.hasClass(e.cellNode, 'dojoxGridRowSelected') || + e.rowNode && (html.hasClass(e.rowNode, 'dojoxGridRowSelected') || html.hasClass(e.rowNode, 'dojoxGridRowbarSelected'))); + + if(inSelectedRegion && this.selectedRegionMenu){ + this.onSelectedRegionContextMenu(e); + return; + } + + var info = {target: e.target, coords: e.keyCode !== keys.F10 && "pageX" in e ? {x: e.pageX, y: e.pageY } : null}; + if(this.rowMenu && (!this.cellMenu || this.selection.isSelected(e.rowIndex) || e.rowNode && html.hasClass(e.rowNode, 'dojoxGridRowbar'))){ + this.rowMenu._openMyself(info); + evt.stop(e); + return; + } + + if(this.cellMenu){ + this.cellMenu._openMyself(info); + } + evt.stop(e); + }, + destroy: function(){ + // summary: + // Destroy all resources. + // _Grid.destroy() will unbind headerMenu + var g = this.grid; + if(g.headerMenu){g.headerMenu.unBindDomNode(g.viewsHeaderNode);} + if(g.rowMenu){g.rowMenu.unBindDomNode(g.domNode);} + if(g.cellMenu){g.cellMenu.unBindDomNode(g.domNode);} + if(g.selectedRegionMenu){g.selectedRegionMenu.destroy();} + this.inherited(arguments); + } +}); + +EnhancedGrid.registerPlugin(Menu/*name:'menus'*/); + +return Menu; + +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js new file mode 100644 index 0000000..a27cddb --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js @@ -0,0 +1,610 @@ +//>>built +define("dojox/grid/enhanced/plugins/NestedSorting", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/lang", + "dojo/_base/html", + "dojo/_base/event", + "dojo/_base/window", + "dojo/keys", + "dojo/query", + "dojo/string", + "../_Plugin", + "../../EnhancedGrid" +], function(declare, array, connect, lang, html, evt, win, keys, query, string, _Plugin, EnhancedGrid){ + +var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin, { + // summary: + // Provides nested sorting feature + // + // description: + // A flexible way to control multiple column sorting, including + // 1. Set default sorting order + // 2. Disable sorting for certain columns + // 3. Set sorting order dynamically with JS API + // + // example: + // | <script type="text/javascript"> + // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true}}, + // | sortFields: [{attribute: 'col4', descending: false},...],//set default sorting order + // | canSort: function(index, field){ return true},//disable sorting for a column + // | ... }, dojo.byId('gridDiv')); + // | grid.startup(); + // | //set new sorting order + // | grid.setSortIndex([{attribute: 'col3', descending: true},...]) + // | </script> + + // name: String + // Plugin name + name: "nestedSorting", + + _currMainSort: 'none',//'none'|'asc'|'desc' + + _currRegionIdx: -1, + + _a11yText: { + 'dojoxGridDescending' : '▾', + 'dojoxGridAscending' : '▴', + 'dojoxGridAscendingTip' : '۸', + 'dojoxGridDescendingTip': '۷', + 'dojoxGridUnsortedTip' : 'x' //'✖' + }, + + constructor: function(){ + this._sortDef = []; + this._sortData = {}; + this._headerNodes = {}; + //column index that are hidden, un-sortable or indirect selection etc. + this._excludedColIdx = []; + this.nls = this.grid._nls; + this.grid.setSortInfo = function(){}; + this.grid.setSortIndex = lang.hitch(this, '_setGridSortIndex'); + this.grid.getSortIndex = function(){}; + this.grid.getSortProps = lang.hitch(this, 'getSortProps'); + if(this.grid.sortFields){ + this._setGridSortIndex(this.grid.sortFields, null, true); + } + this.connect(this.grid.views, 'render', '_initSort');//including column resize + this.initCookieHandler(); + this.subscribe("dojox/grid/rearrange/move/" + this.grid.id, lang.hitch(this, '_onColumnDnD')); + }, + onStartUp: function(){ + //overwrite base Grid functions + this.inherited(arguments); + this.connect(this.grid, 'onHeaderCellClick', '_onHeaderCellClick'); + this.connect(this.grid, 'onHeaderCellMouseOver', '_onHeaderCellMouseOver'); + this.connect(this.grid, 'onHeaderCellMouseOut', '_onHeaderCellMouseOut'); + }, + _onColumnDnD: function(type, mapping){ + // summary: + // Update nested sorting after column moved + if(type !== 'col'){return;} + var m = mapping, obj = {}, d = this._sortData, p; + var cr = this._getCurrentRegion(); + this._blurRegion(cr); + var idx = this._getRegionHeader(cr).getAttribute('idx'); + for(p in m){ + if(d[p]){ + obj[m[p]] = d[p]; + delete d[p]; + } + if(p === idx){ + idx = m[p]; + } + } + for(p in obj){ + d[p] = obj[p]; + } + var c = this._headerNodes[idx]; + this._currRegionIdx = array.indexOf(this._getRegions(), c.firstChild); + this._initSort(false); + }, + _setGridSortIndex: function(inIndex, inAsc, noRefresh){ + if(lang.isArray(inIndex)){ + var i, d, cell; + for(i = 0; i < inIndex.length; i++){ + d = inIndex[i]; + cell = this.grid.getCellByField(d.attribute); + if(!cell){ + console.warn('Invalid sorting option, column ', d.attribute, ' not found.'); + return; + } + if(cell['nosort'] || !this.grid.canSort(cell.index, cell.field)){ + console.warn('Invalid sorting option, column ', d.attribute, ' is unsortable.'); + return; + } + } + this.clearSort(); + array.forEach(inIndex, function(d, i){ + cell = this.grid.getCellByField(d.attribute); + this.setSortData(cell.index, 'index', i); + this.setSortData(cell.index, 'order', d.descending ? 'desc': 'asc'); + }, this); + }else if(!isNaN(inIndex)){ + if(inAsc === undefined){ return; }//header click from base DataGrid + this.setSortData(inIndex, 'order', inAsc ? 'asc' : 'desc'); + }else{ + return; + } + this._updateSortDef(); + if(!noRefresh){ + this.grid.sort(); + } + }, + getSortProps: function(){ + // summary: + // Overwritten, see DataGrid.getSortProps() + return this._sortDef.length ? this._sortDef : null; + }, + _initSort: function(postSort){ + // summary: + // Initiate sorting + var g = this.grid, n = g.domNode, len = this._sortDef.length; + html.toggleClass(n, 'dojoxGridSorted', !!len); + html.toggleClass(n, 'dojoxGridSingleSorted', len === 1); + html.toggleClass(n, 'dojoxGridNestSorted', len > 1); + if(len > 0){ + this._currMainSort = this._sortDef[0].descending ? 'desc' : 'asc'; + } + var idx, excluded = this._excludedCoIdx = [];//reset it + //cache column index of hidden, un-sortable or indirect selection + this._headerNodes = query("th", g.viewsHeaderNode).forEach(function(n){ + idx = parseInt(n.getAttribute('idx'), 10); + if(html.style(n, 'display') === 'none' || g.layout.cells[idx]['nosort'] || (g.canSort && !g.canSort(idx, g.layout.cells[idx]['field']))){ + excluded.push(idx); + } + }); + this._headerNodes.forEach(this._initHeaderNode, this); + this._initFocus(); + if(postSort){ + this._focusHeader(); + } + }, + _initHeaderNode: function(node){ + // summary: + // Initiate sort for each header cell node + html.toggleClass(node, 'dojoxGridSortNoWrap', true); + var sortNode = query('.dojoxGridSortNode', node)[0]; + if(sortNode){ + html.toggleClass(sortNode, 'dojoxGridSortNoWrap', true); + } + if(array.indexOf(this._excludedCoIdx, node.getAttribute('idx')) >= 0){ + html.addClass(node, 'dojoxGridNoSort'); + return; + } + if(!query('.dojoxGridSortBtn', node).length){ + //clear any previous connects + this._connects = array.filter(this._connects, function(conn){ + if(conn._sort){ + connect.disconnect(conn); + return false; + } + return true; + }); + var n = html.create('a', { + className: 'dojoxGridSortBtn dojoxGridSortBtnNested', + title: string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.ascending]), + innerHTML: '1' + }, node.firstChild, 'last'); + n.onmousedown = evt.stop; + n = html.create('a', { + className: 'dojoxGridSortBtn dojoxGridSortBtnSingle', + title: string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.ascending]) + }, node.firstChild, 'last'); + n.onmousedown = evt.stop; + }else{ + //deal with small height grid which doesn't re-render the grid after refresh + var a1 = query('.dojoxGridSortBtnSingle', node)[0]; + var a2 = query('.dojoxGridSortBtnNested', node)[0]; + a1.className = 'dojoxGridSortBtn dojoxGridSortBtnSingle'; + a2.className = 'dojoxGridSortBtn dojoxGridSortBtnNested'; + a2.innerHTML = '1'; + html.removeClass(node, 'dojoxGridCellShowIndex'); + html.removeClass(node.firstChild, 'dojoxGridSortNodeSorted'); + html.removeClass(node.firstChild, 'dojoxGridSortNodeAsc'); + html.removeClass(node.firstChild, 'dojoxGridSortNodeDesc'); + html.removeClass(node.firstChild, 'dojoxGridSortNodeMain'); + html.removeClass(node.firstChild, 'dojoxGridSortNodeSub'); + } + this._updateHeaderNodeUI(node); + }, + _onHeaderCellClick: function(e){ + // summary + // See dojox.grid.enhanced._Events._onHeaderCellClick() + this._focusRegion(e.target); + if(html.hasClass(e.target, 'dojoxGridSortBtn')){ + this._onSortBtnClick(e); + evt.stop(e); + this._focusRegion(this._getCurrentRegion()); + } + }, + _onHeaderCellMouseOver: function(e){ + // summary + // See dojox.grid._Events._onHeaderCellMouseOver() + // When user mouseover other columns than sorted column in a single sorted grid, + // We need to show 1 in the sorted column + if(!e.cell){return; } + if(this._sortDef.length > 1){ return; } + if(this._sortData[e.cellIndex] && this._sortData[e.cellIndex].index === 0){ return; } + var p; + for(p in this._sortData){ + if(this._sortData[p] && this._sortData[p].index === 0){ + html.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex'); + break; + } + } + if(!html.hasClass(win.body(), 'dijit_a11y')){ return; } + //a11y support + var i = e.cell.index, node = e.cellNode; + var singleSortBtn = query('.dojoxGridSortBtnSingle', node)[0]; + var nestedSortBtn = query('.dojoxGridSortBtnNested', node)[0]; + + var sortMode = 'none'; + if(html.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){ + sortMode = 'single'; + }else if(html.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){ + sortMode = 'nested'; + } + var nestedIndex = nestedSortBtn.getAttribute('orderIndex'); + if(nestedIndex === null || nestedIndex === undefined){ + nestedSortBtn.setAttribute('orderIndex', nestedSortBtn.innerHTML); + nestedIndex = nestedSortBtn.innerHTML; + } + if(this.isAsc(i)){ + nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridDescending; + }else if(this.isDesc(i)){ + nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridUnsortedTip; + }else{ + nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridAscending; + } + if(this._currMainSort === 'none'){ + singleSortBtn.innerHTML = this._a11yText.dojoxGridAscending; + }else if(this._currMainSort === 'asc'){ + singleSortBtn.innerHTML = this._a11yText.dojoxGridDescending; + }else if(this._currMainSort === 'desc'){ + singleSortBtn.innerHTML = this._a11yText.dojoxGridUnsortedTip; + } + }, + _onHeaderCellMouseOut: function(e){ + // summary + // See dojox.grid.enhanced._Events._onHeaderCellMouseOut() + var p; + for(p in this._sortData){ + if(this._sortData[p] && this._sortData[p].index === 0){ + html.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex'); + break; + } + } + }, + _onSortBtnClick: function(e){ + // summary: + // If the click target is single sort button, do single sort. + // Else if the click target is nested sort button, do nest sort. + // Otherwise return. + var cellIdx = e.cell.index; + if(html.hasClass(e.target, 'dojoxGridSortBtnSingle')){ + this._prepareSingleSort(cellIdx); + }else if(html.hasClass(e.target, 'dojoxGridSortBtnNested')){ + this._prepareNestedSort(cellIdx); + }else{ + return; + } + evt.stop(e); + this._doSort(cellIdx); + }, + _doSort: function(cellIdx){ + if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){ + this.setSortData(cellIdx, 'order', 'asc'); //no sorting data + }else if(this.isAsc(cellIdx)){ + this.setSortData(cellIdx, 'order', 'desc'); //change to 'desc' + }else if(this.isDesc(cellIdx)){ + this.removeSortData(cellIdx); //remove from sorting sequence + } + this._updateSortDef(); + this.grid.sort(); + this._initSort(true); + }, + setSortData: function(cellIdx, attr, value){ + // summary: + // Set sorting data for a column. + var sd = this._sortData[cellIdx]; + if(!sd){ + sd = this._sortData[cellIdx] = {}; + } + sd[attr] = value; + }, + removeSortData: function(cellIdx){ + var d = this._sortData, i = d[cellIdx].index, p; + delete d[cellIdx]; + for(p in d){ + if(d[p].index > i){ + d[p].index--; + } + } + }, + _prepareSingleSort: function(cellIdx){ + // summary: + // Prepare the single sort, also called main sort, this will clear any existing sorting and just sort the grid by current column. + var d = this._sortData, p; + for(p in d){ + delete d[p]; + } + this.setSortData(cellIdx, 'index', 0); + this.setSortData(cellIdx, 'order', this._currMainSort === 'none' ? null : this._currMainSort); + if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){ + this._currMainSort = 'asc'; + }else if(this.isAsc(cellIdx)){ + this._currMainSort = 'desc'; + }else if(this.isDesc(cellIdx)){ + this._currMainSort = 'none'; + } + }, + _prepareNestedSort: function(cellIdx){ + // summary + // Prepare the nested sorting, this will order the column on existing sorting result. + var i = this._sortData[cellIdx] ? this._sortData[cellIdx].index : null; + if(i === 0 || !!i){ return; } + this.setSortData(cellIdx, 'index', this._sortDef.length); + }, + _updateSortDef: function(){ + this._sortDef.length = 0; + var d = this._sortData, p; + for(p in d){ + this._sortDef[d[p].index] = { + attribute: this.grid.layout.cells[p].field, + descending: d[p].order === 'desc' + }; + } + }, + _updateHeaderNodeUI: function(node){ + // summary: + // Update the column header UI based on current sorting state. + // Show indicator of the sorting order of the column, no order no indicator + var cell = this._getCellByNode(node); + var cellIdx = cell.index; + var data = this._sortData[cellIdx]; + var sortNode = query('.dojoxGridSortNode', node)[0]; + var singleSortBtn = query('.dojoxGridSortBtnSingle', node)[0]; + var nestedSortBtn = query('.dojoxGridSortBtnNested', node)[0]; + + html.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc'); + html.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc'); + if(this._currMainSort === 'asc'){ + singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.descending]); + }else if(this._currMainSort === 'desc'){ + singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.unsorted]); + }else{ + singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.ascending]); + } + + var _this = this; + function setWaiState(){ + var columnInfo = 'Column ' + (cell.index + 1) + ' ' + cell.field; + var orderState = 'none'; + var orderAction = 'ascending'; + if(data){ + orderState = data.order === 'asc' ? 'ascending' : 'descending'; + orderAction = data.order === 'asc' ? 'descending' : 'none'; + } + var a11ySingleLabel = columnInfo + ' - is sorted by ' + orderState; + var a11yNestedLabel = columnInfo + ' - is nested sorted by ' + orderState; + var a11ySingleLabelHover = columnInfo + ' - choose to sort by ' + orderAction; + var a11yNestedLabelHover = columnInfo + ' - choose to nested sort by ' + orderAction; + + singleSortBtn.setAttribute("aria-label", a11ySingleLabel); + nestedSortBtn.setAttribute("aria-label", a11yNestedLabel); + + var handles = [ + _this.connect(singleSortBtn, "onmouseover", function(){ + singleSortBtn.setAttribute("aria-label", a11ySingleLabelHover); + }), + _this.connect(singleSortBtn, "onmouseout", function(){ + singleSortBtn.setAttribute("aria-label", a11ySingleLabel); + }), + _this.connect(nestedSortBtn, "onmouseover", function(){ + nestedSortBtn.setAttribute("aria-label", a11yNestedLabelHover); + }), + _this.connect(nestedSortBtn, "onmouseout", function(){ + nestedSortBtn.setAttribute("aria-label", a11yNestedLabel); + }) + ]; + array.forEach(handles, function(handle){ handle._sort = true; }); + } + setWaiState(); + + var a11y = html.hasClass(win.body(), "dijit_a11y"); + if(!data){ + nestedSortBtn.innerHTML = this._sortDef.length + 1; + nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.ascending]); + if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridUnsortedTip;} + return; + } + if(data.index || (data.index === 0 && this._sortDef.length > 1)){ + nestedSortBtn.innerHTML = data.index + 1; + } + html.addClass(sortNode, 'dojoxGridSortNodeSorted'); + if(this.isAsc(cellIdx)){ + html.addClass(sortNode, 'dojoxGridSortNodeAsc'); + nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.descending]); + if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridAscendingTip;} + }else if(this.isDesc(cellIdx)){ + html.addClass(sortNode, 'dojoxGridSortNodeDesc'); + nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.unsorted]); + if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridDescendingTip;} + } + html.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub')); + }, + isAsc: function(cellIndex){ + return this._sortData[cellIndex].order === 'asc'; + }, + isDesc: function(cellIndex){ + return this._sortData[cellIndex].order === 'desc'; + }, + _getCellByNode: function(node){ + var i; + for(i = 0; i < this._headerNodes.length; i++){ + if(this._headerNodes[i] === node){ + return this.grid.layout.cells[i]; + } + } + return null; + }, + clearSort: function(){ + this._sortData = {}; + this._sortDef.length = 0; + }, + + //persistence + initCookieHandler: function(){ + if(this.grid.addCookieHandler){ + this.grid.addCookieHandler({ + name: "sortOrder", + onLoad: lang.hitch(this, '_loadNestedSortingProps'), + onSave: lang.hitch(this, '_saveNestedSortingProps') + }); + } + }, + _loadNestedSortingProps: function(sortInfo, grid){ + this._setGridSortIndex(sortInfo); + }, + _saveNestedSortingProps: function(grid){ + return this.getSortProps(); + }, + + //focus & keyboard + _initFocus: function(){ + var f = this.focus = this.grid.focus; + this._focusRegions = this._getRegions(); + if(!this._headerArea){ + var area = this._headerArea = f.getArea('header'); + area.onFocus = f.focusHeader = lang.hitch(this, '_focusHeader'); + area.onBlur = f.blurHeader = f._blurHeader = lang.hitch(this, '_blurHeader'); + area.onMove = lang.hitch(this, '_onMove'); + area.onKeyDown = lang.hitch(this, '_onKeyDown'); + area._regions = []; + area.getRegions = null; + this.connect(this.grid, 'onBlur', '_blurHeader'); + } + }, + _focusHeader: function(e){ + // summary: + // Overwritten, see _FocusManager.focusHeader() + //delayed: Boolean + // If called from "this.focus._delayedHeaderFocus()" + if(this._currRegionIdx === -1){ + this._onMove(0, 1, null); + }else{ + this._focusRegion(this._getCurrentRegion()); + } + try{ + evt.stop(e); + }catch(e){} + return true; + }, + _blurHeader: function(e){ + this._blurRegion(this._getCurrentRegion()); + return true; + }, + _onMove: function(rowStep, colStep, e){ + var curr = this._currRegionIdx || 0, regions = this._focusRegions; + var region = regions[curr + colStep]; + if(!region){ + return; + }else if(html.style(region, 'display') === 'none' || html.style(region, 'visibility') === 'hidden'){ + //if the region is invisible, keep finding next + this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), e); + return; + } + this._focusRegion(region); + //keep grid body scrolled by header + var view = this._getRegionView(region); + view.scrollboxNode.scrollLeft = view.headerNode.scrollLeft; + }, + _onKeyDown: function(e, isBubble){ + if(isBubble){ + switch(e.keyCode){ + case keys.ENTER: + case keys.SPACE: + if(html.hasClass(e.target, 'dojoxGridSortBtnSingle') || + html.hasClass(e.target, 'dojoxGridSortBtnNested')){ + this._onSortBtnClick(e); + } + } + } + }, + _getRegionView: function(region){ + var header = region; + while(header && !html.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; } + if(header){ + return array.filter(this.grid.views.views, function(view){ + return view.headerNode === header; + })[0] || null; + } + return null; + }, + _getRegions: function(){ + var regions = [], cells = this.grid.layout.cells; + this._headerNodes.forEach(function(n, i){ + if(html.style(n, 'display') === 'none'){return;} + if(cells[i]['isRowSelector']){ + regions.push(n); + return; + } + query('.dojoxGridSortNode,.dojoxGridSortBtnNested,.dojoxGridSortBtnSingle', n).forEach(function(node){ + node.setAttribute('tabindex', 0); + regions.push(node); + }); + },this); + return regions; + }, + _focusRegion: function(region){ + // summary + // Focus the given region + if(!region){return;} + var currRegion = this._getCurrentRegion(); + if(currRegion && region !== currRegion){ + this._blurRegion(currRegion); + } + var header = this._getRegionHeader(region); + html.addClass(header, 'dojoxGridCellSortFocus'); + if(html.hasClass(region, 'dojoxGridSortNode')){ + html.addClass(region, 'dojoxGridSortNodeFocus'); + }else if(html.hasClass(region, 'dojoxGridSortBtn')){ + html.addClass(region, 'dojoxGridSortBtnFocus'); + } + region.focus(); + this.focus.currentArea('header'); + this._currRegionIdx = array.indexOf(this._focusRegions, region); + }, + _blurRegion: function(region){ + if(!region){return;} + var header = this._getRegionHeader(region); + html.removeClass(header, 'dojoxGridCellSortFocus'); + if(html.hasClass(region, 'dojoxGridSortNode')){ + html.removeClass(region, 'dojoxGridSortNodeFocus'); + }else if(html.hasClass(region, 'dojoxGridSortBtn')){ + html.removeClass(region, 'dojoxGridSortBtnFocus'); + } + region.blur(); + }, + _getCurrentRegion: function(){ + return this._focusRegions ? this._focusRegions[this._currRegionIdx] : null; + }, + _getRegionHeader: function(region){ + while(region && !html.hasClass(region, 'dojoxGridCell')){ + region = region.parentNode; + } + return region; + }, + destroy: function(){ + this._sortDef = this._sortData = null; + this._headerNodes = this._focusRegions = null; + this.inherited(arguments); + } +}); + +EnhancedGrid.registerPlugin(NestedSorting); + +return NestedSorting; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js new file mode 100644 index 0000000..244d79d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js @@ -0,0 +1,974 @@ +//>>built +require({cache:{ +'url:dojox/grid/enhanced/templates/Pagination.html':"<div dojoAttachPoint=\"paginatorBar\"\n\t><table cellpadding=\"0\" cellspacing=\"0\" class=\"dojoxGridPaginator\"\n\t\t><tr\n\t\t\t><td dojoAttachPoint=\"descriptionTd\" class=\"dojoxGridDescriptionTd\"\n\t\t\t\t><div dojoAttachPoint=\"descriptionDiv\" class=\"dojoxGridDescription\"></div\n\t\t\t></div></td\n\t\t\t><td dojoAttachPoint=\"sizeSwitchTd\"></td\n\t\t\t><td dojoAttachPoint=\"pageStepperTd\" class=\"dojoxGridPaginatorFastStep\"\n\t\t\t\t><div dojoAttachPoint=\"pageStepperDiv\" class=\"dojoxGridPaginatorStep\"></div\n\t\t\t></td\n\t\t\t><td dojoAttachPoint=\"gotoPageTd\" class=\"dojoxGridPaginatorGotoTd\"\n\t\t\t\t><div dojoAttachPoint=\"gotoPageDiv\" class=\"dojoxGridPaginatorGotoDiv\" dojoAttachEvent=\"onclick:_openGotopageDialog, onkeydown:_openGotopageDialog\"\n\t\t\t\t\t><span class=\"dojoxGridWardButtonInner\">⊥</span\n\t\t\t\t></div\n\t\t\t></td\n\t\t></tr\n\t></table\n></div>\n"}}); +define("dojox/grid/enhanced/plugins/Pagination", [ + "dojo/_base/kernel", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/lang", + "dojo/_base/html", + "dojo/_base/event", + "dojo/_base/window", + "dojo/query", + "dojo/string", + "dojo/i18n", + "dojo/keys", + "dojo/text!../templates/Pagination.html", + "./Dialog", + "./_StoreLayer", + "../_Plugin", + "../../EnhancedGrid", + "dijit/form/Button", + "dijit/form/NumberTextBox", + "dijit/focus", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/_WidgetsInTemplateMixin", + "dojox/html/metrics", + "dojo/i18n!../nls/Pagination" +], function(kernel, declare, array, connect, lang, html, event, win, query, + string, i18n, keys, template, Dialog, layers, _Plugin, EnhancedGrid, + Button, NumberTextBox, dijitFocus, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, metrics){ + +var _GotoPagePane = declare("dojox.grid.enhanced.plugins.pagination._GotoPagePane", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], { + templateString: "<div>" + + "<div class='dojoxGridDialogMargin' dojoAttachPoint='_mainMsgNode'></div>" + + "<div class='dojoxGridDialogMargin'>" + + "<input dojoType='dijit.form.NumberTextBox' style='width: 50px;' dojoAttachPoint='_pageInputBox' dojoAttachEvent='onKeyUp: _onKey'></input>" + + "<label dojoAttachPoint='_pageLabelNode'></label>" + + "</div>" + + "<div class='dojoxGridDialogButton'>" + + "<button dojoType='dijit.form.Button' dojoAttachPoint='_confirmBtn' dojoAttachEvent='onClick: _onConfirm'></button>" + + "<button dojoType='dijit.form.Button' dojoAttachPoint='_cancelBtn' dojoAttachEvent='onClick: _onCancel'></button>" + + "</div>" + + "</div>", + widgetsInTemplate: true, + dlg: null, + postMixInProperties: function(){ + this.plugin = this.dlg.plugin; + }, + postCreate: function(){ + this.inherited(arguments); + this._mainMsgNode.innerHTML = this.plugin._nls[12]; + this._confirmBtn.set("label", this.plugin._nls[14]); + this._confirmBtn.set("disabled", true); + this._cancelBtn.set("label", this.plugin._nls[15]); + }, + _onConfirm: function(evt){ + if(this._pageInputBox.isValid() && this._pageInputBox.getDisplayedValue() !== ""){ + this.plugin.currentPage(this._pageInputBox.parse(this._pageInputBox.getDisplayedValue())); + this.dlg._gotoPageDialog.hide(); + this._pageInputBox.reset(); + } + stopEvent(evt); + }, + _onCancel: function(evt){ + this._pageInputBox.reset(); + this.dlg._gotoPageDialog.hide(); + stopEvent(evt); + }, + _onKey: function(evt){ + this._confirmBtn.set("disabled", !this._pageInputBox.isValid() || this._pageInputBox.getDisplayedValue() == ""); + if(!evt.altKey && !evt.metaKey && evt.keyCode === keys.ENTER){ + this._onConfirm(evt); + } + } +}); + +var _GotoPageDialog = declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, { + pageCount: 0, + dlgPane: null, + constructor: function(plugin){ + this.plugin = plugin; + this.dlgPane = new _GotoPagePane({"dlg": this}); + this.dlgPane.startup(); + this._gotoPageDialog = new Dialog({ + "refNode": plugin.grid.domNode, + "title": this.plugin._nls[11], + "content": this.dlgPane + }); + this._gotoPageDialog.startup(); + }, + _updatePageCount: function(){ + this.pageCount = this.plugin.getTotalPageNum(); + this.dlgPane._pageInputBox.constraints = {fractional:false, min:1, max:this.pageCount}; + this.dlgPane._pageLabelNode.innerHTML = string.substitute(this.plugin._nls[13], [this.pageCount]); + }, + showDialog: function(){ + this._updatePageCount(); + this._gotoPageDialog.show(); + }, + destroy: function(){ + this._gotoPageDialog.destroy(); + } +}); + +var _ForcedPageStoreLayer = declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", layers._StoreLayer, { + tags: ["presentation"], + constructor: function(plugin){ + this._plugin = plugin; + }, + _fetch: function(request){ + var _this = this, + plugin = _this._plugin, + grid = plugin.grid, + scope = request.scope || win.global, + onBegin = request.onBegin; + request.start = (plugin._currentPage - 1) * plugin._currentPageSize + request.start; + _this.startIdx = request.start; + _this.endIdx = request.start + plugin._currentPageSize - 1; + var p = plugin._paginator; + if(!plugin._showAll){ + plugin._showAll = !p.sizeSwitch && !p.pageStepper && !p.gotoButton; + } + if(onBegin && plugin._showAll){ + request.onBegin = function(size, req){ + plugin._maxSize = plugin._currentPageSize = size; + _this.startIdx = 0; + _this.endIdx = size - 1; + plugin._paginator._update(); + req.onBegin = onBegin; + req.onBegin.call(scope, size, req); + }; + }else if(onBegin){ + request.onBegin = function(size, req){ + req.start = 0; + req.count = plugin._currentPageSize; + plugin._maxSize = size; + _this.endIdx = _this.endIdx >= size ? (size - 1) : _this.endIdx; + if(_this.startIdx > size && size !== 0){ + grid._pending_requests[req.start] = false; + plugin.firstPage(); + } + plugin._paginator._update(); + req.onBegin = onBegin; + req.onBegin.call(scope, Math.min(plugin._currentPageSize, (size - _this.startIdx)), req); + }; + } + return lang.hitch(this._store, this._originFetch)(request); + } +}); + +var stopEvent = function(evt){ + try{ + event.stop(evt); + }catch(e){} +}; + +var _Focus = declare("dojox.grid.enhanced.plugins.pagination._Focus", null, { + _focusedNode: null, + _isFocused: false, + constructor: function(paginator){ + this._pager = paginator; + var focusMgr = paginator.plugin.grid.focus; + paginator.plugin.connect(paginator, 'onSwitchPageSize', lang.hitch(this, '_onActive')); + paginator.plugin.connect(paginator, 'onPageStep', lang.hitch(this, '_onActive')); + paginator.plugin.connect(paginator, 'onShowGotoPageDialog', lang.hitch(this, '_onActive')); + paginator.plugin.connect(paginator, '_update', lang.hitch(this, '_moveFocus')); + }, + _onFocus: function(evt, step){ + var node, nodes; + if(!this._isFocused){ + node = this._focusedNode || query('[tabindex]', this._pager.domNode)[0]; + }else if(step && this._focusedNode){ + var dir = step > 0 ? -1 : 1, + tabindex = parseInt(this._focusedNode.getAttribute('tabindex'), 10) + dir; + while(tabindex >= -3 && tabindex < 0){ + node = query('[tabindex=' + tabindex + ']', this._pager.domNode)[0]; + if(node){ + break; + }else{ + tabindex += dir; + } + } + } + return this._focus(node, evt); + }, + _onBlur: function(evt, step){ + if(!step || !this._focusedNode){ + this._isFocused = false; + if(this._focusedNode && html.hasClass(this._focusedNode, 'dojoxGridButtonFocus')){ + html.removeClass(this._focusedNode, 'dojoxGridButtonFocus'); + } + return true; + } + var node, dir = step > 0 ? -1 : 1, + tabindex = parseInt(this._focusedNode.getAttribute('tabindex'), 10) + dir; + while(tabindex >= -3 && tabindex < 0){ + node = query('[tabindex=' + tabindex + ']', this._pager.domNode)[0]; + if(node){ + break; + }else{ + tabindex += dir; + } + } + if(!node){ + this._isFocused = false; + if(html.hasClass(this._focusedNode, 'dojoxGridButtonFocus')){ + html.removeClass(this._focusedNode, 'dojoxGridButtonFocus'); + } + } + return node ? false : true; + }, + _onMove: function(rowDelta, colDelta, evt){ + if(this._focusedNode){ + var tabindex = this._focusedNode.getAttribute('tabindex'), + delta = colDelta == 1 ? "nextSibling" : "previousSibling", + node = this._focusedNode[delta]; + while(node){ + if(node.getAttribute('tabindex') == tabindex){ + this._focus(node); + break; + } + node = node[delta]; + } + } + }, + _focus: function(node, evt){ + if(node){ + this._isFocused = true; + if(kernel.isIE && this._focusedNode){ + html.removeClass(this._focusedNode, 'dojoxGridButtonFocus'); + } + this._focusedNode = node; + node.focus(); + if(kernel.isIE){ + html.addClass(node, 'dojoxGridButtonFocus'); + } + stopEvent(evt); + return true; + } + return false; + }, + _onActive: function(e){ + this._focusedNode = e.target; + if(!this._isFocused){ + this._pager.plugin.grid.focus.focusArea('pagination' + this._pager.position); + } + }, + _moveFocus: function(){ + if(this._focusedNode && !this._focusedNode.getAttribute('tabindex')){ + var next = this._focusedNode.nextSibling; + while(next){ + if(next.getAttribute('tabindex')){ + this._focus(next); + return; + } + next = next.nextSibling; + } + var prev = this._focusedNode.previousSibling; + while(prev){ + if(prev.getAttribute('tabindex')){ + this._focus(prev); + return; + } + prev = prev.previousSibling; + } + this._focusedNode = null; + this._onBlur(); + }else if(kernel.isIE && this._focusedNode){ + html.addClass(this._focusedNode, 'dojoxGridButtonFocus'); + } + } +}); + +var _Paginator = declare("dojox.grid.enhanced.plugins._Paginator", [_Widget, _TemplatedMixin], { + templateString: template, + constructor: function(params){ + lang.mixin(this, params); + this.grid = this.plugin.grid; + }, + postCreate: function(){ + this.inherited(arguments); + var _this = this, g = this.grid; + this.plugin.connect(g, "_resize", lang.hitch(this, "_resetGridHeight")); + this._originalResize = g.resize; + g.resize = function(changeSize, resultSize){ + _this._changeSize = changeSize; + _this._resultSize = resultSize; + _this._originalResize.apply(g, arguments); + }; + this.focus = _Focus(this); + this._placeSelf(); + }, + destroy: function(){ + this.inherited(arguments); + this.grid.focus.removeArea("pagination" + this.position); + if(this._gotoPageDialog){ + this._gotoPageDialog.destroy(); + } + this.grid.resize = this._originalResize; + }, + onSwitchPageSize: function(/*Event*/evt){ + + }, + onPageStep: function(/*Event*/evt){ + + }, + onShowGotoPageDialog: function(/*Event*/evt){ + + }, + _update: function(){ + // summary: + // Function to update paging information and update + // pagination bar display. + this._updateDescription(); + this._updatePageStepper(); + this._updateSizeSwitch(); + this._updateGotoButton(); + }, + _registerFocus: function(isTop){ + // summary: + // Function to register pagination bar to focus manager. + var focusMgr = this.grid.focus, + name = "pagination" + this.position, + f = this.focus; + focusMgr.addArea({ + name: name, + onFocus: lang.hitch(this.focus, "_onFocus"), + onBlur: lang.hitch(this.focus, "_onBlur"), + onMove: lang.hitch(this.focus, "_onMove") + }); + focusMgr.placeArea(name, isTop ? "before" : "after", isTop ? "header" : "content"); + }, + _placeSelf: function(){ + // summary: + // Place pagination bar to a position. + // There are two options, top of the grid, bottom of the grid. + var g = this.grid, + isTop = this.position == "top"; + this.placeAt(isTop ? g.viewsHeaderNode : g.viewsNode, isTop ? "before" : "after"); + this._registerFocus(isTop); + }, + _resetGridHeight: function(changeSize, resultSize){ + // summary: + // Function of resize grid height to place this pagination bar. + // Since the grid would be able to add other element in its domNode, we have + // change the grid view size to place the pagination bar. + // This function will resize the grid viewsNode height, scorllboxNode height + var g = this.grid; + changeSize = changeSize || this._changeSize; + resultSize = resultSize || this._resultSize; + delete this._changeSize; + delete this._resultSize; + if(g._autoHeight){ + return; + } + var padBorder = g._getPadBorder().h; + if(!this.plugin.gh){ + this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder; + } + if(resultSize){ + changeSize = resultSize; + } + if(changeSize){ + this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder; + } + var gh = this.plugin.gh, + hh = g._getHeaderHeight(), + ph = html.marginBox(this.domNode).h; + // ph = this.plugin._paginator.position == "bottom" ? ph * 2 : ph; + if(typeof g.autoHeight === "number"){ + var cgh = gh + ph - padBorder; + html.style(g.domNode, "height", cgh + "px"); + html.style(g.viewsNode, "height", (cgh - ph - hh) + "px"); + this._styleMsgNode(hh, html.marginBox(g.viewsNode).w, cgh - ph - hh); + }else{ + var h = gh - ph - hh - padBorder; + html.style(g.viewsNode, "height", h + "px"); + var hasHScroller = array.some(g.views.views, function(v){ + return v.hasHScrollbar(); + }); + array.forEach(g.viewsNode.childNodes, function(c){ + html.style(c, "height", h + "px"); + }); + array.forEach(g.views.views, function(v){ + if(v.scrollboxNode){ + if(!v.hasHScrollbar() && hasHScroller){ + html.style(v.scrollboxNode, "height", (h - metrics.getScrollbar().h) + "px"); + }else{ + html.style(v.scrollboxNode, "height", h + "px"); + } + } + }); + this._styleMsgNode(hh, html.marginBox(g.viewsNode).w, h); + } + }, + _styleMsgNode: function(top, width, height){ + var messagesNode = this.grid.messagesNode; + html.style(messagesNode, {"position": "absolute", "top": top + "px", "width": width + "px", "height": height + "px", "z-Index": "100"}); + }, + _updateDescription: function(){ + // summary: + // Update size information. + var s = this.plugin.forcePageStoreLayer, + maxSize = this.plugin._maxSize, + nls = this.plugin._nls, + getItemTitle = function(){ + return maxSize <= 0 || maxSize == 1 ? nls[5] : nls[4]; + }; + if(this.description && this.descriptionDiv){ + this.descriptionDiv.innerHTML = maxSize > 0 ? string.substitute(nls[0], [getItemTitle(), maxSize, s.startIdx + 1, s.endIdx + 1]) : "0 " + getItemTitle(); + } + }, + _updateSizeSwitch: function(){ + // summary: + // Update "items per page" information. + html.style(this.sizeSwitchTd, "display", this.sizeSwitch ? "" : "none"); + if(!this.sizeSwitch){ + return; + } + if(this.sizeSwitchTd.childNodes.length < 1){ + this._createSizeSwitchNodes(); + } + this._updateSwitchNodesStyle(); + }, + _createSizeSwitchNodes: function(){ + // summary: + // The function to create the size switch nodes + var node = null, + nls = this.plugin._nls, + connect = lang.hitch(this.plugin, 'connect'); + array.forEach(this.pageSizes, function(size){ + // create page size switch node + var labelValue = isFinite(size) ? string.substitute(nls[2], [size]) : nls[1], + value = isFinite(size) ? size : nls[16]; + node = html.create("span", {innerHTML: value, title: labelValue, value: size, tabindex: "-1"}, this.sizeSwitchTd, "last"); + // for accessibility + node.setAttribute("aria-label", labelValue); + // connect event + connect(node, "onclick", lang.hitch(this, "_onSwitchPageSize")); + connect(node, "onkeydown", lang.hitch(this, "_onSwitchPageSize")); + connect(node, "onmouseover", function(e){ + html.addClass(e.target, "dojoxGridPageTextHover"); + }); + connect(node, "onmouseout", function(e){ + html.removeClass(e.target, "dojoxGridPageTextHover"); + }); + // create a separation node + node = html.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last"); + html.addClass(node, "dojoxGridSeparator"); + }, this); + // delete last separation node + html.destroy(node); + }, + _updateSwitchNodesStyle: function(){ + // summary: + // Update the switch nodes style + var size = null; + var styleNode = function(node, status){ + if(status){ + html.addClass(node, "dojoxGridActivedSwitch"); + html.removeAttr(node, "tabindex"); + }else{ + html.addClass(node, "dojoxGridInactiveSwitch"); + node.setAttribute("tabindex", "-1"); + } + }; + array.forEach(this.sizeSwitchTd.childNodes, function(node){ + if(node.value){ + html.removeClass(node); + size = node.value; + if(this.plugin._showAll){ + styleNode(node, isNaN(parseInt(size, 10))); + }else{ + styleNode(node, this.plugin._currentPageSize == size); + } + } + }, this); + }, + _updatePageStepper: function(){ + // summary: + // Update the page step nodes + html.style(this.pageStepperTd, "display", this.pageStepper ? "" : "none"); + if(!this.pageStepper){ + return; + } + if(this.pageStepperDiv.childNodes.length < 1){ + this._createPageStepNodes(); + this._createWardBtns(); + }else{ + this._resetPageStepNodes(); + } + this._updatePageStepNodesStyle(); + }, + _createPageStepNodes: function(){ + // summary: + // Create the page step nodes if they do not exist + var startPage = this._getStartPage(), + stepSize = this._getStepPageSize(), + label = "", node = null, i = startPage, + connect = lang.hitch(this.plugin, 'connect'); + for(; i < startPage + this.maxPageStep + 1; i++){ + label = string.substitute(this.plugin._nls[3], [i]); + node = html.create("div", {innerHTML: i, value: i, title: label}, this.pageStepperDiv, "last"); + node.setAttribute("aria-label", label); + // connect event + connect(node, "onclick", lang.hitch(this, "_onPageStep")); + connect(node, "onkeydown", lang.hitch(this, "_onPageStep")); + connect(node, "onmouseover", function(e){ + html.addClass(e.target, "dojoxGridPageTextHover"); + }); + connect(node, "onmouseout", function(e){ + html.removeClass(e.target, "dojoxGridPageTextHover"); + }); + html.style(node, "display", i < startPage + stepSize ? "" : "none"); + } + }, + _createWardBtns: function(){ + // summary: + // Create the previous/next/first/last button + var _this = this, nls = this.plugin._nls; + var highContrastLabel = {prevPage: "<", firstPage: "«", nextPage: ">", lastPage: "»"}; + var createWardBtn = function(value, label, position){ + var node = html.create("div", {value: value, title: label, tabindex: "-2"}, _this.pageStepperDiv, position); + _this.plugin.connect(node, "onclick", lang.hitch(_this, "_onPageStep")); + _this.plugin.connect(node, "onkeydown", lang.hitch(_this, "_onPageStep")); + node.setAttribute("aria-label", label); + // for high contrast + var highConrastNode = html.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position); + html.addClass(highConrastNode, "dojoxGridWardButtonInner"); + }; + createWardBtn("prevPage", nls[6], "first"); + createWardBtn("firstPage", nls[7], "first"); + createWardBtn("nextPage", nls[8], "last"); + createWardBtn("lastPage", nls[9], "last"); + }, + _resetPageStepNodes: function(){ + // summary: + // The page step nodes might be changed when fetch data, we need to + // update/reset them + var startPage = this._getStartPage(), + stepSize = this._getStepPageSize(), + stepNodes = this.pageStepperDiv.childNodes, + node = null, i = startPage, j = 2, tip; + for(; j < stepNodes.length - 2; j++, i++){ + node = stepNodes[j]; + if(i < startPage + stepSize){ + tip = string.substitute(this.plugin._nls[3], [i]); + html.attr(node, { + "innerHTML": i, + "title": tip, + "value": i + }); + html.style(node, "display", ""); + node.setAttribute("aria-label", tip); + }else{ + html.style(node, "display", "none"); + } + } + }, + _updatePageStepNodesStyle: function(){ + // summary: + // Update the style of the page step nodes + var value = null, + curPage = this.plugin.currentPage(), + pageCount = this.plugin.getTotalPageNum(); + var updateClass = function(node, isWardBtn, status){ + var value = node.value, + enableClass = isWardBtn ? "dojoxGrid" + value + "Btn" : "dojoxGridInactived", + disableClass = isWardBtn ? "dojoxGrid" + value + "BtnDisable" : "dojoxGridActived"; + if(status){ + html.addClass(node, disableClass); + html.removeAttr(node, "tabindex"); + }else{ + html.addClass(node, enableClass); + node.setAttribute("tabindex", "-2"); + } + }; + array.forEach(this.pageStepperDiv.childNodes, function(node){ + html.removeClass(node); + if(isNaN(parseInt(node.value, 10))){ + html.addClass(node, "dojoxGridWardButton"); + var disablePageNum = node.value == "prevPage" || node.value == "firstPage" ? 1 : pageCount; + updateClass(node, true, (curPage === disablePageNum)); + }else{ + value = parseInt(node.value, 10); + updateClass(node, false, (value === curPage || html.style(node, "display") === "none")); + } + }, this); + }, + _showGotoButton: function(flag){ + this.gotoButton = flag; + this._updateGotoButton(); + }, + _updateGotoButton: function(){ + // summary: + // Create/destroy the goto page button + if(!this.gotoButton){ + if(this._gotoPageDialog){ + this._gotoPageDialog.destroy(); + } + html.removeAttr(this.gotoPageDiv, "tabindex"); + html.style(this.gotoPageTd, 'display', 'none'); + return; + } + if(html.style(this.gotoPageTd, 'display') == 'none'){ + html.style(this.gotoPageTd, 'display', ''); + } + this.gotoPageDiv.setAttribute('title', this.plugin._nls[10]); + html.toggleClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDivDisabled", this.plugin.getTotalPageNum() <= 1); + if(this.plugin.getTotalPageNum() <= 1){ + html.removeAttr(this.gotoPageDiv, "tabindex"); + }else{ + this.gotoPageDiv.setAttribute("tabindex", "-3"); + } + }, + _openGotopageDialog: function(e){ + // summary: + // Show the goto page dialog + if(this.plugin.getTotalPageNum() <= 1){ + return; + } + if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){ + return; + } + if(!this._gotoPageDialog){ + this._gotoPageDialog = new _GotoPageDialog(this.plugin); + } + this._gotoPageDialog.showDialog(); + this.onShowGotoPageDialog(e); + }, + _onSwitchPageSize: function(/*Event*/e){ + // summary: + // The handler of switch the page size + if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){ + return; + } + this.onSwitchPageSize(e); + this.plugin.currentPageSize(e.target.value); + }, + _onPageStep: function(/*Event*/e){ + // summary: + // The handler jump page event + if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){ + return; + } + var p = this.plugin, + value = e.target.value; + this.onPageStep(e); + if(!isNaN(parseInt(value, 10))){ + p.currentPage(parseInt(value, 10)); + }else{ + p[value](); + } + }, + _getStartPage: function(){ + var cp = this.plugin.currentPage(), + ms = this.maxPageStep, + hs = parseInt(ms / 2, 10), + tp = this.plugin.getTotalPageNum(); + if(cp < hs || (cp - hs) < 1 || tp <= ms){ + return 1; + }else{ + return tp - cp < hs && cp - ms >= 0 ? tp - ms + 1 : cp - hs; + } + }, + _getStepPageSize: function(){ + var sp = this._getStartPage(), + tp = this.plugin.getTotalPageNum(), + ms = this.maxPageStep; + return sp + ms > tp ? tp - sp + 1 : ms; + } +}); + +var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, { + // summary: + // The typical pagination way to deal with huge dataset + // an alternative for the default virtual scrolling manner. + name: "pagination", + // defaultPageSize: Integer + // Number of rows in a page, 25 by default. + defaultPageSize: 25, + // defaultPage: Integer + // Which page will be displayed initially, 1st page by default. + defaultPage: 1, + // description: boolean + // Whether the description information will be displayed, true by default. + description: true, + // sizeSwitch: boolean + // Whether the page size switch options will be displayed, true by default. + sizeSwitch: true, + // pageStepper: boolean + // Whether the page switch options will be displayed, true by default. + pageStepper: true, + // gotoButton: boolean + // Whether the goto page button will be displayed, false by default. + gotoButton: false, + // pageSizes: Array + // Array of page sizes for switching, e.g. [10, 25, 50, 100, Infinity] by default, + // Infinity or any NaN value will be treated as "all". + pageSizes: [10, 25, 50, 100, Infinity], + // maxPageStep: Integer + // The max number of page sizes to be displayed, 7 by default. + maxPageStep: 7, + // position: string + // The position of the pagination bar - "top"|"bottom", "bottom" by default. + position: 'bottom', + + init: function(){ + var g = this.grid; + g.usingPagination = true; + this._initOptions(); + this._currentPage = this.defaultPage; + this._currentPageSize = this.grid.rowsPerPage = this.defaultPageSize; + // wrap store layer + this._store = g.store; + this.forcePageStoreLayer = new _ForcedPageStoreLayer(this); + layers.wrap(g, "_storeLayerFetch", this.forcePageStoreLayer); + // create pagination bar + this._paginator = this.option.position != "top" ? + new _Paginator(lang.mixin(this.option, {position: "bottom", plugin: this})) : + new _Paginator(lang.mixin(this.option, {position: "top", plugin: this})); + this._regApis(); + }, + destroy: function(){ + this.inherited(arguments); + this._paginator.destroy(); + var g = this.grid; + g.unwrap(this.forcePageStoreLayer.name()); + g.scrollToRow = this._gridOriginalfuncs[0]; + g._onNew = this._gridOriginalfuncs[1]; + g.removeSelectedRows = this._gridOriginalfuncs[2]; + this._paginator = null; + this._nls = null; + }, + currentPage: function(page){ + // summary: + // Shift to the given page, return current page number. If there + // is no valid page was passed in, just return current page num. + // page: Integer + // The page to go to, starting at 1. + // return: + // Current page number + if(page <= this.getTotalPageNum() && page > 0 && this._currentPage !== page){ + this._currentPage = page; + this.grid._refresh(true); + this.grid.resize(); + } + return this._currentPage; + }, + nextPage: function(){ + // summary: + // Go to the next page. + this.currentPage(this._currentPage + 1); + }, + prevPage: function(){ + // summary: + // Go to the previous page. + this.currentPage(this._currentPage - 1); + }, + firstPage: function(){ + // summary: + // Go to the first page + this.currentPage(1); + }, + lastPage: function(){ + // summary: + // Go to the last page + this.currentPage(this.getTotalPageNum()); + }, + currentPageSize: function(size){ + // summary: + // Change the size of current page or return the current page size. + // size: Integer || null + // An integer identifying the number of rows per page. If the size + // is an Infinity, all rows will be displayed; if an invalid value pssed + // in, the current page size will be returned. + // return + // Current size of items per page. + if(!isNaN(size)){ + var g = this.grid, + startIndex = this._currentPageSize * (this._currentPage - 1), endIndex; + this._showAll = !isFinite(size); + this.grid.usingPagination = !this._showAll; + this._currentPageSize = this._showAll ? this._maxSize : size; + g.rowsPerPage = this._showAll ? this._defaultRowsPerPage : size; + endIndex = startIndex + Math.min(this._currentPageSize, this._maxSize); + if(endIndex > this._maxSize){ + this.lastPage(); + }else{ + var cp = Math.ceil(startIndex / this._currentPageSize) + 1; + if(cp !== this._currentPage){ + this.currentPage(cp); + }else{ + this.grid._refresh(true); + } + } + this.grid.resize(); + } + return this._currentPageSize; + }, + getTotalPageNum: function(){ + // summary: + // Get total page number + return Math.ceil(this._maxSize / this._currentPageSize); + }, + getTotalRowCount: function(){ + // summary: + // Function for get total row count + return this._maxSize; + }, + scrollToRow: function(inRowIndex){ + // summary: + // Override the grid.scrollToRow(), could jump to the right page + // and scroll to the specific row + // inRowIndex: integer + // The row index + var page = parseInt(inRowIndex / this._currentPageSize, 10) + 1; + if(page > this.getTotalPageNum()){ + return; + } + this.currentPage(page); + var rowIdx = inRowIndex % this._currentPageSize; + return this._gridOriginalfuncs[0](rowIdx); + }, + removeSelectedRows: function(){ + this._multiRemoving = true; + this._gridOriginalfuncs[2].apply(); + this._multiRemoving = false; + this.grid.resize(); + this.grid._refresh(); + }, + showGotoPageButton: function(flag){ + // summary: + // For show/hide the go to page button dynamically + // flag: boolean + // Show the go to page button when flag is true, otherwise hide it + this._paginator.gotoButton = flag; + this._paginator._updateGotoButton(); + }, + // [DEPRECATED] ============ + gotoPage: function(page){ + kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoPage(page)", "use dojox.grid.enhanced.EnhancedGrid.currentPage(page) instead", "1.8"); + this.currentPage(page); + }, + gotoFirstPage: function(){ + kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoFirstPage()", "use dojox.grid.enhanced.EnhancedGrid.firstPage() instead", "1.8"); + this.firstPage(); + }, + gotoLastPage: function(){ + kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoLastPage()", "use dojox.grid.enhanced.EnhancedGrid.lastPage() instead", "1.8"); + this.lastPage(); + }, + changePageSize: function(size){ + kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.changePageSize(size)", "use dojox.grid.enhanced.EnhancedGrid.currentPageSize(size) instead", "1.8"); + this.currentPageSize(size); + }, + // =============== Protected ================ + _nls: null, + _showAll: false, + _maxSize: 0, + // =============== Private =============== + _defaultRowsPerPage: 25, + _currentPage: 1, + _currentPageSize: 25, + + _initOptions: function(){ + this._defaultRowsPerPage = this.grid.rowsPerPage || 25; + this.defaultPage = this.option.defaultPage >= 1 ? parseInt(this.option.defaultPage, 10) : 1; + this.option.description = this.option.description !== undefined ? !!this.option.description : this.description; + this.option.sizeSwitch = this.option.sizeSwitch !== undefined ? !!this.option.sizeSwitch : this.sizeSwitch; + this.option.pageStepper = this.option.pageStepper !== undefined ? !!this.option.pageStepper : this.pageStepper; + this.option.gotoButton = this.option.gotoButton !== undefined ? !!this.option.gotoButton : this.gotoButton; + if(lang.isArray(this.option.pageSizes)){ + var pageSizes = []; + array.forEach(this.option.pageSizes, function(size){ + size = typeof size == 'number' ? size : parseInt(size, 10); + if(!isNaN(size) && size > 0){ + pageSizes.push(size); + }else if(array.indexOf(pageSizes, Infinity) < 0){ + pageSizes.push(Infinity); + } + }, this); + this.option.pageSizes = pageSizes.sort(function(a, b){return a - b;}); + }else{ + this.option.pageSizes = this.pageSizes; + } + this.defaultPageSize = this.option.defaultPageSize >= 1 ? parseInt(this.option.defaultPageSize, 10) : this.pageSizes[0]; + this.option.maxPageStep = this.option.maxPageStep > 0 ? this.option.maxPageStep : this.maxPageStep; + this.option.position = lang.isString(this.option.position) ? this.option.position.toLowerCase() : this.position; + var nls = i18n.getLocalization("dojox.grid.enhanced", "Pagination"); + this._nls = [ + nls.descTemplate, + nls.allItemsLabelTemplate, + nls.pageSizeLabelTemplate, + nls.pageStepLabelTemplate, + nls.itemTitle, + nls.singularItemTitle, + nls.prevTip, + nls.firstTip, + nls.nextTip, + nls.lastTip, + nls.gotoButtonTitle, + nls.dialogTitle, + nls.dialogIndication, + nls.pageCountIndication, + nls.dialogConfirm, + nls.dialogCancel, + nls.all + ]; + }, + _regApis: function(){ + var g = this.grid; + // New added APIs + g.currentPage = lang.hitch(this, this.currentPage); + g.nextPage = lang.hitch(this, this.nextPage); + g.prevPage = lang.hitch(this, this.prevPage); + g.firstPage = lang.hitch(this, this.firstPage); + g.lastPage = lang.hitch(this, this.lastPage); + g.currentPageSize = lang.hitch(this, this.currentPageSize); + g.showGotoPageButton = lang.hitch(this, this.showGotoPageButton); + g.getTotalRowCount = lang.hitch(this, this.getTotalRowCount); + g.getTotalPageNum = lang.hitch(this, this.getTotalPageNum); + + g.gotoPage = lang.hitch(this, this.gotoPage); + g.gotoFirstPage = lang.hitch(this, this.gotoFirstPage); + g.gotoLastPage = lang.hitch(this, this.gotoLastPage); + g.changePageSize = lang.hitch(this, this.changePageSize); + // Changed APIs + this._gridOriginalfuncs = [ + lang.hitch(g, g.scrollToRow), + lang.hitch(g, g._onNew), + lang.hitch(g, g.removeSelectedRows) + ]; + g.scrollToRow = lang.hitch(this, this.scrollToRow); + g.removeSelectedRows = lang.hitch(this, this.removeSelectedRows); + g._onNew = lang.hitch(this, this._onNew); + this.connect(g, "_onDelete", lang.hitch(this, this._onDelete)); + }, + _onNew: function(item, parentInfo){ + var totalPages = this.getTotalPageNum(); + if(((this._currentPage === totalPages || totalPages === 0) && this.grid.get('rowCount') < this._currentPageSize) || this._showAll){ + lang.hitch(this.grid, this._gridOriginalfuncs[1])(item, parentInfo); + this.forcePageStoreLayer.endIdx++; + } + this._maxSize++; + if(this._showAll){ + this._currentPageSize++; + } + if(this._showAll && this.grid.autoHeight){ + this.grid._refresh(); + }else{ + this._paginator._update(); + } + }, + _onDelete: function(){ + if(!this._multiRemoving){ + this.grid.resize(); + if(this._showAll){ + this.grid._refresh(); + } + } + if(this.grid.get('rowCount') === 0){ + this.prevPage(); + } + } +}); + +EnhancedGrid.registerPlugin(Pagination/*name:'pagination'*/); + +return Pagination; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js new file mode 100644 index 0000000..09ab390 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js @@ -0,0 +1,292 @@ +//>>built +define("dojox/grid/enhanced/plugins/Printer", [ + "dojo/_base/declare", + "dojo/_base/html", + "dojo/_base/Deferred", + "dojo/_base/lang", + "dojo/_base/sniff", + "dojo/_base/xhr", + "dojo/_base/array", + "dojo/query", + "dojo/DeferredList", + "../_Plugin", + "../../EnhancedGrid", + "./exporter/TableWriter" +], function(declare, html, Deferred, lang, has, xhr, array, query, DeferredList, _Plugin, EnhancedGrid, TableWriter){ + +var Printer = declare("dojox.grid.enhanced.plugins.Printer", _Plugin, { + // summary: + // Provide printGrid function to the grid. + // example: + // | dojo.require("dojox.grid.enhanced.plugins.Printer"); + // | dijit.byId("grid1").printGrid("my grid", //A title for the grid,optional + // | ["cssfile1.css","cssfile2.css"],//An array of css files to decorate the printed gird,optional + // | {table:"border='border'"} //tagName:"attrbuteList" pairs, optional, + // | //control the html tags in the generated html + // | ); + + // __printArgs: { + // title: String + // A title of the printed page can be specified. Optional. + // If given, it's shown in an <h1> tag at the top of the page. + // cssFiles: Array | String + // CSS file paths. Optional. + // Every row and column is given CSS classes, including: + // grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header, + // grid_col_{col-number}, grid_odd_col, grid_even_col + // {row_number} and {col-number} are both integers starting from 1. + // Row classes are for <thead> and <tbody> tags. + // Column classes are for <th> and <td> tags. + // Users can use these classes in the CSS files, but cannot define their own. + // writerArgs: Object (Association Array) + // Arguments for TableWriter. + // fetchArgs: object? + // Any arguments for store.fetch + // } + + // name: String + // Plugin name + name: "printer", + + constructor: function(grid){ + // summary: + // only newed by _Plugin + // inGrid: EnhancedGrid + // The grid to plug in to. + this.grid = grid; + this._mixinGrid(grid); + + //For print, we usually need the HTML instead of raw data. + grid.setExportFormatter(function(data, cell, rowIndex, rowItem){ + return cell.format(rowIndex, rowItem); + }); + }, + _mixinGrid: function(){ + var g = this.grid; + g.printGrid = lang.hitch(this, this.printGrid); + g.printSelected = lang.hitch(this, this.printSelected); + g.exportToHTML = lang.hitch(this, this.exportToHTML); + g.exportSelectedToHTML = lang.hitch(this, this.exportSelectedToHTML); + g.normalizePrintedGrid = lang.hitch(this, this.normalizeRowHeight); + }, + printGrid: function(args){ + // summary: + // Print all the data in the grid, using title as a title, + // decorating generated html by cssFiles, + // using tagName:"attrbuteList" pairs(writerArgs) to control html tags + // in the generated html string. + // tags: + // public + // args: __printArgs? + // Arguments for print. + this.exportToHTML(args, lang.hitch(this, this._print)); + }, + printSelected: function(args){ + // summary: + // Print selected data. All other features are the same as printGrid. + // For meaning of arguments see function *printGrid* + // tags: + // public + // args: __printArgs? + // Arguments for print. + this.exportSelectedToHTML(args, lang.hitch(this, this._print)); + }, + exportToHTML: function(args, onExported){ + // summary: + // Export to HTML string, but do NOT print. + // Users can use this to implement print preview. + // For meaning of the 1st-3rd arguments see function *printGrid*. + // tags: + // public + // args: __printArgs? + // Arguments for print. + // onExported: function(string) + // call back function + args = this._formalizeArgs(args); + var _this = this; + this.grid.exportGrid("table", args, function(str){ + _this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported); + }); + }, + exportSelectedToHTML: function(args, onExported){ + // summary: + // Export selected rows to HTML string, but do NOT print. + // Users can use this to implement print preview. + // For meaning of arguments see function *printGrid* + // tags: + // public + // args: __printArgs? + // Arguments for print. + args = this._formalizeArgs(args); + var _this = this; + this.grid.exportSelected("table", args.writerArgs, function(str){ + _this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported); + }); + }, + + _loadCSSFiles: function(cssFiles){ + var dl = array.map(cssFiles, function(cssFile){ + cssFile = lang.trim(cssFile); + if(cssFile.substring(cssFile.length - 4).toLowerCase() === '.css'){ + return xhr.get({ + url: cssFile + }); + }else{ + var d = new Deferred(); + d.callback(cssFile); + return d; + } + }); + return DeferredList.prototype.gatherResults(dl); + }, + _print: function(/* string */htmlStr){ + // summary: + // Do the print job. + // tags: + // private + // htmlStr: String + // The html content string to be printed. + // returns: + // undefined + var win, _this = this, + fillDoc = function(w){ + var doc = w.document; + doc.open(); + doc.write(htmlStr); + doc.close(); + _this.normalizeRowHeight(doc); + }; + if(!window.print){ + //We don't have a print facility. + return; + }else if(has("chrome") || has("opera")){ + //referred from dijit._editor.plugins.Print._print() + //In opera and chrome the iframe.contentWindow.print + //will also print the outside window. So we must create a + //stand-alone new window. + win = window.open("javascript: ''", "", + "status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0"); + fillDoc(win); + win.print(); + //Opera will stop at this point, showing the popping-out window. + //If the user closes the window, the following codes will not execute. + //If the user returns focus to the main window, the print function + // is executed, but still a no-op. + win.close(); + }else{ + //Put private things in deeper namespace to avoid poluting grid namespace. + var fn = this._printFrame, + dn = this.grid.domNode; + if(!fn){ + var frameId = dn.id + "_print_frame"; + if(!(fn = html.byId(frameId))){ + //create an iframe to store the grid data. + fn = html.create("iframe"); + fn.id = frameId; + fn.frameBorder = 0; + html.style(fn, { + width: "1px", + height: "1px", + position: "absolute", + right: 0, + bottom: 0, + border: "none", + overflow: "hidden" + }); + if(!has("ie")){ + html.style(fn, "visibility", "hidden"); + } + dn.appendChild(fn); + } + //Reuse this iframe + this._printFrame = fn; + } + win = fn.contentWindow; + fillDoc(win); + //IE requires the frame to be focused for print to work, and it's harmless for FF. + win.focus(); + win.print(); + } + }, + _wrapHTML: function(/* string */title, /* Array */cssFiles, /* string */body_content){ + // summary: + // Put title, cssFiles, and body_content together into an HTML string. + // tags: + // private + // title: String + // A title for the html page. + // cssFiles: Array + // css file pathes. + // body_content: String + // Content to print, not including <head></head> part and <html> tags + // returns: + // the wrapped HTML string ready for print + return this._loadCSSFiles(cssFiles).then(function(cssStrs){ + var i, sb = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">', + '<html ', html._isBodyLtr() ? '' : 'dir="rtl"', '><head><title>', title, + '</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>']; + for(i = 0; i < cssStrs.length; ++i){ + sb.push('<style type="text/css">', cssStrs[i], '</style>'); + } + sb.push('</head>'); + if(body_content.search(/^\s*<body/i) < 0){ + body_content = '<body>' + body_content + '</body>'; + } + sb.push(body_content, '</html>'); + return sb.join(''); + }); + }, + normalizeRowHeight: function(doc){ + var views = query(".grid_view", doc.body); + var headPerView = array.map(views, function(view){ + return query(".grid_header", view)[0]; + }); + var rowsPerView = array.map(views, function(view){ + return query(".grid_row", view); + }); + var rowCount = rowsPerView[0].length; + var i, v, h, maxHeight = 0; + for(v = views.length - 1; v >= 0; --v){ + h = html.contentBox(headPerView[v]).h; + if(h > maxHeight){ + maxHeight = h; + } + } + for(v = views.length - 1; v >= 0; --v){ + html.style(headPerView[v], "height", maxHeight + "px"); + } + for(i = 0; i < rowCount; ++i){ + maxHeight = 0; + for(v = views.length - 1; v >= 0; --v){ + h = html.contentBox(rowsPerView[v][i]).h; + if(h > maxHeight){ + maxHeight = h; + } + } + for(v = views.length - 1; v >= 0; --v){ + html.style(rowsPerView[v][i], "height", maxHeight + "px"); + } + } + var left = 0, ltr = html._isBodyLtr(); + for(v = 0; v < views.length; ++v){ + html.style(views[v], ltr ? "left" : "right", left + "px"); + left += html.marginBox(views[v]).w; + } + }, + _formalizeArgs: function(args){ + args = (args && lang.isObject(args)) ? args : {}; + args.title = String(args.title) || ""; + if(!lang.isArray(args.cssFiles)){ + args.cssFiles = [args.cssFiles]; + } + args.titleInBody = args.title ? ['<h1>', args.title, '</h1>'].join('') : ''; + return args; //Object + } +}); + +EnhancedGrid.registerPlugin(Printer/*name:'printer'*/, { + "dependency": ["exporter"] +}); + +return Printer; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js new file mode 100644 index 0000000..1c3bac3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js @@ -0,0 +1,506 @@ +//>>built +define("dojox/grid/enhanced/plugins/Rearrange", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "../../EnhancedGrid", + "../_Plugin", + "./_RowMapLayer" +], function(dojo, lang, declare, array, connect, EnhancedGrid, _Plugin, _RowMapLayer){ + +var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, { + // summary: + // Provides a set of method to re-arrange the structure of grid. + + // name: String + // plugin name + name: "rearrange", + + constructor: function(grid, args){ + this.grid = grid; + this.setArgs(args); + var rowMapLayer = new _RowMapLayer(grid); + dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer); + }, + setArgs: function(args){ + this.args = lang.mixin(this.args || {}, args || {}); + this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;}; + }, + destroy: function(){ + this.inherited(arguments); + this.grid.unwrap("rowmap"); + }, + onSetStore: function(store){ + this.grid.layer("rowmap").clearMapping(); + }, + _hasIdentity: function(points){ + var g = this.grid, s = g.store, cells = g.layout.cells; + if(s.getFeatures()["dojo.data.api.Identity"]){ + if(array.some(points, function(point){ + return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field; + })){ + return true; + } + } + return false; + }, + moveColumns: function(colsToMove, targetPos){ + // summary: + // Move a set of columns to a given position. + // tag: + // public + // colsToMove: Integer[] + // Array of column indexes. + // targetPos: Integer + // The target position + var g = this.grid, + layout = g.layout, + cells = layout.cells, + colIndex, i, delta = 0, + before = true, tmp = {}, mapping = {}; + colsToMove.sort(function(a, b){ + return a - b; + }); + for(i = 0; i < colsToMove.length; ++i){ + tmp[colsToMove[i]] = i; + if(colsToMove[i] < targetPos){ + ++delta; + } + } + var leftCount = 0, rightCount = 0; + var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos); + if(maxCol == cells.length){ + --maxCol; + } + var minCol = Math.min(colsToMove[0], targetPos); + for(i = minCol; i <= maxCol; ++i){ + var j = tmp[i]; + if(j >= 0){ + mapping[i] = targetPos - delta + j; + }else if(i < targetPos){ + mapping[i] = minCol + leftCount; + ++leftCount; + }else if(i >= targetPos){ + mapping[i] = targetPos + colsToMove.length - delta + rightCount; + ++rightCount; + } + } + //console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos); + delta = 0; + if(targetPos == cells.length){ + --targetPos; + before = false; + } + g._notRefreshSelection = true; + for(i = 0; i < colsToMove.length; ++i){ + colIndex = colsToMove[i]; + if(colIndex < targetPos){ + colIndex -= delta; + } + ++delta; + if(colIndex != targetPos){ + layout.moveColumn(cells[colIndex].view.idx, cells[targetPos].view.idx, colIndex, targetPos, before); + cells = layout.cells; + } + if(targetPos <= colIndex){ + ++targetPos; + } + } + delete g._notRefreshSelection; + connect.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping, colsToMove]); + }, + moveRows: function(rowsToMove, targetPos){ + // summary: + // Move a set of rows to a given position + // tag: + // public + // rowsToMove: Integer[] + // Array of row indexes. + // targetPos: Integer + // The target position + var g = this.grid, + mapping = {}, + preRowsToMove = [], + postRowsToMove = [], + len = rowsToMove.length, + i, r, k, arr, rowMap, lastPos; + + for(i = 0; i < len; ++i){ + r = rowsToMove[i]; + if(r >= targetPos){ + break; + } + preRowsToMove.push(r); + } + postRowsToMove = rowsToMove.slice(i); + + arr = preRowsToMove; + len = arr.length; + if(len){ + rowMap = {}; + array.forEach(arr, function(r){ + rowMap[r] = true; + }); + mapping[arr[0]] = targetPos - len; + for(k = 0, i = arr[k] + 1, lastPos = i - 1; i < targetPos; ++i){ + if(!rowMap[i]){ + mapping[i] = lastPos; + ++lastPos; + }else{ + ++k; + mapping[i] = targetPos - len + k; + } + } + } + arr = postRowsToMove; + len = arr.length; + if(len){ + rowMap = {}; + array.forEach(arr, function(r){ + rowMap[r] = true; + }); + mapping[arr[len - 1]] = targetPos + len - 1; + for(k = len - 1, i = arr[k] - 1, lastPos = i + 1; i >= targetPos; --i){ + if(!rowMap[i]){ + mapping[i] = lastPos; + --lastPos; + }else{ + --k; + mapping[i] = targetPos + k; + } + } + } + var tmpMapping = lang.clone(mapping); + g.layer("rowmap").setMapping(mapping); + g.forEachLayer(function(layer){ + if(layer.name() != "rowmap"){ + layer.invalidate(); + return true; + }else{ + return false; + } + }, false); + g.selection.selected = []; + g._noInternalMapping = true; + g._refresh(); + setTimeout(function(){ + connect.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping, rowsToMove]); + g._noInternalMapping = false; + }, 0); + }, + moveCells: function(cellsToMove, target){ + var g = this.grid, + s = g.store; + if(s.getFeatures()["dojo.data.api.Write"]){ + if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){ + //Same position, no need to move + return; + } + var cells = g.layout.cells, + cnt = cellsToMove.max.row - cellsToMove.min.row + 1, + r, c, tr, tc, + sources = [], targets = []; + for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){ + for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){ + while(cells[c] && cells[c].hidden){ + ++c; + } + while(cells[tc] && cells[tc].hidden){ + ++tc; + } + sources.push({ + "r": r, + "c": c + }); + targets.push({ + "r": tr, + "c": tc, + "v": cells[c].get(r, g._by_idx[r].item) + }); + } + } + if(this._hasIdentity(sources.concat(targets))){ + console.warn("Can not write to identity!"); + return; + } + array.forEach(sources, function(point){ + s.setValue(g._by_idx[point.r].item, cells[point.c].field, ""); + }); + array.forEach(targets, function(point){ + s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v); + }); + s.save({ + onComplete: function(){ + connect.publish("dojox/grid/rearrange/move/" + g.id, ["cell", { + "from": cellsToMove, + "to": target + }]); + } + }); + } + }, + copyCells: function(cellsToMove, target){ + var g = this.grid, + s = g.store; + if(s.getFeatures()["dojo.data.api.Write"]){ + if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){ + return; + } + var cells = g.layout.cells, + cnt = cellsToMove.max.row - cellsToMove.min.row + 1, + r, c, tr, tc, + targets = []; + for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){ + for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){ + while(cells[c] && cells[c].hidden){ + ++c; + } + while(cells[tc] && cells[tc].hidden){ + ++tc; + } + targets.push({ + "r": tr, + "c": tc, + "v": cells[c].get(r, g._by_idx[r].item) + }); + } + } + if(this._hasIdentity(targets)){ + console.warn("Can not write to identity!"); + return; + } + array.forEach(targets, function(point){ + s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v); + }); + s.save({ + onComplete: function(){ + setTimeout(function(){ + connect.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", { + "from": cellsToMove, + "to": target + }]); + }, 0); + } + }); + } + }, + changeCells: function(sourceGrid, cellsToMove, target){ + var g = this.grid, + s = g.store; + if(s.getFeatures()["dojo.data.api.Write"]){ + var srcg = sourceGrid, + cells = g.layout.cells, + srccells = srcg.layout.cells, + cnt = cellsToMove.max.row - cellsToMove.min.row + 1, + r, c, tr, tc, targets = []; + for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){ + for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){ + while(srccells[c] && srccells[c].hidden){ + ++c; + } + while(cells[tc] && cells[tc].hidden){ + ++tc; + } + targets.push({ + "r": tr, + "c": tc, + "v": srccells[c].get(r, srcg._by_idx[r].item) + }); + } + } + if(this._hasIdentity(targets)){ + console.warn("Can not write to identity!"); + return; + } + array.forEach(targets, function(point){ + s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v); + }); + s.save({ + onComplete: function(){ + connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]); + } + }); + } + }, + clearCells: function(cellsToClear){ + var g = this.grid, + s = g.store; + if(s.getFeatures()["dojo.data.api.Write"]){ + var cells = g.layout.cells, + cnt = cellsToClear.max.row - cellsToClear.min.row + 1, + r, c, targets = []; + for(r = cellsToClear.min.row; r <= cellsToClear.max.row; ++r){ + for(c = cellsToClear.min.col; c <= cellsToClear.max.col; ++c){ + while(cells[c] && cells[c].hidden){ + ++c; + } + targets.push({ + "r": r, + "c": c + }); + } + } + if(this._hasIdentity(targets)){ + console.warn("Can not write to identity!"); + return; + } + array.forEach(targets, function(point){ + s.setValue(g._by_idx[point.r].item, cells[point.c].field, ""); + }); + s.save({ + onComplete: function(){ + connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]); + } + }); + } + }, + insertRows: function(sourceGrid, rowsToMove, targetPos){ + try{ + var g = this.grid, + s = g.store, + rowCnt = g.rowCount, + mapping = {}, + obj = {idx: 0}, + newRows = [], i, + emptyTarget = targetPos < 0; + _this = this; + var len = rowsToMove.length; + if(emptyTarget){ + targetPos = 0; + }else{ + for(i = targetPos; i < g.rowCount; ++i){ + mapping[i] = i + len; + } + } + if(s.getFeatures()['dojo.data.api.Write']){ + if(sourceGrid){ + var srcg = sourceGrid, + srcs = srcg.store, + thisItem, attrs; + if(!emptyTarget){ + for(i = 0; !thisItem; ++i){ + thisItem = g._by_idx[i]; + } + attrs = s.getAttributes(thisItem.item); + }else{ + //If the target grid is empty, there is no way to retrieve attributes. + //So try to get attrs from grid.layout.cells[], but this might not be right + //since some fields may be missed(e.g ID fields), please use "setIdentifierForNewItem()" + //to add those missed fields + attrs = array.map(g.layout.cells, function(cell){ + return cell.field; + }); + } + var rowsToFetch = []; + array.forEach(rowsToMove, function(rowIndex, i){ + var item = {}; + var srcItem = srcg._by_idx[rowIndex]; + if(srcItem){ + array.forEach(attrs, function(attr){ + item[attr] = srcs.getValue(srcItem.item, attr); + }); + item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item; + try{ + s.newItem(item); + newRows.push(targetPos + i); + mapping[rowCnt + obj.idx] = targetPos + i; + ++obj.idx; + }catch(e){ + console.log("insertRows newItem:",e,item); + } + }else{ + rowsToFetch.push(rowIndex); + } + }); + }else if(rowsToMove.length && lang.isObject(rowsToMove[0])){ + array.forEach(rowsToMove, function(rowData, i){ + var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData; + try{ + s.newItem(item); + newRows.push(targetPos + i); + mapping[rowCnt + obj.idx] = targetPos + i; + ++obj.idx; + }catch(e){ + console.log("insertRows newItem:",e,item); + } + }); + }else{ + return; + } + g.layer("rowmap").setMapping(mapping); + s.save({ + onComplete: function(){ + g._refresh(); + setTimeout(function(){ + connect.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]); + }, 0); + } + }); + } + }catch(e){ + console.log("insertRows:",e); + } + }, + removeRows: function(rowsToRemove){ + var g = this.grid; + var s = g.store; + try{ + array.forEach(array.map(rowsToRemove, function(rowIndex){ + return g._by_idx[rowIndex]; + }), function(row){ + if(row){ + s.deleteItem(row.item); + } + }); + s.save({ + onComplete: function(){ + connect.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]); + } + }); + }catch(e){ + console.log("removeRows:",e); + } + }, + _getPageInfo: function(){ + // summary: + // Find pages that contain visible rows + // return: Object + // {topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]} + var scroller = this.grid.scroller, + topPage = scroller.page, + bottomPage = scroller.page, + firstVisibleRow = scroller.firstVisibleRow, + lastVisibleRow = scroller.lastVisibleRow, + rowsPerPage = scroller.rowsPerPage, + renderedPages = scroller.pageNodes[0], + topRow, bottomRow, matched, + invalidPages = []; + + array.forEach(renderedPages, function(page, pageIndex){ + if(!page){ return; } + matched = false; + topRow = pageIndex * rowsPerPage; + bottomRow = (pageIndex + 1) * rowsPerPage - 1; + if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){ + topPage = pageIndex; + matched = true; + } + if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){ + bottomPage = pageIndex; + matched = true; + } + if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){ + invalidPages.push(pageIndex); + } + }); + return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages}; + } +}); + +EnhancedGrid.registerPlugin(Rearrange/*name:'rearrange'*/); + +return Rearrange; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js new file mode 100644 index 0000000..2c0284c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js @@ -0,0 +1,123 @@ +//>>built +define("dojox/grid/enhanced/plugins/Search", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/data/util/filter", + "../../EnhancedGrid", + "../_Plugin" +], function(dojo, lang, declare, array, dFilter, EnhancedGrid, _Plugin){ + +var Search = declare("dojox.grid.enhanced.plugins.Search", _Plugin, { + // summary: + // Search the grid using wildcard string or Regular Expression. + + // name: String + // plugin name + name: "search", + + constructor: function(grid, args){ + this.grid = grid; + args = (args && lang.isObject(args)) ? args : {}; + this._cacheSize = args.cacheSize || -1; + grid.searchRow = lang.hitch(this, "searchRow"); + }, + searchRow: function(/* Object|RegExp|String */searchArgs, /* function(Integer, item) */onSearched){ + if(!lang.isFunction(onSearched)){ return; } + if(lang.isString(searchArgs)){ + searchArgs = dFilter.patternToRegExp(searchArgs); + } + var isGlobal = false; + if(searchArgs instanceof RegExp){ + isGlobal = true; + }else if(lang.isObject(searchArgs)){ + var isEmpty = true; + for(var field in searchArgs){ + if(lang.isString(searchArgs[field])){ + searchArgs[field] = dFilter.patternToRegExp(searchArgs[field]); + } + isEmpty = false; + } + if(isEmpty){ return; } + }else{ + return; + } + this._search(searchArgs, 0, onSearched, isGlobal); + }, + _search: function(/* Object|RegExp */searchArgs, /* Integer */start, /* function(Integer, item) */onSearched, /* Boolean */isGlobal){ + var _this = this, + cnt = this._cacheSize, + args = { + start: start, + query: this.grid.query, + sort: this.grid.getSortProps(), + queryOptions: this.grid.queryOptions, + onBegin: function(size){ + _this._storeSize = size; + }, + onComplete: function(items){ + if(!array.some(items, function(item, i){ + if(_this._checkRow(item, searchArgs, isGlobal)){ + onSearched(start + i, item); + return true; + } + return false; + })){ + if(cnt > 0 && start + cnt < _this._storeSize){ + _this._search(searchArgs, start + cnt, onSearched, isGlobal); + }else{ + onSearched(-1, null); + } + } + } + }; + if(cnt > 0){ + args.count = cnt; + } + this.grid._storeLayerFetch(args); + }, + _checkRow: function(/* store item */item, /* Object|RegExp */searchArgs, /* Boolean */isGlobal){ + var g = this.grid, s = g.store, i, field, + cells = array.filter(g.layout.cells, function(cell){ + return !cell.hidden; + }); + if(isGlobal){ + return array.some(cells, function(cell){ + try{ + if(cell.field){ + return String(s.getValue(item, cell.field)).search(searchArgs) >= 0; + } + }catch(e){ + console.log("Search._checkRow() error: ", e); + } + return false; + }); + }else{ + for(field in searchArgs){ + if(searchArgs[field] instanceof RegExp){ + for(i = cells.length - 1; i >= 0; --i){ + if(cells[i].field == field){ + try{ + if(String(s.getValue(item, field)).search(searchArgs[field]) < 0){ + return false; + } + break; + }catch(e){ + return false; + } + } + } + if(i < 0){ return false; } + } + } + return true; + } + } +}); + +EnhancedGrid.registerPlugin(Search/*name:'search'*/); + +return Search; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js new file mode 100644 index 0000000..c9e2574 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js @@ -0,0 +1,1477 @@ +//>>built +define("dojox/grid/enhanced/plugins/Selector", [ + "dojo/_base/kernel", + "dojo/_base/lang", + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/event", + "dojo/keys", + "dojo/query", + "dojo/_base/html", + "dojo/_base/window", + "dijit/focus", + "../../_RowSelector", + "../_Plugin", + "../../EnhancedGrid", + "../../cells/_base", + "./AutoScroll" +], function(dojo, lang, declare, array, event, keys, query, html, win, dijitFocus, _RowSelector, _Plugin, EnhancedGrid){ + +/*===== +dojo.declare("__SelectItem", null,{ + // summary: + // An abstract representation of an item. +}); +dojo.declare("__SelectCellItem", __SelectItem,{ + // summary: + // An abstract representation of a cell. + + // row: Integer + // Row index of this cell + row: 0, + + // col: Integer + // Column index of this cell + col: 0 +}); +dojo.declare("__SelectRowItem", __SelectItem,{ + // summary: + // An abstract representation of a row. + + // row: Integer + // Row index of this row + row: 0, + + // except: Integer[] + // An array of column indexes of all the unselected cells in this row. + except: [] +}); +dojo.declare("__SelectColItem", __SelectItem,{ + // summary: + // An abstract representation of a column. + + // col: Integer + // Column index of this column + col: 0, + + // except: Integer[] + // An array of row indexes of all the unselected cells in this column. + except: [] +}); +=====*/ + +var DISABLED = 0, SINGLE = 1, MULTI = 2, + _theOther = { col: "row", row: "col" }, + _inRange = function(type, value, start, end, halfClose){ + if(type !== "cell"){ + value = value[type]; + start = start[type]; + end = end[type]; + if(typeof value !== "number" || typeof start !== "number" || typeof end !== "number"){ + return false; + } + return halfClose ? ((value >= start && value < end) || (value > end && value <= start)) + : ((value >= start && value <= end) || (value >= end && value <= start)); + }else{ + return _inRange("col", value, start, end, halfClose) && _inRange("row", value, start, end, halfClose); + } + }, + _isEqual = function(type, v1, v2){ + try{ + if(v1 && v2){ + switch(type){ + case "col": case "row": + return v1[type] == v2[type] && typeof v1[type] == "number" && + !(_theOther[type] in v1) && !(_theOther[type] in v2); + case "cell": + return v1.col == v2.col && v1.row == v2.row && typeof v1.col == "number" && typeof v1.row == "number"; + } + } + }catch(e){} + return false; + }, + _stopEvent = function(evt){ + try{ + if(evt && evt.preventDefault){ + event.stop(evt); + } + }catch(e){} + }, + _createItem = function(type, rowIndex, colIndex){ + switch(type){ + case "col": + return { + "col": typeof colIndex == "undefined" ? rowIndex : colIndex, + "except": [] + }; + case "row": + return { + "row": rowIndex, + "except": [] + }; + case "cell": + return { + "row": rowIndex, + "col": colIndex + }; + } + return null; + }; +var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, { + // summary: + // Provides standard extended selection for grid. + // Supports mouse/keyboard selection, multi-selection, and de-selection. + // Acceptable plugin parameters: + // The whole plugin parameter object is a config object passed to the setupConfig function. + // + // Acceptable cell parameters defined in layout: + // 1. notselectable: boolean + // Whether this column is (and all the cells in it are) selectable. + + // name: String + // plugin name + name: "selector", + + // noClear: Boolean + // Not to clear rows selected by IndirectSelection. +/* + // _config: null, + // _enabled: true, + // _selecting: { + // row: false, + // col: false, + // cell: false + // }, + // _selected: { + // row: [], + // col: [], + // cell: [] + // }, + // _startPoint: {}, + // _currentPoint: {}, + // _lastAnchorPoint: {}, + // _lastEndPoint: {}, + // _lastSelectedAnchorPoint: {}, + // _lastSelectedEndPoint: {}, + // _keyboardSelect: { + // row: 0, + // col: 0, + // cell: 0 + // }, + // _curType: null, + // _lastType: null, + // _usingKeyboard: false, + // _toSelect: true, +*/ + + constructor: function(grid, args){ + this.grid = grid; + this._config = { + row: MULTI, + col: MULTI, + cell: MULTI + }; + this.noClear = args && args.noClear; + this.setupConfig(args); + if(grid.selectionMode === "single"){ + this._config.row = SINGLE; + } + this._enabled = true; + this._selecting = {}; + this._selected = { + "col": [], + "row": [], + "cell": [] + }; + this._startPoint = {}; + this._currentPoint = {}; + this._lastAnchorPoint = {}; + this._lastEndPoint = {}; + this._lastSelectedAnchorPoint = {}; + this._lastSelectedEndPoint = {}; + this._keyboardSelect = {}; + this._lastType = null; + this._selectedRowModified = {}; + this._hacks(); + this._initEvents(); + this._initAreas(); + this._mixinGrid(); + }, + destroy: function(){ + this.inherited(arguments); + }, + //------------public-------------------- + setupConfig: function(config){ + // summary: + // Set selection mode for row/col/cell. + // config: Object + // An object with the following structure (all properties are optional): + // { + // //Default is "multi", all other values are same as "multi". + // row: false|"disabled"|"single", + // col: false|"disabled"|"single", + // cell: false|"disabled"|"single" + // } + if(!config || !lang.isObject(config)){ + return; + } + var types = ["row", "col", "cell"]; + for(var type in config){ + if(array.indexOf(types, type) >= 0){ + if(!config[type] || config[type] == "disabled"){ + this._config[type] = DISABLED; + }else if(config[type] == "single"){ + this._config[type] = SINGLE; + }else{ + this._config[type] = MULTI; + } + } + } + + //Have to set mode to default grid selection. + var mode = ["none","single","extended"][this._config.row]; + this.grid.selection.setMode(mode); + }, + isSelected: function(type, rowIndex, colIndex){ + // summary: + // Check whether a location (a cell, a column or a row) is selected. + // tag: + // public + // type: String + // "row" or "col" or "cell" + // rowIndex: Integer + // If type is "row" or "cell", this is the row index. + // If type if "col", this is the column index. + // colIndex: Integer? + // Only valid when type is "cell" + // return: Boolean + // true if selected, false if not. If cell is covered by a selected column, it's selected. + return this._isSelected(type, _createItem(type, rowIndex, colIndex)); + }, + toggleSelect: function(type, rowIndex, colIndex){ + this._startSelect(type, _createItem(type, rowIndex, colIndex), this._config[type] === MULTI, false, false, !this.isSelected(type, rowIndex, colIndex)); + this._endSelect(type); + }, + select: function(type, rowIndex, colIndex){ + // summary: + // Select a location (a cell, a column or a row). + // tag: + // public + // type: String + // "row" or "col" or "cell" + // rowIndex: Integer + // If type is "row" or "cell", this is the row index. + // If type if "col", this is the column index. + // colIndex: Integer? + // Only valid when type is "cell" + if(!this.isSelected(type, rowIndex, colIndex)){ + this.toggleSelect(type, rowIndex, colIndex); + } + }, + deselect: function(type, rowIndex, colIndex){ + if(this.isSelected(type, rowIndex, colIndex)){ + this.toggleSelect(type, rowIndex, colIndex); + } + }, + selectRange: function(type, start, end, toSelect){ + // summary: + // Select a continuous range (a block of cells, a set of continuous columns or rows) + // tag: + // public + // type: String + // "row" or "col" or "cell" + // start: Integer | Object + // If type is "row" or "col", this is the index of the starting row or column. + // If type if "cell", this is the left-top cell of the range. + // end: Integer | Object + // If type is "row" or "col", this is the index of the ending row or column. + // If type if "cell", this is the right-bottom cell of the range. + this.grid._selectingRange = true; + var startPoint = type == "cell" ? _createItem(type, start.row, start.col) : _createItem(type, start), + endPoint = type == "cell" ? _createItem(type, end.row, end.col) : _createItem(type, end); + this._startSelect(type, startPoint, false, false, false, toSelect); + this._highlight(type, endPoint, toSelect === undefined ? true : toSelect); + this._endSelect(type); + this.grid._selectingRange = false; + }, + clear: function(type){ + // summary: + // Clear all selections. + // tag: + // public + // type: String? + // "row" or "col" or "cell". If omitted, clear all. + this._clearSelection(type || "all"); + }, + isSelecting: function(type){ + // summary: + // Check whether the user is currently selecting something. + // tag: + // public + // type: String + // "row" or "col" or "cell" + // return: Boolean + // true if is selection, false otherwise. + if(typeof type == "undefined"){ + return this._selecting.col || this._selecting.row || this._selecting.cell; + } + return this._selecting[type]; + }, + selectEnabled: function(toEnable){ + // summary: + // Turn on/off this selection functionality if *toEnable* is provided. + // Check whether this selection functionality is enabled if nothing is passed in. + // tag: + // public + // toEnable: Boolean? + // To enable or not. Optional. + // return: Boolean | undefined + // Enabled or not. + if(typeof toEnable != "undefined" && !this.isSelecting()){ + this._enabled = !!toEnable; + } + return this._enabled; + }, + getSelected: function(type, includeExceptions){ + // summary: + // Get an array of selected locations. + // tag: + // public + // type: String + // "row" or "col" or "cell" + // includeExceptions: Boolean + // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned. + // return: __SelectItem[] + switch(type){ + case "cell": + return array.map(this._selected[type], function(item){ return item; }); + case "col": case "row": + return array.map(includeExceptions ? this._selected[type] + : array.filter(this._selected[type], function(item){ + return item.except.length === 0; + }), function(item){ + return includeExceptions ? item : item[type]; + }); + } + return []; + }, + getSelectedCount: function(type, includeExceptions){ + // summary: + // Get the number of selected items. + // tag: + // public + // type: String + // "row" or "col" or "cell" + // includeExceptions: Boolean + // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned. + // return: Integer + // The number of selected items. + switch(type){ + case "cell": + return this._selected[type].length; + case "col": case "row": + return (includeExceptions ? this._selected[type] + : array.filter(this._selected[type], function(item){ + return item.except.length === 0; + })).length; + } + return 0; + }, + getSelectedType: function(){ + // summary: + // Get the type of selected items. + // tag: + // public + // return: String + // "row" or "col" or "cell", or any mix of these (separator is | ). + var s = this._selected; + return ["", "cell", "row", "row|cell", + "col", "col|cell", "col|row", "col|row|cell" + ][(!!s.cell.length) | (!!s.row.length << 1) | (!!s.col.length << 2)]; + }, + getLastSelectedRange: function(type){ + // summary: + // Get last selected range of the given type. + // tag: + // public + // return: Object + // {start: __SelectItem, end: __SelectItem} + // return null if nothing is selected. + return this._lastAnchorPoint[type] ? { + "start": this._lastAnchorPoint[type], + "end": this._lastEndPoint[type] + } : null; + }, + + //--------------------------private---------------------------- + _hacks: function(){ + // summary: + // Complete the event system of grid, hack some grid functions to prevent default behavior. + var g = this.grid; + var doContentMouseUp = function(e){ + if(e.cellNode){ + g.onMouseUp(e); + } + g.onMouseUpRow(e); + }; + var mouseUp = lang.hitch(g, "onMouseUp"); + var mouseDown = lang.hitch(g, "onMouseDown"); + var doRowSelectorFocus = function(e){ + e.cellNode.style.border = "solid 1px"; + }; + array.forEach(g.views.views, function(view){ + view.content.domouseup = doContentMouseUp; + view.header.domouseup = mouseUp; + if(view.declaredClass == "dojox.grid._RowSelector"){ + view.domousedown = mouseDown; + view.domouseup = mouseUp; + view.dofocus = doRowSelectorFocus; + } + }); + //Disable default selection. + g.selection.clickSelect = function(){}; + + this._oldDeselectAll = g.selection.deselectAll; + var _this = this; + g.selection.selectRange = function(from, to){ + _this.selectRange("row", from, to, true); + if(g.selection.preserver){ + g.selection.preserver._updateMapping(true, true, false, from, to); + } + g.selection.onChanged(); + }; + g.selection.deselectRange = function(from, to){ + _this.selectRange("row", from, to, false); + if(g.selection.preserver){ + g.selection.preserver._updateMapping(true, false, false, from, to); + } + g.selection.onChanged(); + }; + g.selection.deselectAll = function(){ + g._selectingRange = true; + _this._oldDeselectAll.apply(g.selection, arguments); + _this._clearSelection("all"); + g._selectingRange = false; + if(g.selection.preserver){ + g.selection.preserver._updateMapping(true, false, true); + } + g.selection.onChanged(); + }; + + var rowSelector = g.views.views[0]; + //The default function re-write the whole className, so can not insert any other classes. + if(rowSelector instanceof _RowSelector){ + rowSelector.doStyleRowNode = function(inRowIndex, inRowNode){ + html.removeClass(inRowNode, "dojoxGridRow"); + html.addClass(inRowNode, "dojoxGridRowbar"); + html.addClass(inRowNode, "dojoxGridNonNormalizedCell"); + html.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex)); + html.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex)); + }; + } + this.connect(g, "updateRow", function(rowIndex){ + array.forEach(g.layout.cells, function(cell){ + if(this.isSelected("cell", rowIndex, cell.index)){ + this._highlightNode(cell.getNode(rowIndex), true); + } + }, this); + }); + }, + _mixinGrid: function(){ + // summary: + // Expose events to grid. + var g = this.grid; + g.setupSelectorConfig = lang.hitch(this, this.setupConfig); + g.onStartSelect = function(){}; + g.onEndSelect = function(){}; + g.onStartDeselect = function(){}; + g.onEndDeselect = function(){}; + g.onSelectCleared = function(){}; + }, + _initEvents: function(){ + // summary: + // Connect events, create event handlers. + var g = this.grid, + _this = this, + dp = lang.partial, + starter = function(type, e){ + if(type === "row"){ + _this._isUsingRowSelector = true; + } + //only left mouse button can select. + if(_this.selectEnabled() && _this._config[type] && e.button != 2){ + if(_this._keyboardSelect.col || _this._keyboardSelect.row || _this._keyboardSelect.cell){ + _this._endSelect("all"); + _this._keyboardSelect.col = _this._keyboardSelect.row = _this._keyboardSelect.cell = 0; + } + if(_this._usingKeyboard){ + _this._usingKeyboard = false; + } + var target = _createItem(type, e.rowIndex, e.cell && e.cell.index); + _this._startSelect(type, target, e.ctrlKey, e.shiftKey); + } + }, + ender = lang.hitch(this, "_endSelect"); + this.connect(g, "onHeaderCellMouseDown", dp(starter, "col")); + this.connect(g, "onHeaderCellMouseUp", dp(ender, "col")); + + this.connect(g, "onRowSelectorMouseDown", dp(starter, "row")); + this.connect(g, "onRowSelectorMouseUp", dp(ender, "row")); + + this.connect(g, "onCellMouseDown", function(e){ + if(e.cell && e.cell.isRowSelector){ return; } + if(g.singleClickEdit){ + _this._singleClickEdit = true; + g.singleClickEdit = false; + } + starter(_this._config["cell"] == DISABLED ? "row" : "cell", e); + }); + this.connect(g, "onCellMouseUp", function(e){ + if(_this._singleClickEdit){ + delete _this._singleClickEdit; + g.singleClickEdit = true; + } + ender("all", e); + }); + + this.connect(g, "onCellMouseOver", function(e){ + if(_this._curType != "row" && _this._selecting[_this._curType] && _this._config[_this._curType] == MULTI){ + _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect); + if(!_this._keyboardSelect.cell){ + _this._highlight("cell", _createItem("cell", e.rowIndex, e.cell.index), _this._toSelect); + } + } + }); + this.connect(g, "onHeaderCellMouseOver", function(e){ + if(_this._selecting.col && _this._config.col == MULTI){ + _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect); + } + }); + this.connect(g, "onRowMouseOver", function(e){ + if(_this._selecting.row && _this._config.row == MULTI){ + _this._highlight("row", _createItem("row", e.rowIndex), _this._toSelect); + } + }); + + //When row order has changed in a unpredictable way (sorted or filtered), map the new rowindex. + this.connect(g, "onSelectedById", "_onSelectedById"); + + //When the grid refreshes, all those selected should still appear selected. + this.connect(g, "_onFetchComplete", function(){ + //console.debug("refresh after buildPage:", g._notRefreshSelection); + if(!g._notRefreshSelection){ + this._refreshSelected(true); + } + }); + + //Small scroll might not refresh the grid. + this.connect(g.scroller, "buildPage", function(){ + //console.debug("refresh after buildPage:", g._notRefreshSelection); + if(!g._notRefreshSelection){ + this._refreshSelected(true); + } + }); + + //Whenever the mouse is up, end selecting. + this.connect(win.doc, "onmouseup", dp(ender, "all")); + + //If autoscroll is enabled, connect to it. + this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){ + var selectCell = _this._selecting.cell, + type, current, dir = isForward ? 1 : -1; + if(isVertical && (selectCell || _this._selecting.row)){ + type = selectCell ? "cell" : "row"; + current = _this._currentPoint[type]; + _this._highlight(type, _createItem(type, current.row + dir, current.col), _this._toSelect); + }else if(!isVertical && (selectCell || _this._selecting.col)){ + type = selectCell ? "cell" : "col"; + current = _this._currentPoint[type]; + _this._highlight(type, _createItem(type, current.row, target), _this._toSelect); + } + }); + //If the grid is changed, selection should be consistent. + this.subscribe("dojox/grid/rearrange/move/" + g.id, "_onInternalRearrange"); + this.subscribe("dojox/grid/rearrange/copy/" + g.id, "_onInternalRearrange"); + this.subscribe("dojox/grid/rearrange/change/" + g.id, "_onExternalChange"); + this.subscribe("dojox/grid/rearrange/insert/" + g.id, "_onExternalChange"); + this.subscribe("dojox/grid/rearrange/remove/" + g.id, "clear"); + + //have to also select when the grid's default select is used. + this.connect(g, "onSelected", function(rowIndex){ + if(this._selectedRowModified && this._isUsingRowSelector){ + delete this._selectedRowModified; + }else if(!this.grid._selectingRange){ + this.select("row", rowIndex); + } + }); + this.connect(g, "onDeselected", function(rowIndex){ + if(this._selectedRowModified && this._isUsingRowSelector){ + delete this._selectedRowModified; + }else if(!this.grid._selectingRange){ + this.deselect("row", rowIndex); + } + }); + }, + _onSelectedById: function(id, newIndex, isSelected){ + if(this.grid._noInternalMapping){ + return; + } + var pointSet = [this._lastAnchorPoint.row, this._lastEndPoint.row, + this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row]; + pointSet = pointSet.concat(this._selected.row); + var found = false; + array.forEach(pointSet, function(item){ + if(item){ + if(item.id === id){ + found = true; + item.row = newIndex; + }else if(item.row === newIndex && item.id){ + item.row = -1; + } + } + }); + if(!found && isSelected){ + array.some(this._selected.row, function(item){ + if(item && !item.id && !item.except.length){ + item.id = id; + item.row = newIndex; + return true; + } + return false; + }); + } + found = false; + pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell, + this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]; + pointSet = pointSet.concat(this._selected.cell); + array.forEach(pointSet, function(item){ + if(item){ + if(item.id === id){ + found = true; + item.row = newIndex; + }else if(item.row === newIndex && item.id){ + item.row = -1; + } + } + }); + }, + onSetStore: function(){ + this._clearSelection("all"); + }, + _onInternalRearrange: function(type, mapping){ + try{ + //The column can not refresh it self! + this._refresh("col", false); + + array.forEach(this._selected.row, function(item){ + array.forEach(this.grid.layout.cells, function(cell){ + this._highlightNode(cell.getNode(item.row), false); + }, this); + }, this); + //The rowbar must be cleaned manually + query(".dojoxGridRowSelectorSelected").forEach(function(node){ + html.removeClass(node, "dojoxGridRowSelectorSelected"); + html.removeClass(node, "dojoxGridRowSelectorSelectedUp"); + html.removeClass(node, "dojoxGridRowSelectorSelectedDown"); + }); + + var cleanUp = function(item){ + if(item){ + delete item.converted; + } + }, + pointSet = [this._lastAnchorPoint[type], this._lastEndPoint[type], + this._lastSelectedAnchorPoint[type], this._lastSelectedEndPoint[type]]; + + if(type === "cell"){ + this.selectRange("cell", mapping.to.min, mapping.to.max); + var cells = this.grid.layout.cells; + array.forEach(pointSet, function(item){ + if(item.converted){ return; } + for(var r = mapping.from.min.row, tr = mapping.to.min.row; r <= mapping.from.max.row; ++r, ++tr){ + for(var c = mapping.from.min.col, tc = mapping.to.min.col; c <= mapping.from.max.col; ++c, ++tc){ + while(cells[c].hidden){ ++c; } + while(cells[tc].hidden){ ++tc; } + if(item.row == r && item.col == c){ + //console.log('mapping found: (', item.row, ",",item.col,") to (", tr, ",", tc,")"); + item.row = tr; + item.col = tc; + item.converted = true; + return; + } + } + } + }); + }else{ + pointSet = this._selected.cell.concat(this._selected[type]).concat(pointSet).concat( + [this._lastAnchorPoint.cell, this._lastEndPoint.cell, + this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]); + array.forEach(pointSet, function(item){ + if(item && !item.converted){ + var from = item[type]; + if(from in mapping){ + item[type] = mapping[from]; + } + item.converted = true; + } + }); + array.forEach(this._selected[_theOther[type]], function(item){ + for(var i = 0, len = item.except.length; i < len; ++i){ + var from = item.except[i]; + if(from in mapping){ + item.except[i] = mapping[from]; + } + } + }); + } + + array.forEach(pointSet, cleanUp); + + this._refreshSelected(true); + this._focusPoint(type, this._lastEndPoint); + }catch(e){ + console.warn("Selector._onInternalRearrange() error",e); + } + }, + _onExternalChange: function(type, target){ + var start = type == "cell" ? target.min : target[0], + end = type == "cell" ? target.max : target[target.length - 1]; + this.selectRange(type, start, end); + }, + _refresh: function(type, toHighlight){ + if(!this._keyboardSelect[type]){ + array.forEach(this._selected[type], function(item){ + this._highlightSingle(type, toHighlight, item, undefined, true); + }, this); + } + }, + _refreshSelected: function(){ + this._refresh("col", true); + this._refresh("row", true); + this._refresh("cell", true); + }, + _initAreas: function(){ + var g = this.grid, f = g.focus, _this = this, + keyboardSelectReady = 1, duringKeyboardSelect = 2, + onmove = function(type, createNewEnd, rowStep, colStep, evt){ + //Keyboard swipe selection is SHIFT + Direction Keys. + var ks = _this._keyboardSelect; + //Tricky, rely on valid status not being 0. + if(evt.shiftKey && ks[type]){ + if(ks[type] === keyboardSelectReady){ + if(type === "cell"){ + var item = _this._lastEndPoint[type]; + if(f.cell != g.layout.cells[item.col + colStep] || f.rowIndex != item.row + rowStep){ + ks[type] = 0; + return; + } + } + //If selecting is not started, start it + _this._startSelect(type, _this._lastAnchorPoint[type], true, false, true); + _this._highlight(type, _this._lastEndPoint[type], _this._toSelect); + ks[type] = duringKeyboardSelect; + } + //Highlight to the new end point. + var newEnd = createNewEnd(type, rowStep, colStep, evt); + if(_this._isValid(type, newEnd, g)){ + _this._highlight(type, newEnd, _this._toSelect); + } + _stopEvent(evt); + } + }, + onkeydown = function(type, getTarget, evt, isBubble){ + if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){ + switch(evt.keyCode){ + case keys.SPACE: + //Keyboard single point selection is SPACE. + _this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey); + _this._endSelect(type); + break; + case keys.SHIFT: + //Keyboard swipe selection starts with SHIFT. + if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){ + //End last selection if any. + _this._endSelect(type); + _this._keyboardSelect[type] = keyboardSelectReady; + _this._usingKeyboard = true; + } + } + } + }, + onkeyup = function(type, evt, isBubble){ + if(isBubble && evt.keyCode == keys.SHIFT && _this._keyboardSelect[type]){ + _this._endSelect(type); + _this._keyboardSelect[type] = 0; + } + }; + //TODO: this area "rowHeader" should be put outside, same level as header/content. + if(g.views.views[0] instanceof _RowSelector){ + this._lastFocusedRowBarIdx = 0; + f.addArea({ + name:"rowHeader", + onFocus: function(evt, step){ + var view = g.views.views[0]; + if(view instanceof _RowSelector){ + var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0); + if(rowBarNode){ + html.toggleClass(rowBarNode, f.focusClass, false); + } + //evt might not be real event, it may be a mock object instead. + if(evt && "rowIndex" in evt){ + if(evt.rowIndex >= 0){ + _this._lastFocusedRowBarIdx = evt.rowIndex; + }else if(!_this._lastFocusedRowBarIdx){ + _this._lastFocusedRowBarIdx = 0; + } + } + rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0); + if(rowBarNode){ + dijitFocus.focus(rowBarNode); + html.toggleClass(rowBarNode, f.focusClass, true); + } + f.rowIndex = _this._lastFocusedRowBarIdx; + _stopEvent(evt); + return true; + } + return false; + }, + onBlur: function(evt, step){ + var view = g.views.views[0]; + if(view instanceof _RowSelector){ + var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0); + if(rowBarNode){ + html.toggleClass(rowBarNode, f.focusClass, false); + } + _stopEvent(evt); + } + return true; + }, + onMove: function(rowStep, colStep, evt){ + var view = g.views.views[0]; + if(rowStep && view instanceof _RowSelector){ + var next = _this._lastFocusedRowBarIdx + rowStep; + if(next >= 0 && next < g.rowCount){ + //TODO: these logic require a better Scroller. + _stopEvent(evt); + var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0); + html.toggleClass(rowBarNode, f.focusClass, false); + //If the row is not fetched, fetch it. + var sc = g.scroller; + var lastPageRow = sc.getLastPageRow(sc.page); + var rc = g.rowCount - 1, row = Math.min(rc, next); + if(next > lastPageRow){ + g.setScrollTop(g.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(_this._lastFocusedRowBarIdx)); + } + //Now we have fetched the row. + rowBarNode = view.getCellNode(next, 0); + dijitFocus.focus(rowBarNode); + html.toggleClass(rowBarNode, f.focusClass, true); + _this._lastFocusedRowBarIdx = next; + //If the row is out of view, scroll to it. + f.cell = rowBarNode; + f.cell.view = view; + f.cell.getNode = function(index){ + return f.cell; + }; + f.rowIndex = _this._lastFocusedRowBarIdx; + f.scrollIntoView(); + f.cell = null; + } + } + } + }); + f.placeArea("rowHeader","before","content"); + } + //Support keyboard selection. + f.addArea({ + name:"cellselect", + onMove: lang.partial(onmove, "cell", function(type, rowStep, colStep, evt){ + var current = _this._currentPoint[type]; + return _createItem("cell", current.row + rowStep, current.col + colStep); + }), + onKeyDown: lang.partial(onkeydown, "cell", function(){ + return _createItem("cell", f.rowIndex, f.cell.index); + }), + onKeyUp: lang.partial(onkeyup, "cell") + }); + f.placeArea("cellselect","below","content"); + f.addArea({ + name:"colselect", + onMove: lang.partial(onmove, "col", function(type, rowStep, colStep, evt){ + var current = _this._currentPoint[type]; + return _createItem("col", current.col + colStep); + }), + onKeyDown: lang.partial(onkeydown, "col", function(){ + return _createItem("col", f.getHeaderIndex()); + }), + onKeyUp: lang.partial(onkeyup, "col") + }); + f.placeArea("colselect","below","header"); + f.addArea({ + name:"rowselect", + onMove: lang.partial(onmove, "row", function(type, rowStep, colStep, evt){ + return _createItem("row", f.rowIndex); + }), + onKeyDown: lang.partial(onkeydown, "row", function(){ + return _createItem("row", f.rowIndex); + }), + onKeyUp: lang.partial(onkeyup, "row") + }); + f.placeArea("rowselect","below","rowHeader"); + }, + _clearSelection: function(type, reservedItem){ + // summary: + // Clear selection for given type and fire events, but retain the highlight for *reservedItem*, + // thus avoid "flashing". + // tag: + // private + // type: String + // "row", "col", or "cell + // reservedItem: __SelectItem + // The item to retain highlight. + if(type == "all"){ + this._clearSelection("cell", reservedItem); + this._clearSelection("col", reservedItem); + this._clearSelection("row", reservedItem); + return; + } + this._isUsingRowSelector = true; + array.forEach(this._selected[type], function(item){ + if(!_isEqual(type, reservedItem, item)){ + this._highlightSingle(type, false, item); + } + }, this); + this._blurPoint(type, this._currentPoint); + this._selecting[type] = false; + this._startPoint[type] = this._currentPoint[type] = null; + this._selected[type] = []; + + //Have to also deselect default grid selection. + if(type == "row" && !this.grid._selectingRange){ + this._oldDeselectAll.call(this.grid.selection); + this.grid.selection._selectedById = {}; + } + + //Fire events. + this.grid.onEndDeselect(type, null, null, this._selected); + this.grid.onSelectCleared(type); + }, + _startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){ + // summary: + // Start selection, setup start point and current point, fire events. + // tag: + // private + // type: String + // "row", "col", or "cell" + // extending: Boolean + // Whether this is a multi selection + // isRange: Boolean + // Whether this is a range selection (i.e. select from the last end point to this point) + // start: __SelectItem + // The start point + // mandatarySelect: Boolean + // If true, toSelect will be same as the original selection status. + if(!this._isValid(type, start)){ + return; + } + var lastIsSelected = this._isSelected(type, this._lastEndPoint[type]), + isSelected = this._isSelected(type, start); + + if(this.noClear && !extending){ + this._toSelect = toSelect === undefined ? true : toSelect; + }else{ + //If we are modifying the selection using keyboard, retain the old status. + this._toSelect = mandatarySelect ? isSelected : !isSelected; + } + + //If CTRL is not pressed or it's SINGLE mode, this is a brand new selection. + if(!extending || (!isSelected && this._config[type] == SINGLE)){ + this._clearSelection("col", start); + this._clearSelection("cell", start); + if(!this.noClear || (type === 'row' && this._config[type] == SINGLE)){ + this._clearSelection('row', start); + } + this._toSelect = toSelect === undefined ? true : toSelect; + } + + this._selecting[type] = true; + this._currentPoint[type] = null; + + //We're holding SHIFT while clicking, it's a Click-Range selection. + if(isRange && this._lastType == type && lastIsSelected == this._toSelect && this._config[type] == MULTI){ + if(type === "row"){ + this._isUsingRowSelector = true; + } + this._startPoint[type] = this._lastEndPoint[type]; + this._highlight(type, this._startPoint[type]); + this._isUsingRowSelector = false; + }else{ + this._startPoint[type] = start; + } + //Now start selection + this._curType = type; + this._fireEvent("start", type); + this._isStartFocus = true; + this._isUsingRowSelector = true; + this._highlight(type, start, this._toSelect); + this._isStartFocus = false; + }, + _endSelect: function(type){ + // summary: + // End selection. Keep records, fire events and cleanup status. + // tag: + // private + // type: String + // "row", "col", or "cell" + if(type === "row"){ + delete this._isUsingRowSelector; + } + if(type == "all"){ + this._endSelect("col"); + this._endSelect("row"); + this._endSelect("cell"); + }else if(this._selecting[type]){ + this._addToSelected(type); + this._lastAnchorPoint[type] = this._startPoint[type]; + this._lastEndPoint[type] = this._currentPoint[type]; + if(this._toSelect){ + this._lastSelectedAnchorPoint[type] = this._lastAnchorPoint[type]; + this._lastSelectedEndPoint[type] = this._lastEndPoint[type]; + } + this._startPoint[type] = this._currentPoint[type] = null; + this._selecting[type] = false; + this._lastType = type; + this._fireEvent("end", type); + } + }, + _fireEvent: function(evtName, type){ + switch(evtName){ + case "start": + this.grid[this._toSelect ? "onStartSelect" : "onStartDeselect"](type, this._startPoint[type], this._selected); + break; + case "end": + this.grid[this._toSelect ? "onEndSelect" : "onEndDeselect"](type, this._lastAnchorPoint[type], this._lastEndPoint[type], this._selected); + break; + } + }, + _calcToHighlight: function(type, target, toHighlight, toSelect){ + // summary: + // Calculate what status should *target* have. + // If *toSelect* is not provided, this is a no op. + // This function is time-critical!! + if(toSelect !== undefined){ + var sltd; + if(this._usingKeyboard && !toHighlight){ + var last = this._isInLastRange(this._lastType, target); + if(last){ + sltd = this._isSelected(type, target); + //This 2 cases makes the keyboard swipe selection valid! + if(toSelect && sltd){ + return false; + } + if(!toSelect && !sltd && this._isInLastRange(this._lastType, target, true)){ + return true; + } + } + } + return toHighlight ? toSelect : (sltd || this._isSelected(type, target)); + } + return toHighlight; + }, + _highlightNode: function(node, toHighlight){ + // summary: + // Do the actual highlight work. + if(node){ + var selectCSSClass = "dojoxGridRowSelected"; + var selectCellClass = "dojoxGridCellSelected"; + html.toggleClass(node, selectCSSClass, toHighlight); + html.toggleClass(node, selectCellClass, toHighlight); + } + }, + _highlightHeader: function(colIdx, toHighlight){ + var cells = this.grid.layout.cells; + var node = cells[colIdx].getHeaderNode(); + var selectedClass = "dojoxGridHeaderSelected"; + html.toggleClass(node, selectedClass, toHighlight); + }, + _highlightRowSelector: function(rowIdx, toHighlight){ + //var t1 = (new Date()).getTime(); + var rowSelector = this.grid.views.views[0]; + if(rowSelector instanceof _RowSelector){ + var node = rowSelector.getRowNode(rowIdx); + if(node){ + var selectedClass = "dojoxGridRowSelectorSelected"; + html.toggleClass(node, selectedClass, toHighlight); + } + } + //console.log((new Date()).getTime() - t1); + }, + _highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){ + // summary: + // Highlight a single item. + // This function is time critical!! + var _this = this, toHL, g = _this.grid, cells = g.layout.cells; + switch(type){ + case "cell": + toHL = this._calcToHighlight(type, target, toHighlight, toSelect); + var c = cells[target.col]; + if(!c.hidden && !c.notselectable){ + this._highlightNode(target.node || c.getNode(target.row), toHL); + } + break; + case "col": + toHL = this._calcToHighlight(type, target, toHighlight, toSelect); + this._highlightHeader(target.col, toHL); + query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){ + var rowNode = cells[target.col].view.content.findRowTarget(cellNode); + if(rowNode){ + var rowIndex = rowNode[dojox.grid.util.rowIndexTag]; + _this._highlightSingle("cell", toHL, { + "row": rowIndex, + "col": target.col, + "node": cellNode + }); + } + }); + break; + case "row": + toHL = this._calcToHighlight(type, target, toHighlight, toSelect); + this._highlightRowSelector(target.row, toHL); + if(this._config.cell){ + array.forEach(cells, function(cell){ + _this._highlightSingle("cell", toHL, { + "row": target.row, + "col": cell.index, + "node": cell.getNode(target.row) + }); + }); + } + //To avoid dead lock + this._selectedRowModified = true; + if(!isRefresh){ + g.selection.setSelected(target.row, toHL); + } + } + }, + _highlight: function(type, target, toSelect){ + // summary: + // Highlight from start point to target. + // toSelect: Boolean + // Whether we are selecting or deselecting. + // This function is time critical!! + if(this._selecting[type] && target !== null){ + var start = this._startPoint[type], + current = this._currentPoint[type], + _this = this, + highlight = function(from, to, toHL){ + _this._forEach(type, from, to, function(item){ + _this._highlightSingle(type, toHL, item, toSelect); + }, true); + }; + switch(type){ + case "col": case "row": + if(current !== null){ + if(_inRange(type, target, start, current, true)){ + //target is between start and current, some selected should be deselected. + highlight(current, target, false); + }else{ + if(_inRange(type, start, target, current, true)){ + //selection has jumped to different direction, all should be deselected. + highlight(current, start, false); + current = start; + } + highlight(target, current, true); + } + }else{ + //First time select. + this._highlightSingle(type, true, target, toSelect); + } + break; + case "cell": + if(current !== null){ + if(_inRange("row", target, start, current, true) || + _inRange("col", target, start, current, true) || + _inRange("row", start, target, current, true) || + _inRange("col", start, target, current, true)){ + highlight(start, current, false); + } + } + highlight(start, target, true); + } + this._currentPoint[type] = target; + this._focusPoint(type, this._currentPoint); + } + }, + _focusPoint: function(type, point){ + // summary: + // Focus the current point, so when you move mouse, the focus indicator follows you. + if(!this._isStartFocus){ + var current = point[type], + f = this.grid.focus; + if(type == "col"){ + f._colHeadFocusIdx = current.col; + f.focusArea("header"); + }else if(type == "row"){ + f.focusArea("rowHeader", { + "rowIndex": current.row + }); + }else if(type == "cell"){ + f.setFocusIndex(current.row, current.col); + } + } + }, + _blurPoint: function(type, point){ + // summary: + // Blur the current point. + var f = this.grid.focus; + if(type == "col"){ + f._blurHeader(); + }else if(type == "cell"){ + f._blurContent(); + } + }, + _addToSelected: function(type){ + // summary: + // Record the selected items. + var toSelect = this._toSelect, _this = this, + toAdd = [], toRemove = [], + start = this._startPoint[type], + end = this._currentPoint[type]; + if(this._usingKeyboard){ + //If using keyboard, selection will be ended after every move. But we have to remember the original selection status, + //so as to return to correct status when we shrink the selection region. + this._forEach(type, this._lastAnchorPoint[type], this._lastEndPoint[type], function(item){ + //If the original selected item is not in current range, change its status. + if(!_inRange(type, item, start, end)){ + (toSelect ? toRemove : toAdd).push(item); + } + }); + } + this._forEach(type, start, end, function(item){ + var isSelected = _this._isSelected(type, item); + if(toSelect && !isSelected){ + //Add new selected items + toAdd.push(item); + }else if(!toSelect){ + //Remove deselected items. + toRemove.push(item); + } + }); + this._add(type, toAdd); + this._remove(type, toRemove); + + // have to keep record in original grid selection + array.forEach(this._selected.row, function(item){ + if(item.except.length > 0){ + //to avoid dead lock + this._selectedRowModified = true; + this.grid.selection.setSelected(item.row, false); + } + }, this); + }, + _forEach: function(type, start, end, func, halfClose){ + // summary: + // Go through items from *start* point to *end* point. + // This function is time critical!! + if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){ + return; + } + switch(type){ + case "col": case "row": + start = start[type]; + end = end[type]; + var dir = end > start ? 1 : -1; + if(!halfClose){ + end += dir; + } + for(; start != end; start += dir){ + func(_createItem(type, start)); + } + break; + case "cell": + var colDir = end.col > start.col ? 1 : -1, + rowDir = end.row > start.row ? 1 : -1; + for(var i = start.row, p = end.row + rowDir; i != p; i += rowDir){ + for(var j = start.col, q = end.col + colDir; j != q; j += colDir){ + func(_createItem(type, i, j)); + } + } + } + }, + _makeupForExceptions: function(type, newCellItems){ + // summary: + // When new cells is selected, maybe they will fill in the "holes" in selected rows and columns. + var makedUps = []; + array.forEach(this._selected[type], function(v1){ + array.forEach(newCellItems, function(v2){ + if(v1[type] == v2[type]){ + var pos = array.indexOf(v1.except, v2[_theOther[type]]); + if(pos >= 0){ + v1.except.splice(pos, 1); + } + makedUps.push(v2); + } + }); + }); + return makedUps; + }, + _makeupForCells: function(type, newItems){ + // summary: + // When some rows/cols are selected, maybe they can cover some of the selected cells, + // and fill some of the "holes" in the selected cols/rows. + var toRemove = []; + array.forEach(this._selected.cell, function(v1){ + array.some(newItems, function(v2){ + if(v1[type] == v2[type]){ + toRemove.push(v1); + return true; + } + return false; + }); + }); + this._remove("cell", toRemove); + array.forEach(this._selected[_theOther[type]], function(v1){ + array.forEach(newItems, function(v2){ + var pos = array.indexOf(v1.except, v2[type]); + if(pos >= 0){ + v1.except.splice(pos, 1); + } + }); + }); + }, + _addException: function(type, items){ + // summary: + // If some rows/cols are deselected, maybe they have created "holes" in selected cols/rows. + array.forEach(this._selected[type], function(v1){ + array.forEach(items, function(v2){ + v1.except.push(v2[_theOther[type]]); + }); + }); + }, + _addCellException: function(type, items){ + // summary: + // If some cells are deselected, maybe they have created "holes" in selected rows/cols. + array.forEach(this._selected[type], function(v1){ + array.forEach(items, function(v2){ + if(v1[type] == v2[type]){ + v1.except.push(v2[_theOther[type]]); + } + }); + }); + }, + _add: function(type, items){ + // summary: + // Add to the selection record. + var cells = this.grid.layout.cells; + if(type == "cell"){ + var colMakedup = this._makeupForExceptions("col", items); + var rowMakedup = this._makeupForExceptions("row", items); + //Step over hidden columns. + items = array.filter(items, function(item){ + return array.indexOf(colMakedup, item) < 0 && array.indexOf(rowMakedup, item) < 0 && + !cells[item.col].hidden && !cells[item.col].notselectable; + }); + }else{ + if(type == "col"){ + //Step over hidden columns. + items = array.filter(items, function(item){ + return !cells[item.col].hidden && !cells[item.col].notselectable; + }); + } + this._makeupForCells(type, items); + this._selected[type] = array.filter(this._selected[type], function(v){ + return array.every(items, function(item){ + return v[type] !== item[type]; + }); + }); + } + if(type != "col" && this.grid._hasIdentity){ + array.forEach(items, function(item){ + var record = this.grid._by_idx[item.row]; + if(record){ + item.id = record.idty; + } + }, this); + } + this._selected[type] = this._selected[type].concat(items); + }, + _remove: function(type, items){ + // summary: + // Remove from the selection record. + var comp = lang.partial(_isEqual, type); + this._selected[type] = array.filter(this._selected[type], function(v1){ + return !array.some(items, function(v2){ + return comp(v1, v2); + }); + }); + if(type == "cell"){ + this._addCellException("col", items); + this._addCellException("row", items); + }else if(this._config.cell){ + this._addException(_theOther[type], items); + } + }, + _isCellNotInExcept: function(type, item){ + // summary: + // Return true only when a cell is covered by selected row/col, and its not a "hole". + var attr = item[type], corres = item[_theOther[type]]; + return array.some(this._selected[type], function(v){ + return v[type] == attr && array.indexOf(v.except, corres) < 0; + }); + }, + _isSelected: function(type, item){ + // summary: + // Return true when the item is selected. (or logically selected, i.e, covered by a row/col). + if(!item){ return false; } + var res = array.some(this._selected[type], function(v){ + var ret = _isEqual(type, item, v); + if(ret && type !== "cell"){ + return v.except.length === 0; + } + return ret; + }); + if(!res && type === "cell"){ + res = (this._isCellNotInExcept("col", item) || this._isCellNotInExcept("row", item)); + if(type === "cell"){ + res = res && !this.grid.layout.cells[item.col].notselectable; + } + } + return res; + }, + _isInLastRange: function(type, item, isSelected){ + // summary: + // Return true only when the item is in the last seletion/deseletion range. + var start = this[isSelected ? "_lastSelectedAnchorPoint" : "_lastAnchorPoint"][type], + end = this[isSelected ? "_lastSelectedEndPoint" : "_lastEndPoint"][type]; + if(!item || !start || !end){ return false; } + return _inRange(type, item, start, end); + }, + _isValid: function(type, item, allowNotSelectable){ + // summary: + // Check whether the item is a valid __SelectItem for the given type. + if(!item){ return false; } + try{ + var g = this.grid, index = item[type]; + switch(type){ + case "col": + return index >= 0 && index < g.layout.cells.length && lang.isArray(item.except) && + (allowNotSelectable || !g.layout.cells[index].notselectable); + case "row": + return index >= 0 && index < g.rowCount && lang.isArray(item.except); + case "cell": + return item.col >= 0 && item.col < g.layout.cells.length && + item.row >= 0 && item.row < g.rowCount && + (allowNotSelectable || !g.layout.cells[item.col].notselectable); + } + }catch(e){} + return false; + } +}); + +EnhancedGrid.registerPlugin(Selector/*name:'selector'*/, { + "dependency": ["autoScroll"] +}); + +return Selector; + +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js new file mode 100644 index 0000000..bf19ce3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js @@ -0,0 +1,207 @@ +//>>built +define("dojox/grid/enhanced/plugins/_RowMapLayer", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "./_StoreLayer" +], function(declare, array, lang, layers){ + +var _devideToArrays = function(a){ + a.sort(function(v1, v2){ + return v1 - v2; + }); + var arr = [[a[0]]]; + for(var i = 1, j = 0; i < a.length; ++i){ + if(a[i] == a[i-1] + 1){ + arr[j].push(a[i]); + }else{ + arr[++j] = [a[i]]; + } + } + return arr; +}, +hitchIfCan = function(scope, func){ + return func ? lang.hitch(scope || lang.global, func) : function(){}; +}; + +return declare("dojox.grid.enhanced.plugins._RowMapLayer", layers._StoreLayer, { + tags: ["reorder"], + constructor: function(grid){ + this._map = {}; + this._revMap = {}; + this.grid = grid; + this._oldOnDelete = grid._onDelete; + var _this = this; + grid._onDelete = function(item){ + _this._onDelete(item); + _this._oldOnDelete.call(grid, item); + }; + this._oldSort = grid.sort; + grid.sort = function(){ + _this.clearMapping(); + _this._oldSort.apply(grid, arguments); + }; + }, + uninitialize: function(){ + this.grid._onDelete = this._oldOnDelete; + this.grid.sort = this._oldSort; + }, + setMapping: function(mapping){ + // summary: + // Remember the row mapping. + // mapping: Object + // keys are original rowIndexes, values are new rowIndexes. + this._store.forEachLayer(function(layer){ + if(layer.name() === "rowmap"){ + return false; + }else if(layer.onRowMappingChange){ + layer.onRowMappingChange(mapping); + } + return true; + }, false); + var from, to, origin, revmap = {}; + for(from in mapping){ + from = parseInt(from, 10); + to = mapping[from]; + if(typeof to == "number"){ + if(from in this._revMap){ + origin = this._revMap[from]; + delete this._revMap[from]; + }else{ + origin = from; + } + if(origin == to){ + delete this._map[origin]; + revmap[to] = "eq"; + }else{ + this._map[origin] = to; + revmap[to] = origin; + } + } + } + for(to in revmap){ + if(revmap[to] === "eq"){ + delete this._revMap[parseInt(to, 10)]; + }else{ + this._revMap[parseInt(to, 10)] = revmap[to]; + } + } + }, + clearMapping: function(){ + this._map = {}; + this._revMap = {}; + }, + _onDelete: function(item){ + var idx = this.grid._getItemIndex(item, true); + if(idx in this._revMap){ + var rowIdxArr = [], r, i, origin = this._revMap[idx]; + delete this._map[origin]; + delete this._revMap[idx]; + for(r in this._revMap){ + r = parseInt(r, 10); + if(this._revMap[r] > origin){ + --this._revMap[r]; + } + } + for(r in this._revMap){ + r = parseInt(r, 10); + if(r > idx){ + rowIdxArr.push(r); + } + } + rowIdxArr.sort(function(a, b){ + return b - a; + }); + for(i = rowIdxArr.length - 1; i >= 0; --i){ + r = rowIdxArr[i]; + this._revMap[r - 1] = this._revMap[r]; + delete this._revMap[r]; + } + this._map = {}; + for(r in this._revMap){ + this._map[this._revMap[r]] = r; + } + } + }, + _fetch: function(userRequest){ + var mapCount = 0, r; + var start = userRequest.start || 0; + for(r in this._revMap){ + r = parseInt(r, 10); + if(r >= start){ + ++mapCount; + } + } + if(mapCount > 0){ + //Row mapping is in use. + var rows = [], i, map = {}, + count = userRequest.count > 0 ? userRequest.count : -1; + if(count > 0){ + for(i = 0; i < count; ++i){ + r = start + i; + r = r in this._revMap ? this._revMap[r] : r; + map[r] = i; + rows.push(r); + } + }else{ + //We don't have a count, must create our own. + for(i = 0;; ++i){ + r = start + i; + if(r in this._revMap){ + --mapCount; + r = this._revMap[r]; + } + map[r] = i; + rows.push(r); + if(mapCount <= 0){ + break; + } + } + } + this._subFetch(userRequest, this._getRowArrays(rows), 0, [], map, userRequest.onComplete, start, count); + return userRequest; + }else{ + //No row mapping at all. + return lang.hitch(this._store, this._originFetch)(userRequest); + } + }, + _getRowArrays: function(rows){ + return _devideToArrays(rows); + }, + _subFetch: function(userRequest, rowArrays, index, result, map, oldOnComplete, start, count){ + var arr = rowArrays[index], _this = this; + var urstart = userRequest.start = arr[0]; + userRequest.count = arr[arr.length - 1] - arr[0] + 1; + userRequest.onComplete = function(items){ + array.forEach(items, function(item, i){ + var r = urstart + i; + if(r in map){ + result[map[r]] = item; + } + }); + if(++index == rowArrays.length){ + //mapped rows are all fetched. + if(count > 0){ + userRequest.start = start; + userRequest.count = count; + userRequest.onComplete = oldOnComplete; + hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest); + }else{ + userRequest.start = userRequest.start + items.length; + delete userRequest.count; + userRequest.onComplete = function(items){ + result = result.concat(items); + userRequest.start = start; + userRequest.onComplete = oldOnComplete; + hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest); + }; + _this.originFetch(userRequest); + } + }else{ + _this._subFetch(userRequest, rowArrays, index, result, map, oldOnComplete, start, count); + } + }; + _this.originFetch(userRequest); + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js new file mode 100644 index 0000000..dff96c1 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js @@ -0,0 +1,109 @@ +//>>built +define("dojox/grid/enhanced/plugins/_SelectionPreserver", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/connect", + '../../_SelectionPreserver' +], function(declare, lang, connect, _SelectionPreserver){ + +return declare("dojox.grid.enhanced.plugins._SelectionPreserver", _SelectionPreserver, { + // summary: + // Preserve selections across various user actions. + // + // description: + // Extends dojox.grid._SelectionPreserver adding a bit more support to make selection persistence working well + // with various EnhancedGrid features, e.g. filtering, nested sorting, pagination, select all etc. + // + // Precondition - Identifier(id) is required for store, as id is used for differentiating row items. + // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click) + // + // example: + // | //To turn on this - set 'keepSelection' attribute to true + // | <div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../> + + constructor: function(selection){ + var grid = this.grid; + grid.onSelectedById = this.onSelectedById; + this._oldClearData = grid._clearData; + var self = this; + grid._clearData = function(){ + self._updateMapping(!grid._noInternalMapping); + self._trustSelection = []; + self._oldClearData.apply(grid, arguments); + }; + this._connects.push( + connect.connect(selection, 'selectRange', lang.hitch(this, '_updateMapping', true, true, false)), + connect.connect(selection, 'deselectRange', lang.hitch(this, '_updateMapping', true, false, false)), + connect.connect(selection, 'deselectAll', lang.hitch(this, '_updateMapping', true, false, true)) + ); + }, + destroy: function(){ + this.inherited(arguments); + this.grid._clearData = this._oldClearData; + }, + reset: function(){ + this.inherited(arguments); + this._idMap = []; + this._trustSelection = []; + this._defaultSelected = false; + }, + _reSelectById: function(item, index){ + // summary: + // Overwritten + var s = this.selection, g = this.grid; + if(item && g._hasIdentity){ + var id = g.store.getIdentity(item); + if(this._selectedById[id] === undefined){ + if(!this._trustSelection[index]){ + s.selected[index] = this._defaultSelected; + } + }else{ + s.selected[index] = this._selectedById[id]; + } + this._idMap.push(id); + g.onSelectedById(id, index, s.selected[index]); + } + }, + _selectById: function(toSelect, inItemOrIndex){ + // summary: + // Overwritten + if(!this.inherited(arguments)){ + this._trustSelection[inItemOrIndex] = true; + } + }, + onSelectedById: function(id, rowIndex, value){}, + + _updateMapping: function(trustSelection, isSelect, isForAll, from, to){ + // summary: + // This function try to keep the selection info updated when range selection is performed. + // 1. Calculate how many unloaded rows are there; + // 2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can + // be properly recorded. + var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id; + for(i = g.rowCount - 1; i >= 0; --i){ + if(!g._by_idx[i]){ + ++unloaded; + flag += s.selected[i] ? 1 : -1; + }else{ + id = g._by_idx[i].idty; + if(id && (trustSelection || this._selectedById[id] === undefined)){ + this._selectedById[id] = !!s.selected[i]; + } + } + } + if(unloaded){ + this._defaultSelected = flag > 0; + } + if(!isForAll && from !== undefined && to !== undefined){ + isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount; + } + // When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now. + // This occurs only when pagination's "All" is used. + if(isForAll && (!g.usingPagination || g.selectionMode === 'single')){ + for(i = this._idMap.length - 1; i >= 0; --i){ + this._selectedById[this._idMap[i]] = isSelect; + } + } + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js new file mode 100644 index 0000000..bf73a6d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js @@ -0,0 +1,395 @@ +//>>built +define("dojox/grid/enhanced/plugins/_StoreLayer", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/_base/xhr" +], function(declare, array, lang, xhr){ +// summary: +// The dojo.data.api.Read API is powerful, but it's difficult to give the store some special commands before +// fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The +// parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because: +// 1. users do not have the opportunity to response to the store actions when these options or queries are applied, +// especially when the real store is at server side. +// 2. the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be +// difficult if this implementation is not able to or very hard to be changed, or some new options are required to +// be valid for all stores. +// This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that +// it can be easily extended to have special behaviors or act like a totally different store. +// The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming +// store.fetch as a 'black box', thus maintaining the independence between layers. +// *fetch* is the most important data retriever in the Read API, almost all other functions are used for a single +// item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this +// *fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer. +// example: +// //ns is for namespace, i.e.:dojox.grid.enhanced.plugins +// ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer()); +// +// //every layer has a name, it should be given in the document of this layer. +// //if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name(); +// store.layer("filter").filterDef(...); +// store.layer("unique").setUniqueColumns(...); +// store.layer("transform").setScheme(...); +// +// //now use the store as usual... +// +// store.unwrap("transform"); //remove the transform layer but retain the other two. +// +// //now use the store as usual... +// +// store.unwrap(); //remove all the layers, get the original store back. + + var ns = lang.getObject("grid.enhanced.plugins", true, dojox); + + var getPrevTags = function(tags){ + var tagList = ["reorder", "sizeChange", "normal", "presentation"]; + var idx = tagList.length; + for(var i = tags.length - 1; i >= 0; --i){ + var p = array.indexOf(tagList, tags[i]); + if(p >= 0 && p <= idx){ + idx = p; + } + } + if(idx < tagList.length - 1){ + return tagList.slice(0, idx + 1); + }else{ + return tagList; + } + }, + + unwrap = function(/* string? */layerName){ + // summary: + // Unwrap the layers of the store + // tags: + // public + // returns: + // The unwrapped store, for nested use only. + var i, layers = this._layers, len = layers.length; + if(layerName){ + for(i = len-1; i >= 0; --i){ + if(layers[i].name() == layerName){ + layers[i]._unwrap(layers[i + 1]); + break; + } + } + layers.splice(i, 1); + }else{ + for(i = len - 1; i >= 0; --i){ + layers[i]._unwrap(); + } + } + if(!layers.length){ + delete this._layers; + delete this.layer; + delete this.unwrap; + delete this.forEachLayer; + } + //console.log("layers:",this._layers); + return this; //Read-store + }, + + getLayer = function(layerName){ + // summary: + // Get a layer of the store, so we can configure that layer. + // tags: + // public (scope is store) + // layerName: string + // the name of the layer + // returns: + // the store layer object + var i, layers = this._layers; + if(typeof layerName == "undefined"){ + return layers.length; //Integer + } + if(typeof layerName == "number"){ + return layers[layerName]; //_StoreLayer + } + for(i = layers.length - 1; i >= 0; --i){ + if(layers[i].name() == layerName){ + return layers[i]; //_StoreLayer + } + } + return null; //_StoreLayer + }, + + forEachLayer = function(callback, isInnerToOuter){ + // summary: + // Visit the layers one by one. From the outer most to inner most by default. + // callback: Function + // The function to callback. + // If return false, break the loop. + // isInnerToOuter: Boolean + // Whether visit from the inner most layer to the outer most layer. + var len = this._layers.length, start, end, dir; + if(isInnerToOuter){ + start = 0; + end = len; + dir = 1; + }else{ + start = len - 1; + end = -1; + dir = -1; + } + for(var i = start; i != end; i += dir){ + if(callback(this._layers[i], i) === false){ + return i; + } + } + return end; + }; + ns.wrap = function(store, funcName, layer, layerFuncName){ + // summary: + // Wrap the store with the given layer. + // tags: + // public + // store: Read-store + // The store to be wrapped. + // layer: _StoreLayer + // The layer to be used + // returns + // The wrapped store, for nested use only. + if(!store._layers){ + store._layers = []; + store.layer = lang.hitch(store, getLayer); + store.unwrap = lang.hitch(store, unwrap); + store.forEachLayer = lang.hitch(store, forEachLayer); + } + var prevTags = getPrevTags(layer.tags); + if(!array.some(store._layers, function(lyr, i){ + if(array.some(lyr.tags, function(tag){ + return array.indexOf(prevTags, tag) >= 0; + })){ + return false; + }else{ + store._layers.splice(i, 0, layer); + layer._wrap(store, funcName, layerFuncName, lyr); + return true; + } + })){ + store._layers.push(layer); + layer._wrap(store, funcName, layerFuncName); + } + //console.log("wrapped layers:", dojo.map(store._layers, function(lyr){return lyr.name();})); + return store; //Read-store + }; + + var _StoreLayer = declare("dojox.grid.enhanced.plugins._StoreLayer", null, { + // summary: + // The most abstract class of store layers, provides basic utilities and some interfaces. + // tags: + // abstract +/*===== + // _store: [protected] Read-store + // The wrapped store. + _store: null, + + // _originFetch: [protected] function + // The original fetch function of the store. + _originFetch: null, + + // __enabled: [private] Boolean + // To control whether this layer is valid. + __enabled: true, +=====*/ + tags: ["normal"], + + layerFuncName: "_fetch", + + constructor: function(){ + this._store = null; + this._originFetch = null; + this.__enabled = true; + }, + initialize: function(store){ + // summary: + // + }, + uninitialize: function(store){ + // summary: + // + }, + invalidate: function(){ + + }, + _wrap: function(store, funcName, layerFuncName, nextLayer){ + // summary: + // Do the actual wrapping (or 'hacking' if you like) to the store. + // tags: + // internal + // store: Read-store + // The store to be wrapped. + this._store = store; + this._funcName = funcName; + var fetchFunc = lang.hitch(this, function(){ + return (this.enabled() ? this[layerFuncName || this.layerFuncName] : this.originFetch).apply(this, arguments); + }); + if(nextLayer){ + this._originFetch = nextLayer._originFetch; + nextLayer._originFetch = fetchFunc; + }else{ + this._originFetch = store[funcName] || function(){}; + store[funcName] = fetchFunc; + } + this.initialize(store); + }, + _unwrap: function(nextLayer){ + // summary: + // Do the actual unwrapping to the store. + // tags: + // internal + // store: Read-store + // The store to be unwrapped. + this.uninitialize(this._store); + if(nextLayer){ + nextLayer._originFetch = this._originFetch; + }else{ + this._store[this._funcName] = this._originFetch; + } + this._originFetch = null; + this._store = null; + }, + enabled: function(/* bool? */toEnable){ + // summary: + // The get/set function of the enabled status of this layer + // tags: + // public + // toEnable: Boolean? + // If given, is a setter, otherwise, it's getter. + if(typeof toEnable != "undefined"){ + this.__enabled = !!toEnable; + } + return this.__enabled; //Boolean + }, + name: function(){ + // summary: + // Get the name of this store layer. + // The default name retrieved from class name, which should have a pattern of "{name}Layer". + // If this pattern does not exist, the whole class name will be this layer's name. + // It's better to override this method if your class name is too complicated. + // tags: + // public extension + // returns: + // The name of this layer. + if(!this.__name){ + var m = this.declaredClass.match(/(?:\.(?:_*)([^\.]+)Layer$)|(?:\.([^\.]+)$)/i); + this.__name = m ? (m[1] || m[2]).toLowerCase() : this.declaredClass; + } + return this.__name; + }, + originFetch: function(){ + return (lang.hitch(this._store, this._originFetch)).apply(this, arguments); + } + }); + var _ServerSideLayer = declare("dojox.grid.enhanced.plugins._ServerSideLayer", _StoreLayer, { + // summary: + // The most abstract class for all server side store layers. + // tags: + // abstract +/*===== + // _url: [protected] string + // The url of the server + _url: "", + // __cmds [private] object + // The command object to be sent to server. + __cmds: {}, +=====*/ + constructor: function(args){ + args = args || {}; + this._url = args.url || ""; + this._isStateful = !!args.isStateful; + this._onUserCommandLoad = args.onCommandLoad || function(){}; + this.__cmds = {cmdlayer:this.name(), enable:true}; + + //Only for stateful server, sending commands before fetch makes sense. + this.useCommands(this._isStateful); + }, + enabled: function(/* bool? */toEnable){ + // summary: + // Overrided from _StoreLayer.enabled + var res = this.inherited(arguments); + this.__cmds.enable = this.__enabled; + return res; + }, + useCommands: function(/* bool? */toUse){ + // summary: + // If you only want to modify the user request, instead of sending a separate command + // to server before fetch, just call: + // this.useCommand(false); + // tags: + // public + // toUse: Boolean? + // If provided, it's a setter, otherwise, it's a getter + if(typeof toUse != "undefined"){ + this.__cmds.cmdlayer = (toUse && this._isStateful) ? this.name() : null; + } + return !!(this.__cmds.cmdlayer); //Boolean + }, + _fetch: function(/* keywordArgs */userRequest){ + // summary: + // Implementation of _StoreLayer._fetch + if(this.__cmds.cmdlayer){ + //We're gonna send command to server before fetch. + xhr.post({ + url: this._url || this._store.url, + content: this.__cmds, + load: lang.hitch(this, function(responce){ + this.onCommandLoad(responce, userRequest); + this.originFetch(userRequest); + }), + error: lang.hitch(this, this.onCommandError) + }); + }else{ + //The user only wants to modify the request object. + this.onCommandLoad("", userRequest); + this.originFetch(userRequest); + } + return userRequest; //dojo.data.api.Request + }, + command: function(/* string */cmdName,/* (string|number|bool|...)? */cmdContent){ + // summary: + // get/set a command (a name-value pair) + // tags: + // public + // cmdName: string + // The name of the command + // cmdContent: anything + // The content of the command + // returns: + // The content of the command if cmdContent is undefined + var cmds = this.__cmds; + if(cmdContent === null){ + delete cmds[cmdName]; + }else if(typeof cmdContent !== "undefined"){ + cmds[cmdName] = cmdContent; + } + return cmds[cmdName]; //anything + }, + onCommandLoad: function(/* string */response, /* keywordArgs */userRequest){ + // summary: + // When the server gives back *response* for the commands, you can do something here. + // tags: + // callback extension + // response: string + // server response + // userRequest: [in|out] dojo.data.api.Request + // The request object for *fetch*. You can modify this object according to the *response* + // so as to change the behavior of *fetch* + this._onUserCommandLoad(this.__cmds, userRequest, response); + }, + onCommandError: function(error){ + // summary: + // handle errors when sending commands. + // tags: + // callback extension + // error: Error + console.log(error); + throw error; + } + }); + + return { + _StoreLayer: _StoreLayer, + _ServerSideLayer: _ServerSideLayer, + wrap: ns.wrap + }; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js new file mode 100644 index 0000000..44006e2 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js @@ -0,0 +1,88 @@ +//>>built +define("dojox/grid/enhanced/plugins/exporter/CSVWriter", [ + "dojo/_base/declare", + "dojo/_base/array", + "./_ExportWriter", + "../Exporter" +], function(declare, array, _ExportWriter, Exporter){ + +Exporter.registerWriter("csv", "dojox.grid.enhanced.plugins.exporter.CSVWriter"); + +return declare("dojox.grid.enhanced.plugins.exporter.CSVWriter", _ExportWriter, { + // summary: + // Export grid to CSV format. + _separator: ',', + + _newline: "\r\n", + + constructor: function(/* object? */writerArgs){ + // summary: + // CSV default separator is ','. + // But we can also use our own. + // writerArgs: object? + // {separator:'...'} + if(writerArgs){ + this._separator = writerArgs.separator ? writerArgs.separator : this._separator; + this._newline = writerArgs.newline ? writerArgs.newline : this._newline; + } + this._headers = []; + this._dataRows = []; + }, + + _formatCSVCell: function(/* string */cellValue){ + // summary: + // Format cell value to follow CSV standard. + // See: http://en.wikipedia.org/wiki/Comma-separated_values + // tags: + // private + // cellValue: string + // The value in a cell. + // returns: + // The formatted content of a cell + if(cellValue === null || cellValue === undefined){ + return ''; + } + var result = String(cellValue).replace(/"/g, '""'); + if(result.indexOf(this._separator) >= 0 || result.search(/[" \t\r\n]/) >= 0){ + result = '"' + result + '"'; + } + return result; //String + }, + + beforeContentRow: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var row = [], + func = this._formatCSVCell; + array.forEach(arg_obj.grid.layout.cells, function(cell){ + //We are not interested in indirect selectors and row indexes. + if(!cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){ + //We only need data here, not html + row.push(func(this._getExportDataForCell(arg_obj.rowIndex, arg_obj.row, cell, arg_obj.grid))); + } + }, this); + this._dataRows.push(row); + //We do not need to go into the row. + return false; //Boolean + }, + + handleCell: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var cell = arg_obj.cell; + if(arg_obj.isHeader && !cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){ + this._headers.push(cell.name || cell.field); + } + }, + + toString: function(){ + // summary: + // Overrided from _ExportWriter + var result = this._headers.join(this._separator); + for(var i = this._dataRows.length - 1; i >= 0; --i){ + this._dataRows[i] = this._dataRows[i].join(this._separator); + } + return result + this._newline + this._dataRows.join(this._newline); //String + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js new file mode 100644 index 0000000..0ea2c74 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js @@ -0,0 +1,160 @@ +//>>built +define("dojox/grid/enhanced/plugins/exporter/TableWriter", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/dom-geometry", + "./_ExportWriter", + "../Exporter" +], function(declare, array, domGeometry, _ExportWriter, Exporter){ + +Exporter.registerWriter("table", "dojox.grid.enhanced.plugins.exporter.TableWriter"); + +return declare("dojox.grid.enhanced.plugins.exporter.TableWriter", _ExportWriter, { + // summary: + // Export grid to HTML table format. Primarily used by Printer plugin. + constructor: function(/* object? */writerArgs){ + // summary: + // The generated table only defines the col/rowspan, height and width of + // all the cells in the style attribute, no other attributes + // (like border, cellspacing, etc.) are used. + // Users can define these attributes in the writerArgs object, like: + // {table:"border='border'",thead:"cellspacing='3'"} + this._viewTables = []; + this._tableAttrs = writerArgs || {}; + }, + + _getTableAttrs: function(/* string */tagName){ + // summary: + // Get html attribute string for the given kind of tag. + // tags: + // private + // tagName: string + // An html tag name + // returns: + // The well formatted attributes for the given html table.tag + var attrs = this._tableAttrs[tagName] || ''; + //To ensure the attribute list starts with a space + if(attrs && attrs[0] != ' '){ + attrs = ' ' + attrs; + } + return attrs; //String + }, + + _getRowClass: function(/* object */arg_obj){ + // summary: + // Get CSS class string for a row + // tags: + // private + return arg_obj.isHeader ? " grid_header" : [//String + " grid_row grid_row_", + arg_obj.rowIdx + 1, + arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row" + ].join(''); + }, + + _getColumnClass: function(/* object */arg_obj){ + // summary: + // Get CSS class string for a column + // tags: + // private + var col_idx = arg_obj.cell.index + arg_obj.colOffset + 1; + return [" grid_column grid_column_", col_idx,//String + col_idx % 2 ? " grid_odd_column" : " grid_even_column"].join(''); + }, + + beforeView: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var viewIdx = arg_obj.viewIdx, + table = this._viewTables[viewIdx], + height, width = domGeometry.getMarginBox(arg_obj.view.contentNode).w; + if(!table){ + var left = 0; + for(var i = 0; i < viewIdx; ++i){ + left += this._viewTables[i]._width; + } + table = this._viewTables[viewIdx] = ['<div class="grid_view" style="position: absolute; top: 0; ', + domGeometry.isBodyLtr() ? 'left' : 'right', ':', left, + 'px;">']; + } + table._width = width; + if(arg_obj.isHeader){ + height = domGeometry.getContentBox(arg_obj.view.headerContentNode).h; + }else{ + var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx); + if(rowNode){ + height = domGeometry.getContentBox(rowNode).h; + }else{ + //This row has not been loaded from store, so we should estimate it's height. + height = arg_obj.grid.scroller.averageRowHeight; + } + } + table.push('<table class="', this._getRowClass(arg_obj), + '" style="table-layout:fixed; height:', height, 'px; width:', width, 'px;" ', + 'border="0" cellspacing="0" cellpadding="0" ', + this._getTableAttrs("table"), + '><tbody ', this._getTableAttrs('tbody'), '>'); + return true; //Boolean + }, + + afterView: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + this._viewTables[arg_obj.viewIdx].push('</tbody></table>'); + }, + + beforeSubrow: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + this._viewTables[arg_obj.viewIdx].push('<tr', this._getTableAttrs('tr'), '>'); + return true; //Boolean + }, + + afterSubrow: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + this._viewTables[arg_obj.viewIdx].push('</tr>'); + }, + + handleCell: function(/* object */arg_obj){ + // summary: + // Overrided from _ExportWriter + var cell = arg_obj.cell; + if(cell.hidden || array.indexOf(arg_obj.spCols, cell.index) >= 0){ + //We are not interested in indirect selectors and row indexes. + return; + } + var cellTagName = arg_obj.isHeader ? 'th' : 'td', + attrs = [cell.colSpan ? ' colspan="' + cell.colSpan + '"' : '', + cell.rowSpan ? ' rowspan="' + cell.rowSpan + '"' : '', + ' style="width: ', domGeometry.getContentBox(cell.getHeaderNode()).w, 'px;"', + this._getTableAttrs(cellTagName), + ' class="', this._getColumnClass(arg_obj), '"'].join(''), + table = this._viewTables[arg_obj.viewIdx]; + table.push('<', cellTagName, attrs, '>'); + if(arg_obj.isHeader){ + table.push(cell.name || cell.field); + } else{ + table.push(this._getExportDataForCell(arg_obj.rowIdx, arg_obj.row, cell, arg_obj.grid)); + } + table.push('</', cellTagName, '>'); + }, + + afterContent: function(){ + // summary: + // Overrided from _ExportWriter + array.forEach(this._viewTables, function(table){ + table.push('</div>'); + }); + }, + + toString: function(){ + // summary: + // Overrided from _ExportWriter + var viewsHTML = array.map(this._viewTables, function(table){ //String + return table.join(''); + }).join(''); + return ['<div style="position: relative;">', viewsHTML, '</div>'].join(''); + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js new file mode 100644 index 0000000..14bd39f --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js @@ -0,0 +1,269 @@ +//>>built +define("dojox/grid/enhanced/plugins/exporter/_ExportWriter", [ + "dojo/_base/declare" +], function(declare){ +//require Exporter here, so the implementations only need to require this file, +//and the users only need to require the implementation file. + +return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, { + // summary: + // This is an abstract class for all kinds of writers used in the Exporter plugin. + // It utilizes the strategy pattern to break the export work into several stages, + // and provide interfaces for all of them. + // Implementations might choose some of the functions in this class to override, + // thus providing their own functionalities. + // The Exporter will go through the grid line by line. So in every line, all the Views + // will be reached, and the header line is only handled once. + // An *argObj* object is passed to most functions of this class. + // It carries context arguments that make sense when they are called. + +/*===== + argObj: { + // grid: EnhancedGrid + // The grid object we are now handling. + grid: null, + + // isHeader: bool + // Indicating which context we're handling, header or content. + isHeader: true, + + // view: _View + // Reference to the current _View object. + view: null, + + // viewIdx: int + // The index of the current _View object in the views array. + // If the grid does not have any rowselector view, it conforms to the index + // in the _ViewManager.views. + viewIdx: -1, + + // subrow: _View.structure.cells[i] + // Reference to the current subrow. + // A subrow describe the innter structure of a row in a view, it's an array of cells + subrow: null, + + // subrowIdx: int + // The index of the current subrow in the subrow array: _View.structure.cells. + subrowIdx: -1, + + // cell: dojox.grid.__CellDef + // Reference to the current cell. + cell: null, + + //cellIdx: int + // The index of the current cell in the current subrow. + // It's different from cell.index, which is the index in the whole line. + cellIdx: -1, + + //row: item + // The current row of data (logically), a.k.a.: current item. + row: null, + + //rowIdx: int + // The index of the current row (item). + rowIdx: -1, + + // spCols: Array<int> + // An array of special column indexes(flat,not regarding structure). + // Special columns are typically attached to grid as a kind of UI facility + // by the grid widget, instead of some real data. + // For example, indirect selectors and row indexers. + // Users can choose to export it or not. + spCols: [], + + // colOffset: int + // If the grid has a _RowSelector view or something else, this view will NOT be + // passed to the user in argObj. So the column index (cell.index) will appear shifted + // (start from 1 instead of 0). This colOffset is provided to remove this shift. + // usage: + // var correctColIndex = argObj.cell.index + argObj.colOffset; + colOffset: 0 + }, +=====*/ + + constructor: function(/* object? */writerArgs){ + // summary: + // Writer initializations goes here. + // writerArgs: object? + // Any implementation of this class might accept a writerArgs object (optional), + // which contains some writer-specific arguments given by the user. + }, + _getExportDataForCell: function(rowIndex, rowItem, cell, grid){ + var data = (cell.get || grid.get).call(cell, rowIndex, rowItem); + if(this.formatter){ + return this.formatter(data, cell, rowIndex, rowItem); + }else{ + return data; + } + }, + beforeHeader: function(/* EnhancedGrid */grid){ + // summary: + // We are going to start the travel in the grid. + // Is there anything we should do now? + // tags: + // protected extension + // return: + // true: go on hanling the header row and then call afterHeader. + // false: skip the header row, won't call afterHeader. + return true; //Boolean + }, + afterHeader: function(){ + // summary: + // The header line has been handled. + // tags: + // protected extension + // returns: + // undefined + }, + beforeContent: function(/* Array */items){ + // summary: + // We are ready to go through all the contents(items). + // tags: + // protected extension + // items: + // All the items fetched from the store + // return: + // true: go on handling the contents and then call afterContent. + // false: skip all the contents, won't call afterContent. + return true; //Boolean + }, + afterContent: function(){ + // summary: + // We have finished the entire grid travel. + // Do some clean up work if you need to. + // tags: + // protected extension + // returns: + // undefined + }, + beforeContentRow: function(/* object */argObj){ + // summary: + // Before handling a line of data (not header). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // spCols + // } + // return: + // true: go on handling the current data row and then call afterContentRow. + // false: skip the current data row, won't call afterContentRow. + return true; //Boolean + }, + afterContentRow: function(/* object */argObj){ + // summary: + // After handling a line of data (not header). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // spCols + // } + // returns: + // undefined + }, + beforeView: function(/* object */argObj){ + // summary: + // Before handling a view. + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // view,viewIdx, + // spCols(if isHeader==false) + // } + // return: + // true: go on handling the current view and then call afterView. + // false: skip the current view, won't call afterView. + return true; //Boolean + }, + afterView: function(/* object */argObj){ + // summary: + // After handling a view. + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // view,viewIdx, + // spCols(if isHeader==false) + // } + // tags: + // protected extension + // returns: + // undefined + }, + beforeSubrow: function(/* object */argObj){ + // summary: + // Before handling a subrow in a line (defined in the grid structure). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // view,viewIdx, + // subrow,subrowIdx, + // spCols(if isHeader==false) + // } + // return: + // true: go on handling the current subrow and then call afterSubrow. + // false: skip the current subrow, won't call afterSubrow. + return true; //Boolean + }, + afterSubrow: function(/* object */argObj){ + // summary: + // Before handling a subrow in a line (defined in the grid structure). + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // view,viewIdx, + // subrow,subrowIdx, + // spCols(if isHeader==false) + // } + // returns: + // undefined + }, + handleCell: function(/* object */argObj){ + // summary: + // Handle a header cell or data cell. + // tags: + // protected extension + // argObj: + // An object with at least the following context properties available: + // { + // grid,isHeader, + // row,rowIdx, + // view,viewIdx, + // subrow,subrowIdx, + // cell,cellIdx, + // spCols(if isHeader==false) + // } + // returns: + // undefined + }, + toString: function(){ + // summary: + // Export to a string. + // tags: + // protected extension + // returns: + // The exported result string. + return ''; //String + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js new file mode 100644 index 0000000..2a63dcb --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js @@ -0,0 +1,46 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/ClearFilterConfirm", [ + "dojo/_base/declare", + "dojo/cache", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/_WidgetsInTemplateMixin" +], function(declare, cache, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){ + +return declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm", + [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], { + // summary: + // The UI for user to confirm the operation of clearing filter. + templateString: cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"), + + widgetsInTemplate: true, + + plugin: null, + + postMixInProperties: function(){ + var nls = this.plugin.nls; + this._clearBtnLabel = nls["clearButton"]; + this._cancelBtnLabel = nls["cancelButton"]; + this._clearFilterMsg = nls["clearFilterMsg"]; + }, + + postCreate: function(){ + this.inherited(arguments); + this.cancelBtn.domNode.setAttribute("aria-label", this.plugin.nls["waiCancelButton"]); + this.clearBtn.domNode.setAttribute("aria-label", this.plugin.nls["waiClearButton"]); + }, + + uninitialize: function(){ + this.plugin = null; + }, + + _onCancel: function(){ + this.plugin.clearFilterDialog.hide(); + }, + + _onClear: function(){ + this.plugin.clearFilterDialog.hide(); + this.plugin.filterDefDialog.clearFilter(this.plugin.filterDefDialog._clearWithoutRefresh); + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js new file mode 100644 index 0000000..422c56a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js @@ -0,0 +1,386 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/FilterBar", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/lang", + "dojo/_base/sniff", + "dojo/_base/event", + "dojo/_base/html", + "dojo/_base/window", + "dojo/cache", + "dojo/query", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/_WidgetsInTemplateMixin", + "dojo/fx", + "dojo/_base/fx", + "dojo/string", + "dijit/focus" +], function(declare, array, connect, lang, has, event, html, win, cache, query, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, fx, baseFx, string, dijitFocus){ + +var _focusClass = "dojoxGridFBarHover", + _filteredClass = "dojoxGridFBarFiltered", + _stopEvent = function(evt){ + try{ + if(evt && evt.preventDefault){ + event.stop(evt); + } + }catch(e){} + }; + +return declare("dojox.grid.enhanced.plugins.filter.FilterBar", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{ + // summary: + // The filter bar UI. + templateString: cache("dojox.grid","enhanced/templates/FilterBar.html"), + + widgetsInTemplate: true, + + _timeout_statusTooltip: 300, + + _handle_statusTooltip: null, + + _curColIdx: -1, + + plugin: null, + + postMixInProperties: function(){ + var plugin = this.plugin; + var nls = plugin.nls; + this._filterBarDefBtnLabel = nls["filterBarDefButton"]; + this._filterBarClearBtnLabel = nls["filterBarClearButton"]; + this._closeFilterBarBtnLabel = nls["closeFilterBarBtn"]; + var itemsName = plugin.args.itemsName || nls["defaultItemsName"]; + this._noFilterMsg = string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]); + + var t = this.plugin.args.statusTipTimeout; + if(typeof t == 'number'){ + this._timeout_statusTooltip = t; + } + + var g = plugin.grid; + g.showFilterBar = lang.hitch(this, "showFilterBar"); + g.toggleFilterBar = lang.hitch(this, "toggleFilterBar"); + g.isFilterBarShown = lang.hitch(this, "isFilterBarShown"); + }, + postCreate: function(){ + this.inherited(arguments); + if(!this.plugin.args.closeFilterbarButton){ + html.style(this.closeFilterBarButton.domNode, "display", "none"); + } + var _this = this, + g = this.plugin.grid, + old_func = this.oldGetHeaderHeight = lang.hitch(g,g._getHeaderHeight); + + this.placeAt(g.viewsHeaderNode, "after"); + this.connect(this.plugin.filterDefDialog, "showDialog", "_onShowFilterDefDialog"); + this.connect(this.plugin.filterDefDialog, "closeDialog", "_onCloseFilterDefDialog"); + this.connect(g.layer("filter"), "onFiltered", this._onFiltered); + + this.defineFilterButton.domNode.title = this.plugin.nls["filterBarDefButton"]; + if(html.hasClass(win.body(), "dijit_a11y")){ + this.defineFilterButton.set("label", this.plugin.nls["a11yFilterBarDefButton"]); + } + this.connect(this.defineFilterButton.domNode, "click", _stopEvent); + this.connect(this.clearFilterButton.domNode, "click", _stopEvent); + this.connect(this.closeFilterBarButton.domNode, "click", _stopEvent); + + this.toggleClearFilterBtn(true); + this._initAriaInfo(); + + //Hack the header height to include filter bar height; + g._getHeaderHeight = function(){ + return old_func() + html.marginBox(_this.domNode).h; + }; + //Define an area to make focusManager handle all the navigation stuff + g.focus.addArea({ + name: "filterbar", + onFocus: lang.hitch(this, this._onFocusFilterBar, false), + onBlur: lang.hitch(this, this._onBlurFilterBar) + }); + g.focus.placeArea("filterbar","after","header"); + }, + uninitialize: function(){ + var g = this.plugin.grid; + g._getHeaderHeight = this.oldGetHeaderHeight; + g.focus.removeArea("filterbar"); + this.plugin = null; + }, + isFilterBarShown: function(){ + return html.style(this.domNode, "display") != "none"; + }, + showFilterBar: function(toShow, useAnim, animArgs){ + var g = this.plugin.grid; + if(useAnim){ + if(Boolean(toShow) == this.isFilterBarShown()){ return; } + animArgs = animArgs || {}; + var anims = [], defaultDuration = 500; + anims.push(fx[toShow ? "wipeIn" : "wipeOut"](lang.mixin({ + "node": this.domNode, + "duration": defaultDuration + }, animArgs))); + var curHeight = g.views.views[0].domNode.offsetHeight; + var prop = { + "duration": defaultDuration, + "properties": { + "height": { + "end": lang.hitch(this, function(){ + var barHeight = this.domNode.scrollHeight; + if(has("ff")){ + barHeight -= 2; + } + return toShow ? (curHeight - barHeight) : (curHeight + barHeight); + }) + } + } + }; + array.forEach(g.views.views, function(view){ + anims.push(baseFx.animateProperty(lang.mixin({ + "node": view.domNode + }, prop, animArgs)), baseFx.animateProperty(lang.mixin({ + "node": view.scrollboxNode + }, prop, animArgs))); + }); + anims.push(baseFx.animateProperty(lang.mixin({ + "node": g.viewsNode + }, prop, animArgs))); + fx.combine(anims).play(); + }else{ + html.style(this.domNode, "display", toShow ? "" : "none"); + g.update(); + } + }, + toggleFilterBar: function(useAnim, animArgs){ + this.showFilterBar(!this.isFilterBarShown(), useAnim, animArgs); + }, + getColumnIdx: function(/* int */coordX){ + var headers = query("[role='columnheader']", this.plugin.grid.viewsHeaderNode); + var idx = -1; + for(var i = headers.length - 1; i >= 0; --i){ + var coord = html.position(headers[i]); + if(coordX >= coord.x && coordX < coord.x + coord.w){ + idx = i; + break; + } + } + if(idx >= 0 && this.plugin.grid.layout.cells[idx].filterable !== false){ + return idx; //Integer + }else{ + return -1; //Integer + } + }, + toggleClearFilterBtn: function(toHide){ + html.style(this.clearFilterButton.domNode, "display", toHide ? "none" : ""); + }, + _closeFilterBar: function(e){ + _stopEvent(e); + var rulesCnt = this.plugin.filterDefDialog.getCriteria(); + if(rulesCnt){ + var handle = connect.connect(this.plugin.filterDefDialog, "clearFilter", this, function(){ + this.showFilterBar(false, true); + connect.disconnect(handle); + }); + this._clearFilterDefDialog(e); + }else{ + this.showFilterBar(false, true); + } + }, + + _showFilterDefDialog: function(e){ + _stopEvent(e); + this.plugin.filterDefDialog.showDialog(this._curColIdx); + this.plugin.grid.focus.focusArea("filterbar"); + }, + _clearFilterDefDialog: function(e){ + _stopEvent(e); + this.plugin.filterDefDialog.onClearFilter(); + this.plugin.grid.focus.focusArea("filterbar"); + }, + _onEnterButton: function(e){ + //If mouse is hovering the btn, which means the user is about to click, + //we should not show status tip on the btn! + this._onBlurFilterBar(); + _stopEvent(e); + }, + _onMoveButton: function(e){ + this._onBlurFilterBar(); + }, + _onLeaveButton: function(e){ + this._leavingBtn = true; + }, + _onShowFilterDefDialog: function(/* Integer */colIdx){ + if(typeof colIdx == "number"){ + this._curColIdx = colIdx; + } + this._defPaneIsShown = true; + }, + _onCloseFilterDefDialog: function(){ + this._defPaneIsShown = false; + //Do not remember what column are we on, so clicking the btn will show 'any column' + this._curColIdx = -1; + dijitFocus.focus(this.defineFilterButton.domNode); + }, + _onClickFilterBar: function(/* event */e){ + _stopEvent(e); + this._clearStatusTipTimeout(); + this.plugin.grid.focus.focusArea("filterbar"); + this.plugin.filterDefDialog.showDialog(this.getColumnIdx(e.clientX)); + }, + _onMouseEnter: function(/* event */e){ + this._onFocusFilterBar(true, null); + this._updateTipPosition(e); + this._setStatusTipTimeout(); + }, + _onMouseMove: function(/* event */e){ + if(this._leavingBtn){ + this._onFocusFilterBar(true, null); + this._leavingBtn = false; + } + if(this._isFocused){ + this._setStatusTipTimeout(); + this._highlightHeader(this.getColumnIdx(e.clientX)); + if(this._handle_statusTooltip){ + this._updateTipPosition(e); + } + } + }, + _onMouseLeave: function(e){ + this._onBlurFilterBar(); + }, + _updateTipPosition: function(evt){ + this._tippos = { + x: evt.pageX, + y: evt.pageY + }; + }, + _onFocusFilterBar: function(highlightOnly, evt, step){ + if(!this.isFilterBarShown()){ + return false; + } + this._isFocused = true; + html.addClass(this.domNode,_focusClass); + if(!highlightOnly){ + var hasFilter = html.style(this.clearFilterButton.domNode, "display") !== "none"; + var hasCloseButton = html.style(this.closeFilterBarButton.domNode, "display") !== "none"; + if(typeof this._focusPos == "undefined"){ + if(step > 0){ + this._focusPos = 0; + }else{ + if(hasCloseButton){ + this._focusPos = 1; + }else{ + this._focusPos = 0; + } + if(hasFilter){ + ++this._focusPos; + } + } + } + if(this._focusPos === 0){ + dijitFocus.focus(this.defineFilterButton.focusNode); + }else if(this._focusPos === 1 && hasFilter){ + dijitFocus.focus(this.clearFilterButton.focusNode); + }else{ + dijitFocus.focus(this.closeFilterBarButton.focusNode); + } + } + _stopEvent(evt); + return true; + }, + _onBlurFilterBar: function(evt, step){ + if(this._isFocused){ + this._isFocused = false; + html.removeClass(this.domNode,_focusClass); + this._clearStatusTipTimeout(); + this._clearHeaderHighlight(); + } + var toBlur = true; + if(step){ + var buttonCount = 3; + if(html.style(this.closeFilterBarButton.domNode, "display") === "none"){ + --buttonCount; + } + if(html.style(this.clearFilterButton.domNode, "display") === "none"){ + --buttonCount; + } + if(buttonCount == 1){ + delete this._focusPos; + }else{ + var current = this._focusPos; + for(var next = current + step; next < 0; next += buttonCount){} + next %= buttonCount; + if((step > 0 && next < current) || (step < 0 && next > current)){ + delete this._focusPos; + }else{ + this._focusPos = next; + toBlur = false; + } + } + } + return toBlur; + }, + _onFiltered: function(/* int */filteredSize,/* int */originSize){ + var p = this.plugin, + itemsName = p.args.itemsName || p.nls["defaultItemsName"], + msg = "", g = p.grid, + filterLayer = g.layer("filter"); + if(filterLayer.filterDef()){ + msg = string.substitute(p.nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]); + html.addClass(this.domNode, _filteredClass); + }else{ + msg = string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]); + html.removeClass(this.domNode, _filteredClass); + } + this.statusBarNode.innerHTML = msg; + this._focusPos = 0; + }, + _initAriaInfo: function(){ + this.defineFilterButton.domNode.setAttribute("aria-label", this.plugin.nls["waiFilterBarDefButton"]); + this.clearFilterButton.domNode.setAttribute("aria-label", this.plugin.nls["waiFilterBarClearButton"]); + }, + _isInColumn: function(/* int */mousePos_x, /* domNode */headerNode, /* int */colIndex){ + var coord = html.position(headerNode); + return mousePos_x >= coord.x && mousePos_x < coord.x + coord.w; + }, + _setStatusTipTimeout: function(){ + this._clearStatusTipTimeout(); + if(!this._defPaneIsShown){ + this._handle_statusTooltip = setTimeout(lang.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip); + } + }, + _clearStatusTipTimeout: function(){ + clearTimeout(this._handle_statusTooltip); + this._handle_statusTooltip = null; + }, + _showStatusTooltip: function(){ + this._handle_statusTooltip = null; + this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x)); + }, + _highlightHeader: function(/* int */colIdx){ + if(colIdx != this._previousHeaderIdx){ + var g = this.plugin.grid, + cell = g.getCell(this._previousHeaderIdx); + if(cell){ + html.removeClass(cell.getHeaderNode(), "dojoxGridCellOver"); + } + cell = g.getCell(colIdx); + if(cell){ + html.addClass(cell.getHeaderNode(), "dojoxGridCellOver"); + } + this._previousHeaderIdx = colIdx; + } + }, + _clearHeaderHighlight: function(){ + if(typeof this._previousHeaderIdx != "undefined"){ + var g = this.plugin.grid, + cell = g.getCell(this._previousHeaderIdx); + if(cell){ + g.onHeaderCellMouseOut({ + cellNode: cell.getHeaderNode() + }); + } + delete this._previousHeaderIdx; + } + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js new file mode 100644 index 0000000..63297c0 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js @@ -0,0 +1,81 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/FilterBuilder", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "./_FilterExpr" +], function(declare, array, lang, exprs){ + +var bdr = function(opCls){ + return lang.partial(function(cls,operands){ + return new exprs[cls](operands); + },opCls); + }, + bdr_not = function(opCls){ + return lang.partial(function(cls,operands){ + return new exprs.LogicNOT(new exprs[cls](operands)); + },opCls); + }; +return declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, { + // summary: + // Create filter expression from a JSON object. + buildExpression: function(def){ + if("op" in def){ + return this.supportedOps[def.op.toLowerCase()](array.map(def.data, this.buildExpression, this)); + }else{ + var args = lang.mixin(this.defaultArgs[def.datatype], def.args || {}); + return new this.supportedTypes[def.datatype](def.data, def.isColumn, args); + } + }, + supportedOps: { + // summary: + // The builders of all supported operations + "equalto": bdr("EqualTo"), + "lessthan": bdr("LessThan"), + "lessthanorequalto": bdr("LessThanOrEqualTo"), + "largerthan": bdr("LargerThan"), + "largerthanorequalto": bdr("LargerThanOrEqualTo"), + "contains": bdr("Contains"), + "startswith": bdr("StartsWith"), + "endswith": bdr("EndsWith"), + "notequalto": bdr_not("EqualTo"), + "notcontains": bdr_not("Contains"), + "notstartswith": bdr_not("StartsWith"), + "notendswith": bdr_not("EndsWith"), + "isempty": bdr("IsEmpty"), + "range": function(operands){ + return new exprs.LogicALL( + new exprs.LargerThanOrEqualTo(operands.slice(0,2)), + new exprs.LessThanOrEqualTo(operands[0], operands[2]) + ); + }, + "logicany": bdr("LogicANY"), + "logicall": bdr("LogicALL") + }, + supportedTypes: { + "number": exprs.NumberExpr, + "string": exprs.StringExpr, + "boolean": exprs.BooleanExpr, + "date": exprs.DateExpr, + "time": exprs.TimeExpr + }, + defaultArgs: { + "boolean": { + "falseValue": "false", + "convert": function(dataValue, args){ + var falseValue = args.falseValue; + var trueValue = args.trueValue; + if(lang.isString(dataValue)){ + if(trueValue && dataValue.toLowerCase() == trueValue){ + return true; + } + if(falseValue && dataValue.toLowerCase() == falseValue){ + return false; + } + } + return !!dataValue; + } + } + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js new file mode 100644 index 0000000..7e49153 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js @@ -0,0 +1,1252 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/FilterDefDialog", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/lang", + "dojo/_base/event", + "dojo/_base/html", + "dojo/_base/sniff", + "dojo/cache", + "dojo/keys", + "dojo/string", + "dojo/window", + "dojo/date/locale", + "./FilterBuilder", + "../Dialog", + "dijit/form/ComboBox", + "dijit/form/TextBox", + "dijit/form/NumberTextBox", + "dijit/form/DateTextBox", + "dijit/form/TimeTextBox", + "dijit/form/Button", + "dijit/layout/AccordionContainer", + "dijit/layout/ContentPane", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/_WidgetsInTemplateMixin", + "dijit/focus", + "dojox/html/metrics", + "dijit/a11y", + "dijit/Tooltip", + "dijit/form/Select", + "dijit/form/RadioButton", + "dojox/html/ellipsis", + "../../../cells/dijit" +], function(declare, array, connect, lang, event, html, has, cache, keys, string, win, dateLocale, + FilterBuilder, Dialog, ComboBox, TextBox, NumberTextBox, DateTextBox, TimeTextBox, Button, + AccordionContainer, ContentPane, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, dijitFocus, metrics, dijitA11y){ + +var _tabIdxes = { + // summary: + // Define tabindexes for elements in the filter definition dialog + relSelect: 60, + accordionTitle: 70, + removeCBoxBtn: -1, + colSelect: 90, + condSelect: 95, + valueBox: 10, + addCBoxBtn: 20, + filterBtn: 30, + clearBtn: 40, + cancelBtn: 50 + }; +var FilterAccordionContainer = declare("dojox.grid.enhanced.plugins.filter.AccordionContainer", AccordionContainer, { + nls: null, + addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){ + var pane = arguments[0] = child._pane = new ContentPane({ + content: child + }); + this.inherited(arguments); + this._modifyChild(pane); + }, + removeChild: function(child){ + var pane = child, isRemoveByUser = false; + if(child._pane){ + isRemoveByUser = true; + pane = arguments[0] = child._pane; + } + this.inherited(arguments); + if(isRemoveByUser){ + this._hackHeight(false, this._titleHeight); + var children = this.getChildren(); + if(children.length === 1){ + html.style(children[0]._removeCBoxBtn.domNode, "display", "none"); + } + } + pane.destroyRecursive(); + }, + selectChild: function(child){ + if(child._pane){ + arguments[0] = child._pane; + } + this.inherited(arguments); + }, + resize: function(){ + this.inherited(arguments); + array.forEach(this.getChildren(), this._setupTitleDom); + }, + startup: function(){ + if(this._started){ + return; + } + this.inherited(arguments); + if(parseInt(has("ie"), 10) == 7){ + //IE7 will fire a lot of "onresize" event during initialization. + array.some(this._connects, function(cnnt){ + if(cnnt[0][1] == "onresize"){ + this.disconnect(cnnt); + return true; + } + }, this); + } + array.forEach(this.getChildren(), function(child){ + this._modifyChild(child, true); + }, this); + }, + _onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){ + // summary: + // Overrides base class method, make left/right button do other things. + if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){ + return; + } + var k = keys, c = e.charOrCode, ltr = html._isBodyLtr(), toNext = null; + if((fromTitle && c == k.UP_ARROW) || (e.ctrlKey && c == k.PAGE_UP)){ + toNext = false; + }else if((fromTitle && c == k.DOWN_ARROW) || (e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){ + toNext = true; + }else if(c == (ltr ? k.LEFT_ARROW : k.RIGHT_ARROW)){ + toNext = this._focusOnRemoveBtn ? null : false; + this._focusOnRemoveBtn = !this._focusOnRemoveBtn; + }else if(c == (ltr ? k.RIGHT_ARROW : k.LEFT_ARROW)){ + toNext = this._focusOnRemoveBtn ? true : null; + this._focusOnRemoveBtn = !this._focusOnRemoveBtn; + }else{ + return; + } + if(toNext !== null){ + this._adjacent(toNext)._buttonWidget._onTitleClick(); + } + event.stop(e); + win.scrollIntoView(this.selectedChildWidget._buttonWidget.domNode.parentNode); + if(has("ie")){ + //IE will not show focus indicator if tabIndex is -1 + this.selectedChildWidget._removeCBoxBtn.focusNode.setAttribute("tabIndex", this._focusOnRemoveBtn ? _tabIdxes.accordionTitle : -1); + } + dijitFocus.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode); + }, + _modifyChild: function(child, isFirst){ + if(!child || !this._started){ + return; + } + html.style(child.domNode, "overflow", "hidden"); + child._buttonWidget.connect(child._buttonWidget, "_setSelectedAttr", function(){ + this.focusNode.setAttribute("tabIndex", this.selected ? _tabIdxes.accordionTitle : "-1"); + }); + var _this = this; + child._buttonWidget.connect(child._buttonWidget.domNode, "onclick", function(){ + _this._focusOnRemoveBtn = false; + }); + (child._removeCBoxBtn = new Button({ + label: this.nls.removeRuleButton, + showLabel: false, + iconClass: "dojoxGridFCBoxRemoveCBoxBtnIcon", + tabIndex: _tabIdxes.removeCBoxBtn, + onClick: lang.hitch(child.content, "onRemove"), + onKeyPress: function(e){ + _this._onKeyPress(e, child._buttonWidget.contentWidget); + } + })).placeAt(child._buttonWidget.domNode); + var i, children = this.getChildren(); + if(children.length === 1){ + child._buttonWidget.set("selected", true); + html.style(child._removeCBoxBtn.domNode, "display", "none"); + }else{ + for(i = 0; i < children.length; ++i){ + if(children[i]._removeCBoxBtn){ + html.style(children[i]._removeCBoxBtn.domNode, "display", ""); + } + } + } + this._setupTitleDom(child); + if(!this._titleHeight){ + for(i = 0; i < children.length; ++i){ + if(children[i] != this.selectedChildWidget){ + this._titleHeight = html.marginBox(children[i]._buttonWidget.domNode.parentNode).h; + break; + } + } + } + if(!isFirst){ + this._hackHeight(true, this._titleHeight); + } + }, + _hackHeight: function(/* bool */toGrow,/* int */heightDif){ + var children = this.getChildren(), + dn = this.domNode, h = html.style(dn, "height"); + if(!toGrow){ + dn.style.height = (h - heightDif) + 'px'; + }else if(children.length > 1){ + dn.style.height = (h + heightDif) + 'px'; + }else{ + //Only one rule, no need to do anything. + return; + } + this.resize(); + }, + _setupTitleDom: function(child){ + var w = html.contentBox(child._buttonWidget.titleNode).w; + if(has("ie") < 8){ w -= 8; } + html.style(child._buttonWidget.titleTextNode, "width", w + "px"); + } +}); +var FilterDefPane = declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{ + templateString: cache("dojox.grid","enhanced/templates/FilterDefPane.html"), + widgetsInTemplate: true, + dlg: null, + postMixInProperties: function(){ + this.plugin = this.dlg.plugin; + var nls = this.plugin.nls; + this._addRuleBtnLabel = nls.addRuleButton; + this._cancelBtnLabel = nls.cancelButton; + this._clearBtnLabel = nls.clearButton; + this._filterBtnLabel = nls.filterButton; + this._relAll = nls.relationAll; + this._relAny = nls.relationAny; + this._relMsgFront = nls.relationMsgFront; + this._relMsgTail = nls.relationMsgTail; + }, + postCreate: function(){ + this.inherited(arguments); + this.connect(this.domNode, "onkeypress", "_onKey"); + (this.cboxContainer = new FilterAccordionContainer({ + nls: this.plugin.nls + })).placeAt(this.criteriaPane); + + this._relSelect.set("tabIndex", _tabIdxes.relSelect); + this._addCBoxBtn.set("tabIndex", _tabIdxes.addCBoxBtn); + this._cancelBtn.set("tabIndex", _tabIdxes.cancelBtn); + this._clearFilterBtn.set("tabIndex", _tabIdxes.clearBtn); + this._filterBtn.set("tabIndex", _tabIdxes.filterBtn); + + var nls = this.plugin.nls; + this._relSelect.domNode.setAttribute("aria-label", nls.waiRelAll); + this._addCBoxBtn.domNode.setAttribute("aria-label", nls.waiAddRuleButton); + this._cancelBtn.domNode.setAttribute("aria-label", nls.waiCancelButton); + this._clearFilterBtn.domNode.setAttribute("aria-label", nls.waiClearButton); + this._filterBtn.domNode.setAttribute("aria-label", nls.waiFilterButton); + + this._relSelect.set("value", this.dlg._relOpCls === "logicall" ? "0" : "1"); + }, + uninitialize: function(){ + this.cboxContainer.destroyRecursive(); + this.plugin = null; + this.dlg = null; + }, + _onRelSelectChange: function(val){ + this.dlg._relOpCls = val == "0" ? "logicall" : "logicany"; + this._relSelect.domNode.setAttribute("aria-label", this.plugin.nls[val == "0" ? "waiRelAll" : "waiRelAny"]); + }, + _onAddCBox: function(){ + this.dlg.addCriteriaBoxes(1); + }, + _onCancel: function(){ + this.dlg.onCancel(); + }, + _onClearFilter: function(){ + this.dlg.onClearFilter(); + }, + _onFilter: function(){ + this.dlg.onFilter(); + }, + _onKey: function(e){ + if(e.keyCode == keys.ENTER){ + this.dlg.onFilter(); + } + } +}); +var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{ + templateString: cache("dojox.grid","enhanced/templates/CriteriaBox.html"), + widgetsInTemplate: true, + dlg: null, + postMixInProperties: function(){ + this.plugin = this.dlg.plugin; + this._curValueBox = null; + + var nls = this.plugin.nls; + this._colSelectLabel = nls.columnSelectLabel; + this._condSelectLabel = nls.conditionSelectLabel; + this._valueBoxLabel = nls.valueBoxLabel; + this._anyColumnOption = nls.anyColumnOption; + }, + postCreate: function(){ + var dlg = this.dlg, g = this.plugin.grid; + //Select Column + this._colSelect.set("tabIndex", _tabIdxes.colSelect); + this._colOptions = this._getColumnOptions(); + this._colSelect.addOption([ + {label: this.plugin.nls.anyColumnOption, value: "anycolumn", selected: dlg.curColIdx < 0}, + {value: ""} + ].concat(this._colOptions)); + //Select Condition + this._condSelect.set("tabIndex", _tabIdxes.condSelect); + this._condSelect.addOption(this._getUsableConditions(dlg.getColumnType(dlg.curColIdx))); + this._showSelectOrLabel(this._condSelect, this._condSelectAlt); + + this.connect(g.layout, "moveColumn", "onMoveColumn"); + }, + _getColumnOptions: function(){ + var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn"; + return array.map(array.filter(this.plugin.grid.layout.cells, function(cell){ + return !(cell.filterable === false || cell.hidden); + }), function(cell){ + return { + label: cell.name || cell.field, + value: String(cell.index), + selected: colIdx == String(cell.index) + }; + }); + }, + onMoveColumn: function(){ + var tmp = this._onChangeColumn; + this._onChangeColumn = function(){}; + var option = this._colSelect.get("selectedOptions"); + this._colSelect.removeOption(this._colOptions); + this._colOptions = this._getColumnOptions(); + this._colSelect.addOption(this._colOptions); + var i = 0; + for(; i < this._colOptions.length; ++i){ + if(this._colOptions[i].label == option.label){ + break; + } + } + if(i < this._colOptions.length){ + this._colSelect.set("value", this._colOptions[i].value); + } + var _this = this; + setTimeout(function(){ + _this._onChangeColumn = tmp; + }, 0); + }, + onRemove: function(){ + this.dlg.removeCriteriaBoxes(this); + }, + uninitialize: function(){ + if(this._curValueBox){ + this._curValueBox.destroyRecursive(); + this._curValueBox = null; + } + this.plugin = null; + this.dlg = null; + }, + _showSelectOrLabel: function(sel, alt){ + var options = sel.getOptions(); + if(options.length == 1){ + alt.innerHTML = options[0].label; + html.style(sel.domNode, "display", "none"); + html.style(alt, "display", ""); + }else{ + html.style(sel.domNode, "display", ""); + html.style(alt, "display", "none"); + } + }, + _onChangeColumn: function(val){ + this._checkValidCriteria(); + var type = this.dlg.getColumnType(val); + this._setConditionsByType(type); + this._setValueBoxByType(type); + this._updateValueBox(); + }, + _onChangeCondition: function(val){ + this._checkValidCriteria(); + var f = (val == "range"); + if(f ^ this._isRange){ + this._isRange = f; + this._setValueBoxByType(this.dlg.getColumnType(this._colSelect.get("value"))); + } + this._updateValueBox(); + }, + _updateValueBox: function(cond){ + this._curValueBox.set("disabled", this._condSelect.get("value") == "isempty"); + }, + _checkValidCriteria: function(){ + // summary: + // Check whether the given criteria box is completed. If it is, mark it. + setTimeout(lang.hitch(this, function(){ + this.updateRuleTitle(); + this.dlg._updatePane(); + }),0); + }, + _createValueBox: function(/* widget constructor */cls,/* object */arg){ + // summary: + // Create a value input box with given class and arguments + var func = lang.hitch(arg.cbox, "_checkValidCriteria"); + return new cls(lang.mixin(arg,{ + tabIndex: _tabIdxes.valueBox, + onKeyPress: func, + onChange: func, + "class": "dojoxGridFCBoxValueBox" + })); + }, + _createRangeBox: function(/* widget constructor */cls,/* object */arg){ + // summary: + // Create a DIV containing 2 input widgets, which represents a range, with the given class and arguments + var func = lang.hitch(arg.cbox, "_checkValidCriteria"); + lang.mixin(arg,{ + tabIndex: _tabIdxes.valueBox, + onKeyPress: func, + onChange: func + }); + var div = html.create("div", {"class": "dojoxGridFCBoxValueBox"}), + start = new cls(arg), + txt = html.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}), + end = new cls(arg); + html.addClass(start.domNode, "dojoxGridFCBoxStartValue"); + html.addClass(end.domNode, "dojoxGridFCBoxEndValue"); + div.appendChild(start.domNode); + div.appendChild(txt); + div.appendChild(end.domNode); + div.domNode = div; + //Mock functions for set and get (in place of the old attr function) + div.set = function(dummy, args){ + if(lang.isObject(args)){ + start.set("value", args.start); + end.set("value", args.end); + } + }; + div.get = function(){ + var s = start.get("value"), + e = end.get("value"); + return s && e ? {start: s, end: e} : ""; + }; + return div; + }, + changeCurrentColumn: function(/* bool */selectCurCol){ + var colIdx = this.dlg.curColIdx; + //Re-populate the columns in case some of them are set to hidden. + this._colSelect.removeOption(this._colOptions); + this._colOptions = this._getColumnOptions(); + this._colSelect.addOption(this._colOptions); + this._colSelect.set('value', colIdx >= 0 ? String(colIdx) : "anycolumn"); + this.updateRuleTitle(true); + }, + curColumn: function(){ + return this._colSelect.getOptions(this._colSelect.get("value")).label; + }, + curCondition: function(){ + return this._condSelect.getOptions(this._condSelect.get("value")).label; + }, + curValue: function(){ + var cond = this._condSelect.get("value"); + if(cond == "isempty"){return "";} + return this._curValueBox ? this._curValueBox.get("value") : ""; + }, + save: function(){ + if(this.isEmpty()){ + return null; + } + var colIdx = this._colSelect.get("value"), + type = this.dlg.getColumnType(colIdx), + value = this.curValue(), + cond = this._condSelect.get("value"); + return { + "column": colIdx, + "condition": cond, + "value": value, + "formattedVal": this.formatValue(type, cond, value), + "type": type, + "colTxt": this.curColumn(), + "condTxt": this.curCondition() + }; + }, + load: function(obj){ + var tmp = [ + this._onChangeColumn, + this._onChangeCondition + ]; + this._onChangeColumn = this._onChangeCondition = function(){}; + if(obj.column){ + this._colSelect.set("value", obj.column); + } + if(obj.condition){ + this._condSelect.set("value", obj.condition); + } + if(obj.type){ + this._setValueBoxByType(obj.type); + }else{ + obj.type = this.dlg.getColumnType(this._colSelect.get("value")); + } + var value = obj.value || ""; + if(value || (obj.type != "date" && obj.type != "time")){ + this._curValueBox.set("value", value); + } + this._updateValueBox(); + setTimeout(lang.hitch(this, function(){ + this._onChangeColumn = tmp[0]; + this._onChangeCondition = tmp[1]; + }), 0); + }, + getExpr: function(){ + if(this.isEmpty()){ + return null; + } + var colval = this._colSelect.get("value"); + return this.dlg.getExprForCriteria({ + "type": this.dlg.getColumnType(colval), + "column": colval, + "condition": this._condSelect.get("value"), + "value": this.curValue() + }); + }, + isEmpty: function(){ + var cond = this._condSelect.get("value"); + if(cond == "isempty"){return false;} + var v = this.curValue(); + return v === "" || v === null || typeof v == "undefined" || (typeof v == "number" && isNaN(v)); + }, + updateRuleTitle: function(isEmpty){ + var node = this._pane._buttonWidget.titleTextNode; + var title = [ + "<div class='dojoxEllipsis'>" + ]; + if(isEmpty || this.isEmpty()){ + node.title = string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]); + title.push(node.title); + }else{ + var type = this.dlg.getColumnType(this._colSelect.get("value")); + var column = this.curColumn(); + var condition = this.curCondition(); + var value = this.formatValue(type, this._condSelect.get("value"), this.curValue()); + title.push( + column, + " <span class='dojoxGridRuleTitleCondition'>", + condition, + "</span> ", + value + ); + node.title = [column, " ", condition, " ", value].join(''); + } + node.innerHTML = title.join(''); + if(has("mozilla")){ + var tt = html.create("div", { + "style": "width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9999;" + }, node); + tt.title = node.title; + } + }, + updateRuleIndex: function(index){ + if(this._ruleIndex != index){ + this._ruleIndex = index; + if(this.isEmpty()){ + this.updateRuleTitle(); + } + } + }, + setAriaInfo: function(idx){ + var dss = string.substitute, nls = this.plugin.nls; + this._colSelect.domNode.setAttribute("aria-label", dss(nls.waiColumnSelectTemplate, [idx])); + this._condSelect.domNode.setAttribute("aria-label", dss(nls.waiConditionSelectTemplate, [idx])); + this._pane._removeCBoxBtn.domNode.setAttribute("aria-label", dss(nls.waiRemoveRuleButtonTemplate, [idx])); + this._index = idx; + }, + _getUsableConditions: function(type){ + var conditions = lang.clone(this.dlg._dataTypeMap[type].conditions); + var typeDisabledConds = (this.plugin.args.disabledConditions || {})[type]; + var colIdx = parseInt(this._colSelect.get("value"), 10); + var colDisabledConds = isNaN(colIdx) ? + (this.plugin.args.disabledConditions || {})["anycolumn"] : + this.plugin.grid.layout.cells[colIdx].disabledConditions; + if(!lang.isArray(typeDisabledConds)){ + typeDisabledConds = []; + } + if(!lang.isArray(colDisabledConds)){ + colDisabledConds = []; + } + var arr = typeDisabledConds.concat(colDisabledConds); + if(arr.length){ + var disabledConds = {}; + array.forEach(arr, function(c){ + if(lang.isString(c)){ + disabledConds[c.toLowerCase()] = true; + } + }); + return array.filter(conditions, function(condOption){ + return !(condOption.value in disabledConds); + }); + } + return conditions; + }, + _setConditionsByType: function(/* string */type){ + var condSelect = this._condSelect; + condSelect.removeOption(condSelect.options); + condSelect.addOption(this._getUsableConditions(type)); + this._showSelectOrLabel(this._condSelect, this._condSelectAlt); + }, + _setValueBoxByType: function(/* string */type){ + if(this._curValueBox){ + this.valueNode.removeChild(this._curValueBox.domNode); + try{ + this._curValueBox.destroyRecursive(); + }catch(e){} + delete this._curValueBox; + } + //value box class + var vbcls = this.dlg._dataTypeMap[type].valueBoxCls[this._getValueBoxClsInfo(this._colSelect.get("value"), type)], + vboxArg = this._getValueBoxArgByType(type); + this._curValueBox = this[this._isRange ? "_createRangeBox" : "_createValueBox"](vbcls, vboxArg); + this.valueNode.appendChild(this._curValueBox.domNode); + + //Can not move to setAriaInfo, 'cause the value box is created after the defpane is loaded. + this._curValueBox.domNode.setAttribute("aria-label", string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index])); + //Now our cbox is completely ready + this.dlg.onRendered(this); + }, + //--------------------------UI Configuration-------------------------------------- + _getValueBoxArgByType: function(/* string */type){ + // summary: + // Get the arguments for the value box construction. + var g = this.plugin.grid, + cell = g.layout.cells[parseInt(this._colSelect.get("value"), 10)], + res = { + cbox: this + }; + if(type == "string"){ + if(cell && (cell.suggestion || cell.autoComplete)){ + html.mixin(res, { + store: g.store, + searchAttr: cell.field || cell.name, + fetchProperties: { + sort: [{"attribute": cell.field || cell.name}], + query: g.query, + queryOptions: g.queryOptions + } + }); + } + }else if(type == "boolean"){ + html.mixin(res, this.dlg.builder.defaultArgs["boolean"]); + } + if(cell && cell.dataTypeArgs){ + html.mixin(res, cell.dataTypeArgs); + } + return res; + }, + formatValue: function(type, cond, v){ + // summary: + // Format the value to be shown in tooltip. + if(cond == "isempty"){return "";} + if(type == "date" || type == "time"){ + var opt = {selector: type}, + fmt = dateLocale.format; + if(cond == "range"){ + return string.substitute(this.plugin.nls.rangeTemplate, [fmt(v.start, opt), fmt(v.end, opt)]); + } + return fmt(v, opt); + }else if(type == "boolean"){ + return v ? this._curValueBox._lblTrue : this._curValueBox._lblFalse; + } + return v; + }, + _getValueBoxClsInfo: function(/* int|string */colIndex, /* string */type){ + // summary: + // Decide which value box to use given data type and column index. + var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)]; + //Now we only need to handle string. But maybe we need to handle more types here in the future. + if(type == "string"){ + return (cell && (cell.suggestion || cell.autoComplete)) ? "ac" : "dft"; + } + return "dft"; + } +}); + + +var UniqueComboBox = declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox", ComboBox, { + _openResultList: function(results){ + var cache = {}, s = this.store, colName = this.searchAttr; + arguments[0] = array.filter(results, function(item){ + var key = s.getValue(item, colName), existed = cache[key]; + cache[key] = true; + return !existed; + }); + this.inherited(arguments); + }, + _onKey: function(evt){ + if(evt.charOrCode === keys.ENTER && this._opened){ + event.stop(evt); + } + this.inherited(arguments); + } +}); +var BooleanValueBox = declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], { + templateString: cache("dojox.grid","enhanced/templates/FilterBoolValueBox.html"), + widgetsInTemplate: true, + constructor: function(args){ + var nls = args.cbox.plugin.nls; + this._baseId = args.cbox.id; + this._lblTrue = args.trueLabel || nls.trueLabel || "true"; + this._lblFalse = args.falseLabel || nls.falseLabel || "false"; + this.args = args; + }, + postCreate: function(){ + this.onChange(); + }, + onChange: function(){}, + + get: function(prop){ + return this.rbTrue.get("checked"); + }, + set: function(prop, v){ + this.inherited(arguments); + if(prop == "value"){ + this.rbTrue.set("checked", !!v); + this.rbFalse.set("checked", !v); + } + } +}); +var FilterDefDialog = declare("dojox.grid.enhanced.plugins.filter.FilterDefDialog", null, { + // summary: + // Create the filter definition UI. + curColIdx: -1, + _relOpCls: "logicall", + _savedCriterias: null, + plugin: null, + constructor: function(args){ + var plugin = this.plugin = args.plugin; + this.builder = new FilterBuilder(); + this._setupData(); + this._cboxes = []; + this.defaultType = plugin.args.defaultType || "string"; + + (this.filterDefPane = new FilterDefPane({ + "dlg": this + })).startup(); + (this._defPane = new Dialog({ + "refNode": this.plugin.grid.domNode, + "title": plugin.nls.filterDefDialogTitle, + "class": "dojoxGridFDTitlePane", + "iconClass": "dojoxGridFDPaneIcon", + "content": this.filterDefPane + })).startup(); + + this._defPane.connect(plugin.grid.layer('filter'), "filterDef", lang.hitch(this, "_onSetFilter")); + plugin.grid.setFilter = lang.hitch(this, "setFilter"); + plugin.grid.getFilter = lang.hitch(this, "getFilter"); + plugin.grid.getFilterRelation = lang.hitch(this, function(){ + return this._relOpCls; + }); + + plugin.connect(plugin.grid.layout, "moveColumn", lang.hitch(this, "onMoveColumn")); + }, + onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){ + if(this._savedCriterias && cellIndex != targetIndex){ + if(before){ --targetIndex; } + var min = cellIndex < targetIndex ? cellIndex : targetIndex; + var max = cellIndex < targetIndex ? targetIndex : cellIndex; + var dir = targetIndex > min ? 1 : -1; + array.forEach(this._savedCriterias, function(sc){ + var idx = parseInt(sc.column, 10); + if(!isNaN(idx) && idx >= min && idx <= max){ + sc.column = String(idx == cellIndex ? idx + (max - min) * dir : idx - dir); + } + }); + } + }, + destroy: function(){ + this._defPane.destroyRecursive(); + this._defPane = null; + this.filterDefPane = null; + this.builder = null; + this._dataTypeMap = null; + this._cboxes = null; + var g = this.plugin.grid; + g.setFilter = null; + g.getFilter = null; + g.getFilterRelation = null; + this.plugin = null; + }, + _setupData: function(){ + var nls = this.plugin.nls; + this._dataTypeMap = { + // summary: + // All supported data types + "number":{ + valueBoxCls: { + dft: NumberTextBox + }, + conditions:[ + {label: nls.conditionEqual, value: "equalto", selected: true}, + {label: nls.conditionNotEqual, value: "notequalto"}, + {label: nls.conditionLess, value: "lessthan"}, + {label: nls.conditionLessEqual, value: "lessthanorequalto"}, + {label: nls.conditionLarger, value: "largerthan"}, + {label: nls.conditionLargerEqual, value: "largerthanorequalto"}, + {label: nls.conditionIsEmpty, value: "isempty"} + ] + }, + "string":{ + valueBoxCls: { + dft: TextBox, + ac: UniqueComboBox //For autoComplete + }, + conditions:[ + {label: nls.conditionContains, value: "contains", selected: true}, + {label: nls.conditionIs, value: "equalto"}, + {label: nls.conditionStartsWith, value: "startswith"}, + {label: nls.conditionEndWith, value: "endswith"}, + {label: nls.conditionNotContain, value: "notcontains"}, + {label: nls.conditionIsNot, value: "notequalto"}, + {label: nls.conditionNotStartWith, value: "notstartswith"}, + {label: nls.conditionNotEndWith, value: "notendswith"}, + {label: nls.conditionIsEmpty, value: "isempty"} + ] + }, + "date":{ + valueBoxCls: { + dft: DateTextBox + }, + conditions:[ + {label: nls.conditionIs, value: "equalto", selected: true}, + {label: nls.conditionBefore, value: "lessthan"}, + {label: nls.conditionAfter, value: "largerthan"}, + {label: nls.conditionRange, value: "range"}, + {label: nls.conditionIsEmpty, value: "isempty"} + ] + }, + "time":{ + valueBoxCls: { + dft: TimeTextBox + }, + conditions:[ + {label: nls.conditionIs, value: "equalto", selected: true}, + {label: nls.conditionBefore, value: "lessthan"}, + {label: nls.conditionAfter, value: "largerthan"}, + {label: nls.conditionRange, value: "range"}, + {label: nls.conditionIsEmpty, value: "isempty"} + ] + }, + "boolean": { + valueBoxCls: { + dft: BooleanValueBox + }, + conditions: [ + {label: nls.conditionIs, value: "equalto", selected: true}, + {label: nls.conditionIsEmpty, value: "isempty"} + ] + } + }; + }, + setFilter: function(rules, ruleRelation){ + rules = rules || []; + if(!lang.isArray(rules)){ + rules = [rules]; + } + var func = function(){ + if(rules.length){ + this._savedCriterias = array.map(rules, function(rule){ + var type = rule.type || this.defaultType; + return { + "type": type, + "column": String(rule.column), + "condition": rule.condition, + "value": rule.value, + "colTxt": this.getColumnLabelByValue(String(rule.column)), + "condTxt": this.getConditionLabelByValue(type, rule.condition), + "formattedVal": rule.formattedVal || rule.value + }; + }, this); + this._criteriasChanged = true; + if(ruleRelation === "logicall" || ruleRelation === "logicany"){ + this._relOpCls = ruleRelation; + } + var exprs = array.map(rules, this.getExprForCriteria, this); + exprs = this.builder.buildExpression(exprs.length == 1 ? exprs[0] : { + "op": this._relOpCls, + "data": exprs + }); + this.plugin.grid.layer("filter").filterDef(exprs); + this.plugin.filterBar.toggleClearFilterBtn(false); + } + this._closeDlgAndUpdateGrid(); + }; + if(this._savedCriterias){ + this._clearWithoutRefresh = true; + var handle = connect.connect(this, "clearFilter", this, function(){ + connect.disconnect(handle); + this._clearWithoutRefresh = false; + func.apply(this); + }); + this.onClearFilter(); + }else{ + func.apply(this); + } + }, + getFilter: function(){ + return lang.clone(this._savedCriterias) || []; + }, + getColumnLabelByValue: function(v){ + var nls = this.plugin.nls; + if(v.toLowerCase() == "anycolumn"){ + return nls["anyColumnOption"]; + }else{ + var cell = this.plugin.grid.layout.cells[parseInt(v, 10)]; + return cell ? (cell.name || cell.field) : ""; + } + }, + getConditionLabelByValue: function(type, c){ + var conditions = this._dataTypeMap[type].conditions; + for(var i = conditions.length - 1; i >= 0; --i){ + var cond = conditions[i]; + if(cond.value == c.toLowerCase()){ + return cond.label; + } + } + return ""; + }, + addCriteriaBoxes: function(/* int */cnt){ + // summary: + // Add *cnt* criteria boxes to the filter definition pane. + // Check overflow if necessary. + if(typeof cnt != "number" || cnt <= 0){ + return; + } + var cbs = this._cboxes, + cc = this.filterDefPane.cboxContainer, + total = this.plugin.args.ruleCount, + len = cbs.length, cbox; + //If overflow, add to max rule count. + if(total > 0 && len + cnt > total){ + cnt = total - len; + } + for(; cnt > 0; --cnt){ + cbox = new CriteriaBox({ + dlg: this + }); + cbs.push(cbox); + cc.addChild(cbox); + } + //If there's no content box in it , AccordionContainer can not startup + cc.startup(); + this._updatePane(); + this._updateCBoxTitles(); + cc.selectChild(cbs[cbs.length-1]); + //Asign an impossibly large scrollTop to scroll the criteria pane to the bottom. + this.filterDefPane.criteriaPane.scrollTop = 1000000; + if(cbs.length === 4){ + if(has("ie") <= 6 && !this.__alreadyResizedForIE6){ + var size = html.position(cc.domNode); + size.w -= metrics.getScrollbar().w; + cc.resize(size); + this.__alreadyResizedForIE6 = true; + }else{ + cc.resize(); + } + } + }, + removeCriteriaBoxes: function(/* int|CriteriaBox|int[] */cnt,/* bool? */isIdx){ + // summary: + // Remove criteria boxes from the filter definition pane. + var cbs = this._cboxes, cc = this.filterDefPane.cboxContainer, + len = cbs.length, start = len - cnt, + end = len - 1, cbox, + curIdx = array.indexOf(cbs, cc.selectedChildWidget.content); + if(lang.isArray(cnt)){ + var i, idxes = cnt; + idxes.sort(); + cnt = idxes.length; + //find a rule that's not deleted. + //must find and focus the last one, or the hack will not work. + for(i = len - 1; i >= 0 && array.indexOf(idxes, i) >= 0; --i){} + if(i >= 0){ + //must select before remove + if(i != curIdx){ + cc.selectChild(cbs[i]); + } + //idxes is sorted from small to large, + //so travel reversely won't need change index after delete from array. + for(i = cnt-1; i >= 0; --i){ + if(idxes[i] >= 0 && idxes[i] < len){ + cc.removeChild(cbs[idxes[i]]); + cbs.splice(idxes[i],1); + } + } + } + start = cbs.length; + }else{ + if(isIdx === true){ + if(cnt >= 0 && cnt < len){ + start = end = cnt; + cnt = 1; + }else{ + return; + } + }else{ + if(cnt instanceof CriteriaBox){ + cbox = cnt; + cnt = 1; + start = end = array.indexOf(cbs, cbox); + }else if(typeof cnt != "number" || cnt <= 0){ + return; + }else if(cnt >= len){ + cnt = end; + start = 1; + } + } + if(end < start){ + return; + } + //must select before remove + if(curIdx >= start && curIdx <= end){ + cc.selectChild(cbs[start ? start-1 : end+1]); + } + for(; end >= start; --end){ + cc.removeChild(cbs[end]); + } + cbs.splice(start, cnt); + } + this._updatePane(); + this._updateCBoxTitles(); + if(cbs.length === 3){ + //In ie6, resize back to the normal width will cause the title button look strange. + cc.resize(); + } + }, + getCriteria: function(/* int */idx){ + // summary: + // Get the *idx*-th criteria. + if(typeof idx != "number"){ + return this._savedCriterias ? this._savedCriterias.length : 0; + } + if(this._savedCriterias && this._savedCriterias[idx]){ + return lang.mixin({ + relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or + },this._savedCriterias[idx]); + } + return null; + }, + getExprForCriteria: function(rule){ + if(rule.column == "anycolumn"){ + var cells = array.filter(this.plugin.grid.layout.cells, function(cell){ + return !(cell.filterable === false || cell.hidden); + }); + return { + "op": "logicany", + "data": array.map(cells, function(cell){ + return this.getExprForColumn(rule.value, cell.index, rule.type, rule.condition); + }, this) + }; + }else{ + return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition); + } + }, + getExprForColumn: function(value, colIdx, type, condition){ + colIdx = parseInt(colIdx, 10); + var cell = this.plugin.grid.layout.cells[colIdx], + colName = cell.field || cell.name, + obj = { + "datatype": type || this.getColumnType(colIdx), + "args": cell.dataTypeArgs, + "isColumn": true + }, + operands = [lang.mixin({"data": this.plugin.args.isServerSide ? colName : cell}, obj)]; + obj.isColumn = false; + if(condition == "range"){ + operands.push(lang.mixin({"data": value.start}, obj), + lang.mixin({"data": value.end}, obj)); + }else if(condition != "isempty"){ + operands.push(lang.mixin({"data": value}, obj)); + } + return { + "op": condition, + "data": operands + }; + }, + getColumnType: function(/* int */colIndex){ + var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)]; + if(!cell || !cell.datatype){ + return this.defaultType; + } + var type = String(cell.datatype).toLowerCase(); + return this._dataTypeMap[type] ? type : this.defaultType; + }, + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + clearFilter: function(noRefresh){ + // summary: + // Clear filter definition. + if(!this._savedCriterias){ + return; + } + this._savedCriterias = null; + this.plugin.grid.layer("filter").filterDef(null); + try{ + this.plugin.filterBar.toggleClearFilterBtn(true); + this.filterDefPane._clearFilterBtn.set("disabled", true); + this.removeCriteriaBoxes(this._cboxes.length-1); + this._cboxes[0].load({}); + }catch(e){ + //Any error means the filter is defined outside this plugin. + } + if(noRefresh){ + this.closeDialog(); + }else{ + this._closeDlgAndUpdateGrid(); + } + }, + showDialog: function(/* int */colIndex){ + // summary: + // Show the filter defintion dialog. + this._defPane.show(); + this.plugin.filterStatusTip.closeDialog(); + this._prepareDialog(colIndex); + }, + closeDialog: function(){ + // summary: + // Close the filter definition dialog. + if(this._defPane.open){ + this._defPane.hide(); + } + }, + onFilter: function(e){ + // summary: + // Triggered when the "Filter" button is clicked. + if(this.canFilter()){ + this._defineFilter(); + this._closeDlgAndUpdateGrid(); + this.plugin.filterBar.toggleClearFilterBtn(false); + } + }, + onClearFilter: function(e){ + // summary: + // Triggered when the "Clear" button is clicked. + if(this._savedCriterias){ + if(this._savedCriterias.length >= this.plugin.ruleCountToConfirmClearFilter){ + this.plugin.clearFilterDialog.show(); + }else{ + this.clearFilter(this._clearWithoutRefresh); + } + } + }, + onCancel: function(e){ + // summary: + // Triggered when the "Cancel" buttton is clicked. + var sc = this._savedCriterias; + var cbs = this._cboxes; + if(sc){ + this.addCriteriaBoxes(sc.length - cbs.length); + this.removeCriteriaBoxes(cbs.length - sc.length); + array.forEach(sc, function(c, i){ + cbs[i].load(c); + }); + }else{ + this.removeCriteriaBoxes(cbs.length - 1); + cbs[0].load({}); + } + this.closeDialog(); + }, + onRendered: function(cbox){ + // summary: + // Triggered when the rendering of the filter definition dialog is completely finished. + // cbox: + // Current visible criteria box + if(!has("ff")){ + var elems = dijitA11y._getTabNavigable(html.byId(cbox.domNode)); + dijitFocus.focus(elems.lowest || elems.first); + }else{ + var dp = this._defPane; + dp._getFocusItems(dp.domNode); + dijitFocus.focus(dp._firstFocusItem); + } + }, + _onSetFilter: function(filterDef){ + // summary: + // If someone clear the filter def in the store directly, we must clear it in the UI. + // If someone defines a filter, don't know how to handle it! + if(filterDef === null && this._savedCriterias){ + this.clearFilter(); + } + }, + _prepareDialog: function(/* int */colIndex){ + var sc = this._savedCriterias, + cbs = this._cboxes, i, cbox; + this.curColIdx = colIndex; + if(!sc){ + if(cbs.length === 0){ + this.addCriteriaBoxes(1); + }else{ + //Re-populate columns anyway, because we don't know when the column is set to hidden. + for(i = 0; (cbox = cbs[i]); ++i){ + cbox.changeCurrentColumn(); + } + } + }else if(this._criteriasChanged){ + this.filterDefPane._relSelect.set("value", this._relOpCls === "logicall" ? "0" : "1"); + this._criteriasChanged = false; + var needNewCBox = sc.length > cbs.length ? sc.length - cbs.length : 0; + this.addCriteriaBoxes(needNewCBox); + this.removeCriteriaBoxes(cbs.length - sc.length); + this.filterDefPane._clearFilterBtn.set("disabled", false); + for(i = 0; i < cbs.length - needNewCBox; ++i){ + cbs[i].load(sc[i]); + } + if(needNewCBox > 0){ + var handled = [], handle = connect.connect(this, "onRendered", function(cbox){ + var i = array.indexOf(cbs, cbox); + if(!handled[i]){ + handled[i] = true; + if(--needNewCBox === 0){ + connect.disconnect(handle); + } + cbox.load(sc[i]); + } + }); + } + } + //Since we're allowed to remove cboxes when the definition pane is not shown, + //we have to resize the container to have a correct _verticalSpace. + this.filterDefPane.cboxContainer.resize(); + }, + _defineFilter: function(){ + var cbs = this._cboxes, + filterCboxes = function(method){ + return array.filter(array.map(cbs, function(cbox){ + return cbox[method](); + }), function(result){ + return !!result; + }); + }, + exprs = filterCboxes("getExpr"); + this._savedCriterias = filterCboxes("save"); + exprs = exprs.length == 1 ? exprs[0] : { + "op": this._relOpCls, + "data": exprs + }; + exprs = this.builder.buildExpression(exprs); + + this.plugin.grid.layer("filter").filterDef(exprs); + this.filterDefPane._clearFilterBtn.set("disabled", false); + }, + _updateCBoxTitles: function(){ + for(var cbs = this._cboxes, i = cbs.length; i > 0; --i){ + cbs[i - 1].updateRuleIndex(i); + cbs[i - 1].setAriaInfo(i); + } + }, + _updatePane: function(){ + var cbs = this._cboxes, + defPane = this.filterDefPane; + defPane._addCBoxBtn.set("disabled", cbs.length == this.plugin.args.ruleCount); + defPane._filterBtn.set("disabled", !this.canFilter()); + }, + canFilter: function(){ + return array.filter(this._cboxes, function(cbox){ + return !cbox.isEmpty(); + }).length > 0; + }, + _closeDlgAndUpdateGrid: function(){ + this.closeDialog(); + var g = this.plugin.grid; + g.showMessage(g.loadingMessage); + setTimeout(lang.hitch(g, g._refresh), this._defPane.duration + 10); + } +}); + +return FilterDefDialog; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js new file mode 100644 index 0000000..e8f7ac4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js @@ -0,0 +1,411 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/FilterLayer", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/window", + "dojo/_base/json", + "../_StoreLayer" +], function(declare, lang, win, json, layers){ + + var cmdSetFilter = "filter", + cmdClearFilter = "clear", + hitchIfCan = function(scope, func){ + return func ? lang.hitch(scope || win.global, func) : function(){}; + }, + shallowClone = function(obj){ + var res = {}; + if(obj && lang.isObject(obj)){ + for(var name in obj){ + res[name] = obj[name]; + } + } + return res; + }; + var _FilterLayerMixin = declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, { +/*===== + // _filter: _ConditionExpr + // The filter definition + _filter: null, + + filterDef: function(filter){ + // summary: + // Get/set/clear the filter definition + // tags: + // public + // filter: (_ConditionExpr|null)? + // null: clear filter definition + // undefined: it's getter + // returns: + // A filter definition if it's getter. + }, +=====*/ + tags: ["sizeChange"], + name: function(){ + // summary: + // override from _StoreLayer.name + return "filter"; //string + }, + onFilterDefined: function(filter){}, + + onFiltered: function(filteredSize, totalSize){ + // summary: + // Called when store data is filtered. This event is before *onComplete*, after *onBegin*. + // tags: + // callback extension + // filteredSize: Integer + // The number of remaining fetched items after filtering. + // totalSize: Integer + // The number of original fetched items. + } + }); + var ServerSideFilterLayer = declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [layers._ServerSideLayer, _FilterLayerMixin], { + constructor: function(args){ + this._onUserCommandLoad = args.setupFilterQuery || this._onUserCommandLoad; + this.filterDef(null); + }, + filterDef: function(/* (_ConditionExpr|null)? */filter){ + // summary: + // See _FilterLayerMixin.filterDef + if(filter){ + this._filter = filter; + var obj = filter.toObject(); + //Stateless implementation will need to parse the filter object. + this.command(cmdSetFilter, this._isStateful ? json.toJson(obj) : obj); + this.command(cmdClearFilter, null); + this.useCommands(true); + this.onFilterDefined(filter); + }else if(filter === null){ + this._filter = null; + this.command(cmdSetFilter, null); + this.command(cmdClearFilter, true); + this.useCommands(true); + this.onFilterDefined(null); + } + return this._filter; //_ConditionExpr + }, + onCommandLoad: function(/* (in)string */responce, /* (in|out)keywordArgs */ userRequest){ + // summary: + // override from _ServerSideLayer.onCommandLoad + this.inherited(arguments); + var oldOnBegin = userRequest.onBegin; + if(this._isStateful){ + var filteredSize; + if(responce){ + this.command(cmdSetFilter, null); + this.command(cmdClearFilter, null); + this.useCommands(false); + var sizes = responce.split(','); + if(sizes.length >= 2){ + filteredSize = this._filteredSize = parseInt(sizes[0], 10); + this.onFiltered(filteredSize, parseInt(sizes[1], 10)); + }else{ + //Error here. + return; + } + }else{ + filteredSize = this._filteredSize; + } + if(this.enabled()){ + userRequest.onBegin = function(size, req){ + hitchIfCan(userRequest.scope, oldOnBegin)(filteredSize, req); + }; + } + }else{ + var _this = this; + userRequest.onBegin = function(size, req){ + if(!_this._filter){ + _this._storeSize = size; + } + _this.onFiltered(size, _this._storeSize || size); + req.onBegin = oldOnBegin; + hitchIfCan(userRequest.scope, oldOnBegin)(size, req); + }; + } + } + }); + var ClientSideFilterLayer = declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [layers._StoreLayer, _FilterLayerMixin], { + // summary: + // Add a client side filter layer on top of the data store, + // so any filter expression can be applied to the store. +/*===== + //_items: Array, + // Cached items (may contain holes) + _items: [], + + //_result: Array, + // Current fetch result + _result: [], + + //_resultStartIdx: Integer, + // The index in cache of the first result item + _resultStartIdx: 0, + + //_indexMap: Array, + // A map from the row index of this._items to the row index of the original store. + _indexMap: null, + + //_getter: function(datarow, colArg, rowIndex, store); + // A user defined way to get data from store + _getter: null, + + // _nextUnfetchedIdx: Integer + // The index of the next item in the store that is never fetched. + _nextUnfetchedIdx: 0, +=====*/ + // _storeSize: Integer + // The actual size of the original store + _storeSize: -1, + + // _fetchAll + // If the store is small or store size must be correct when onBegin is called, + // we should fetch and filter all the items on the first query. + _fetchAll: true, + + constructor: function(args){ + this.filterDef(null); + args = lang.isObject(args) ? args : {}; + this.fetchAllOnFirstFilter(args.fetchAll); + this._getter = lang.isFunction(args.getter) ? args.getter : this._defaultGetter; + }, + _defaultGetter: function(datarow, colName, rowIndex, store){ + return store.getValue(datarow, colName); + }, + filterDef: function(/* (_ConditionExpr|null)? */filter){ + // summary: + // See _FilterLayerMixin.filterDef + if(filter !== undefined){ + this._filter = filter; + this.invalidate(); + this.onFilterDefined(filter); + } + return this._filter; //_ConditionExpr + }, + setGetter: function(/* function */getter){ + // summary: + // Set the user defined way to retrieve data from store. + // tags: + // public + // getter: function(datarow, colArg, rowIndex, store); + if(lang.isFunction(getter)){ + this._getter = getter; + } + }, + fetchAllOnFirstFilter: function(/* bool? */toFetchAll){ + // summary: + // The get/set function for fetchAll. + // tags: + // public + // toFetchAll: boolean? + // If provided, it's a set function, otherwise it's a get function. + // returns: + // Whether fetch all on first filter if this is a getter + if(toFetchAll !== undefined){ + this._fetchAll = !!toFetchAll; + } + return this._fetchAll; //Boolean + }, + invalidate: function(){ + // summary: + // Clear all the status information of this layer + // tags: + // private + this._items = []; + this._nextUnfetchedIdx = 0; + this._result = []; + this._indexMap = []; + this._resultStartIdx = 0; + }, + //----------------Private Functions----------------------------- + _fetch: function(userRequest,filterRequest){ + // summary: + // Implement _StoreLayer._fetch + // tags: + // private callback + // filterRequest: dojo.data.api.Request + // The actual request used in store.fetch. + // This function is called recursively to fill the result store items + // until the user specified item count is reached. Only in recursive calls, + // this parameter is valid. + if(!this._filter){ + //If we don't have any filter, use the original request and fetch. + var old_onbegin = userRequest.onBegin, _this = this; + userRequest.onBegin = function(size, r){ + hitchIfCan(userRequest.scope, old_onbegin)(size, r); + _this.onFiltered(size, size); + }; + this.originFetch(userRequest); + return userRequest; + } + try{ + //If the fetch is at the beginning, user's start position is used; + //If we are in a recursion, our own request is used. + var start = filterRequest ? filterRequest._nextResultItemIdx : userRequest.start; + start = start || 0; + if(!filterRequest){ + //Initially, we have no results. + this._result = []; + this._resultStartIdx = start; + var sortStr; + if(lang.isArray(userRequest.sort) && userRequest.sort.length > 0 && + //Sort info will stay here in every re-fetch, so remember it! + (sortStr = json.toJson(userRequest.sort)) != this._lastSortInfo){ + //If we should sort data, all the old caches are no longer valid. + this.invalidate(); + this._lastSortInfo = sortStr; + } + } + //this._result contains the current fetch result (of every recursion). + var end = typeof userRequest.count == "number" ? + start + userRequest.count - this._result.length : this._items.length; + //Try to retrieve all the items from our cache. + //Only need items after userRequest.start, test it in case start is smaller. + if(this._result.length){ + this._result = this._result.concat(this._items.slice(start, end)); + }else{ + this._result = this._items.slice(userRequest.start, typeof userRequest.count == "number" ? + userRequest.start + userRequest.count : this._items.length); + } + if(this._result.length >= userRequest.count || this._hasReachedStoreEnd()){ + //We already have had enough items, or we have to stop fetching because there's nothing more to fetch. + this._completeQuery(userRequest); + }else{ + //User's request hasn't been finished yet. Fetch more. + if(!filterRequest){ + //Initially, we've got to create a new request object. + filterRequest = shallowClone(userRequest); + //Use our own onBegin function to remember the total size of the original store. + filterRequest.onBegin = lang.hitch(this, this._onFetchBegin); + filterRequest.onComplete = lang.hitch(this, function(items, req){ + //We've fetched some more, so march ahead! + this._nextUnfetchedIdx += items.length; + //Actual filtering work goes here. Survived items are added to our cache. + //req is our own request object. + this._doFilter(items, req.start, userRequest); + //Recursively call this function. Let's do this again! + this._fetch(userRequest, req); + }); + } + //Fetch starts from the next unfetched item. + filterRequest.start = this._nextUnfetchedIdx; + //If store is small, we should only fetch once. + if(this._fetchAll){ + delete filterRequest.count; + } + //Remember we've (maybe) already added something to our result array, so next time we should not start over again. + filterRequest._nextResultItemIdx = end < this._items.length ? end : this._items.length; + //Actual fetch work goes here. + this.originFetch(filterRequest); + } + }catch(e){ + if(userRequest.onError){ + hitchIfCan(userRequest.scope, userRequest.onError)(e, userRequest); + }else{ + throw e; + } + } + return userRequest; + }, + _hasReachedStoreEnd: function(){ + // summary: + // Check whether all the items in the original store have been fetched. + // tags: + // private + return this._storeSize >= 0 && this._nextUnfetchedIdx >= this._storeSize; //Boolean + }, + _applyFilter: function(/* data item */datarow,/* Integer */rowIndex){ + // summary: + // Apply the filter to a row of data + // tags: + // private + // returns: + // whether this row survived the filter. + var g = this._getter, s = this._store; + try{ + return !!(this._filter.applyRow(datarow, function(item, arg){ + return g(item, arg, rowIndex, s); + }).getValue()); + }catch(e){ + console.warn("FilterLayer._applyFilter() error: ", e); + return false; + } + }, + _doFilter: function(/* Array */items,/* Integer */startIdx,/* object */userRequest){ + // summary: + // Use the filter expression to filter items. Survived items are stored in this._items. + // The given items start from "startIdx" in the original store. + // tags: + // private + for(var i = 0, cnt = 0; i < items.length; ++i){ + if(this._applyFilter(items[i], startIdx + i)){ + hitchIfCan(userRequest.scope, userRequest.onItem)(items[i], userRequest); + cnt += this._addCachedItems(items[i], this._items.length); + this._indexMap.push(startIdx + i); + } + } + }, + _onFetchBegin: function(/* Integer */size,/* request object */req){ + // summary: + // This function is used to replace the user's onFetchBegin in store.fetch + // tags: + // private + this._storeSize = size; + }, + _completeQuery: function(/* request object */userRequest){ + // summary: + // Logically, the user's query is completed here, i.e., all the filtered results are ready. + // (or their index mappings are ready) + // tags: + // private + var size = this._items.length; + if(this._nextUnfetchedIdx < this._storeSize){ + //FIXME: There's still some items in the original store that are not fetched & filtered. + //So we have to estimate a little bigger size to allow scrolling to these unfetched items. + //However, this behavior is ONLY correct in Grid! Any better way to do this? + size++; + } + hitchIfCan(userRequest.scope, userRequest.onBegin)(size,userRequest); + this.onFiltered(this._items.length, this._storeSize); + hitchIfCan(userRequest.scope, userRequest.onComplete)(this._result, userRequest); + }, + _addCachedItems: function(/* Array */items,/* Integer */filterStartIdx){ + // summary: + // Add data items to the cache. The insert point is at *filterStartIdx* + // tags: + // private + // items: Array + // Data items to add. + // filterStartIdx: Integer + // The start point to insert in the cache. + if(!lang.isArray(items)){ + items = [items]; + } + for(var k = 0; k < items.length; ++k){ + this._items[filterStartIdx + k] = items[k]; + } + return items.length; + }, + onRowMappingChange: function(mapping){ + //This function runs in FilterLayer scope! + if(this._filter){ + var m = lang.clone(mapping), + alreadyUpdated = {}; + for(var r in m){ + r = parseInt(r, 10); + mapping[this._indexMap[r]] = this._indexMap[m[r]]; + if(!alreadyUpdated[this._indexMap[r]]){ + alreadyUpdated[this._indexMap[r]] = true; + } + if(!alreadyUpdated[r]){ + alreadyUpdated[r] = true; + delete mapping[r]; + } + } + } + } + }); + + return lang.mixin({ + ServerSideFilterLayer: ServerSideFilterLayer, + ClientSideFilterLayer: ClientSideFilterLayer + }, layers); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js new file mode 100644 index 0000000..36f4430 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js @@ -0,0 +1,148 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/FilterStatusTip", [ + "dojo/_base/declare", + "dojo/_base/array", + "dojo/_base/lang", + "dojo/query", + "dojo/cache", + "dojo/string", + "dojo/date/locale", + "dijit/_Widget", + "dijit/_TemplatedMixin", + "dijit/_WidgetsInTemplateMixin", + "dijit/TooltipDialog", + "dijit/form/Button", + "dijit/_base/popup", + "dojo/i18n!../../nls/Filter" +], function(declare, array, lang, query, cache, string, dateLocale, _Widget, + _TemplatedMixin, _WidgetsInTemplateMixin, TooltipDialog, Button, popup){ + + var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "", + oddRowCssCls = "dojoxGridFStatusTipOddRow", + handleHolderCssCls = "dojoxGridFStatusTipHandle", + conditionCssCls = "dojoxGridFStatusTipCondition", + _removeRuleIconCls = "dojoxGridFStatusTipDelRuleBtnIcon", + _statusFooter = "</tbody></table>"; + + var FilterStatusPane = declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [_Widget, _TemplatedMixin], { + templateString: cache("dojox.grid", "enhanced/templates/FilterStatusPane.html") + }); + + return declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, { + // summary: + // Create the status tip UI. + constructor: function(args){ + var plugin = this.plugin = args.plugin; + this._statusHeader = ["<table border='0' cellspacing='0' class='", + gridCssCls, "'><thead><tr class='", + headerCssCls, "'><th class='", + cellCssCls, "'><div>", plugin.nls["statusTipHeaderColumn"], "</div></th><th class='", + cellCssCls, " lastColumn'><div>", plugin.nls["statusTipHeaderCondition"], "</div></th></tr></thead><tbody>" + ].join(''); + this._removedCriterias = []; + this._rules = []; + this.statusPane = new FilterStatusPane(); + this._dlg = new TooltipDialog({ + "class": "dojoxGridFStatusTipDialog", + content: this.statusPane, + autofocus: false + }); + this._dlg.connect(this._dlg.domNode, 'onmouseleave', lang.hitch(this, this.closeDialog)); + this._dlg.connect(this._dlg.domNode, 'click', lang.hitch(this, this._modifyFilter)); + }, + destroy: function(){ + this._dlg.destroyRecursive(); + }, + //-----------------Public Functions------------------------ + showDialog: function(/* int */pos_x,/* int */pos_y, columnIdx){ + this._pos = {x:pos_x,y:pos_y}; + popup.close(this._dlg); + this._removedCriterias = []; + this._rules = []; + this._updateStatus(columnIdx); + popup.open({ + popup: this._dlg, + parent: this.plugin.filterBar, + onCancel: function(){}, + x:pos_x - 12, + y:pos_y - 3 + }); + }, + closeDialog: function(){ + popup.close(this._dlg); + if(this._removedCriterias.length){ + this.plugin.filterDefDialog.removeCriteriaBoxes(this._removedCriterias); + this._removedCriterias = []; + this.plugin.filterDefDialog.onFilter(); + } + }, + //-----------------Private Functions--------------------------- + _updateStatus: function(columnIdx){ + var res, p = this.plugin, + nls = p.nls, + sp = this.statusPane, + fdg = p.filterDefDialog; + if(fdg.getCriteria() === 0){ + sp.statusTitle.innerHTML = nls["statusTipTitleNoFilter"]; + sp.statusRel.innerHTML = ""; + var cell = p.grid.layout.cells[columnIdx]; + var colName = cell ? "'" + (cell.name || cell.field) + "'" : nls["anycolumn"]; + res = string.substitute(nls["statusTipMsg"], [colName]); + }else{ + sp.statusTitle.innerHTML = nls["statusTipTitleHasFilter"]; + sp.statusRel.innerHTML = fdg._relOpCls == "logicall" ? nls["statusTipRelAll"] : nls["statusTipRelAny"]; + this._rules = []; + var i = 0, c = fdg.getCriteria(i++); + while(c){ + c.index = i - 1; + this._rules.push(c); + c = fdg.getCriteria(i++); + } + res = this._createStatusDetail(); + } + sp.statusDetailNode.innerHTML = res; + this._addButtonForRules(); + }, + _createStatusDetail: function(){ + return this._statusHeader + array.map(this._rules, function(rule, i){ + return this._getCriteriaStr(rule, i); + }, this).join('') + _statusFooter; + }, + _addButtonForRules: function(){ + if(this._rules.length > 1){ + query("." + handleHolderCssCls, this.statusPane.statusDetailNode).forEach(lang.hitch(this, function(nd, idx){ + (new Button({ + label: this.plugin.nls["removeRuleButton"], + showLabel: false, + iconClass: _removeRuleIconCls, + onClick: lang.hitch(this, function(e){ + e.stopPropagation(); + this._removedCriterias.push(this._rules[idx].index); + this._rules.splice(idx,1); + this.statusPane.statusDetailNode.innerHTML = this._createStatusDetail(); + this._addButtonForRules(); + }) + })).placeAt(nd, "last"); + })); + } + }, + _getCriteriaStr: function(/* object */c, /* int */rowIdx){ + var res = ["<tr class='", rowCssCls, + " ", (rowIdx % 2 ? oddRowCssCls : ""), + "'><td class='", cellCssCls, "'>", c.colTxt, + "</td><td class='", cellCssCls, + "'><div class='", handleHolderCssCls, "'><span class='", conditionCssCls, + "'>", c.condTxt, " </span>", + c.formattedVal, "</div></td></tr>"]; + return res.join(''); + }, + _modifyFilter: function(){ + this.closeDialog(); + var p = this.plugin; + p.filterDefDialog.showDialog(p.filterBar.getColumnIdx(this._pos.x)); + } + }); + + + return FilterStatusTip; +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js new file mode 100644 index 0000000..87f3461 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js @@ -0,0 +1,243 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/_ConditionExpr", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/_base/array" +], function(declare, lang, array){ + +var _ConditionExpr = declare("dojox.grid.enhanced.plugins.filter._ConditionExpr", null, { + // summary: + // The most abstract class for all condition expressions. + // A condition expression can be applied on a data row (e.g. an item in a store) + // and generate a result condition expression. + // tags: + // abstract + + _name: "expr", + + applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){ + // summary: + // *Unimplemented Interface* + // Apply this condition expression on the given datarow, return a result expression. + // taqs: + // public extension + // datarow: object + // A data item of a store. + // getter: function(datarow, colArg) + // A user defined function that extract cell data from *datarow*. + // *colArg* is an argument that provides a kind of column information. + // It is defined by user in the constructor of a _DataExpr object. + // returns: + // MUST return a _ConditionExpr object + throw new Error("_ConditionExpr.applyRow: unimplemented interface"); + }, + + toObject: function(){ + // summary: + // Convert this data expression to a simple object. Mainly used for serialization. + // tags: + // public extension + // returns: + // An object for serialization. + return {}; //Object + }, + + getName: function(){ + // summary: + // Get the name of this kind of expression. + // tags: + // public extension + // returns: + // the name of this kind of expression + return this._name; //String + } +}); + +var _DataExpr = declare("dojox.grid.enhanced.plugins.filter._DataExpr", _ConditionExpr, { + // summary: + // The most abstract class for all data expressions. + // A _DataExpr is a condition expression for a single data value. + // If the data value to be represent is a pure value (literal value, like string/number/Date/...) + // this _DataExpr is nothing more than a simple wrapper. + // If the data value to be represent is in a store, then _DataExpr is responsible to extract it + // from the store when this condition is applied to a data row. + // private fields: + // _value: anything + // _colArg: anything + _name: "data", + + constructor: function(/* anything */dataValue,/* bool */isColumn, /* object */convertArgs){ + // summary: + // If a _DataExpr is constructed with only one argument, this argument is regarded as a pure value. + // If the second argument is exactly a boolean true (no implict type transformation, + // so as to allow derived classes accept more arguments while retain *isColumn* to be optional), + // then this _DataExpr represents a column, and it's applyRow method is not a no-op. + // dataValue: anything + // If *isColumn* is a boolean true, then it should be a kind of column information, like field name + // or column index. Otherwise, it is regarded as a pure value, and the getValue method will simply + // return it. + // isColumn: boolean? + // Optional. To specify whether this _DataExpr represents a column or a pure value. + this._convertArgs = convertArgs || {}; + if(lang.isFunction(this._convertArgs.convert)){ + this._convertData = lang.hitch(this._convertArgs.scope, this._convertArgs.convert); + } + if(isColumn){ + this._colArg = dataValue; + }else{ + this._value = this._convertData(dataValue, this._convertArgs); + } + }, + + getValue: function(){ + // summary: + // If this is a pure value wrapper, simply return the value. + // Otherwise (it's a column), return is undefined. + // tags: + // public + // returns: + // the value of this data expression. + return this._value; //String + }, + + applyRow: function(/* data item */datarow,/* function(row,colIdx) */getter){ + // summary: + // Implement _ConditionExpr.applyRow. + // If this is a pure value, simply return self. + // Otherwise, extract the cell data from datarow using the given getter function, + // and then convert this cell data to a _DataExpr and return the expression. + return typeof this._colArg == "undefined" ? this : //_ConditionExpr + new (lang.getObject(this.declaredClass))( + this._convertData(getter(datarow, this._colArg), this._convertArgs) + ); + }, + + _convertData: function(/* anything */dataValue){ + // summary: + // + // tags: + // protected extension + // dataValue: anything + // This argument should come from a store. + // returns: + return dataValue; + }, + + toObject: function(){ + // summary: + // Overrided from _ConditionExpr.toObject + return { //String + op: this.getName(), + data: this._colArg === undefined ? this._value : this._colArg, + isCol: this._colArg !== undefined + }; + } +}); + +var _OperatorExpr = declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", _ConditionExpr, { + // summary: + // The most abstract class for all operator expressions. + // An operator expression is a _ConditionExpr that represents an operation. + _name: "operator", + + constructor: function(/* Array | operand1,operand2,... */){ + // summary: + // The arguments are operands (or an array of operands, if the first argument + // is an Array) of this operator, ordering from left to right. + // Every operand should be a _ConditionExpr. + if(lang.isArray(arguments[0])){ + this._operands = arguments[0]; + }else{ + this._operands = []; + for(var i = 0; i < arguments.length; ++i){ + this._operands.push(arguments[i]); + } + } + }, + toObject: function(){ + // summary: + // Overrided from _ConditionExpr.toObject + return { //Object + op: this.getName(), + data: array.map(this._operands,function(operand){ + return operand.toObject(); + }) + }; + } +}); + +var _UniOpExpr = declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", _OperatorExpr, { + // summary: + // The most abstract class for all uni-operator expressions. + // A uni-operator expression is an _OperatorExpr that only allow one operand. + _name: "uniOperator", + + applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){ + // summary: + // Implement _ConditionExpr.applyRow. + // Apply the restriction of "only one operand" and confirm the operand is a valid _ConditionExpr. + // Then do the calculation of this operator. + if(!(this._operands[0] instanceof _ConditionExpr)){ + throw new Error("_UniOpExpr: operand is not expression."); + } + return this._calculate(this._operands[0],datarow,getter); //_ConditionExpr + }, + + _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colArg) */getter){ + // summary: + // *Unimplemented Interface* + // Do the actrual work of applyRow here. + // tags: + // protected extension + // operand: _ConditionExpr + // datarow: object + // getter: function(row,colArg) + // returns: + // MUST return a _ConditionExpr object. + throw new Error("_UniOpExpr._calculate: unimplemented interface"); + } +}); + +var _BiOpExpr = declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", _OperatorExpr, { + // summary: + // The most abstract class for all bi-operator expressions. + // A bi-operator expression is an _OperatorExpr that allow and only allow two operands. + _name: "biOperator", + + applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){ + // summary: + // Implement _ConditionExpr.applyRow. + // Apply the restriction of "two operands" and confirm operands are valid _ConditionExpr's. + if(!(this._operands[0] instanceof _ConditionExpr)){ + throw new Error("_BiOpExpr: left operand is not expression."); + }else if(!(this._operands[1] instanceof _ConditionExpr)){ + throw new Error("_BiOpExpr: right operand is not expression."); + } + return this._calculate(this._operands[0],this._operands[1],datarow,getter); + }, + + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,/* data item*/datarow,/* function(row,colArg) */getter){ + // summary: + // *Unimplemented Interface* + // Do the actrual work of applyRow here. + // tags: + // protected extension + // left_operand: _ConditionExpr + // right_operand: _ConditionExpr + // datarow: object + // getter: function(row,colArg) + // returns: + // MUST return a _ConditionExpr object. + throw new Error("_BiOpExpr._calculate: unimplemented interface"); + } +}); + +return { + _ConditionExpr: _ConditionExpr, + _DataExpr: _DataExpr, + _OperatorExpr: _OperatorExpr, + _UniOpExpr: _UniOpExpr, + _BiOpExpr: _BiOpExpr +}; + +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js new file mode 100644 index 0000000..b19c2c4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js @@ -0,0 +1,85 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/_DataExprs", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/date/locale", + "./_ConditionExpr" +], function(declare, lang, dateLocale, exprs){ + + var BooleanExpr = declare("dojox.grid.enhanced.plugins.filter.BooleanExpr", exprs._DataExpr, { + // summary: + // A condition expression wrapper for boolean values + _name: "bool", + _convertData: function(/* anything */dataValue){ + // summary: + // override from _DataExpr + return !!dataValue; //Boolean + } + }); + var StringExpr = declare("dojox.grid.enhanced.plugins.filter.StringExpr", exprs._DataExpr, { + // summary: + // A condition expression wrapper for string values + _name: "string", + _convertData: function(/* anything */dataValue){ + // summary: + // override from _DataExpr + return String(dataValue); //String + } + }); + var NumberExpr = declare("dojox.grid.enhanced.plugins.filter.NumberExpr", exprs._DataExpr, { + // summary: + // A condition expression wrapper for number values + _name: "number", + _convertDataToExpr: function(/* anything */dataValue){ + // summary: + // override from _DataExpr + return parseFloat(dataValue); //Number + } + }); + var DateExpr = declare("dojox.grid.enhanced.plugins.filter.DateExpr", exprs._DataExpr, { + // summary: + // A condition expression wrapper for date values + _name: "date", + _convertData: function(/* anything */dataValue){ + // summary: + // override from _DataExpr + if(dataValue instanceof Date){ + return dataValue; + }else if(typeof dataValue == "number"){ + return new Date(dataValue); + }else{ + var res = dateLocale.parse(String(dataValue), lang.mixin({selector: this._name}, this._convertArgs)); + if(!res){ + throw new Error("Datetime parse failed: " + dataValue); + } + return res; + } + }, + toObject: function(){ + // summary: + // Overrided from _DataExpr.toObject + if(this._value instanceof Date){ + var tmp = this._value; + this._value = this._value.valueOf(); + var res = this.inherited(arguments); + this._value = tmp; + return res; + }else{ + return this.inherited(arguments); + } + } + }); + var TimeExpr = declare("dojox.grid.enhanced.plugins.filter.TimeExpr", DateExpr, { + // summary: + // A condition expression wrapper for time values + _name: "time" + }); + + return lang.mixin({ + BooleanExpr: BooleanExpr, + StringExpr: StringExpr, + NumberExpr: NumberExpr, + DateExpr: DateExpr, + TimeExpr: TimeExpr + }, exprs); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js new file mode 100644 index 0000000..f1c2461 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js @@ -0,0 +1,248 @@ +//>>built +define("dojox/grid/enhanced/plugins/filter/_FilterExpr", [ + "dojo/_base/declare", + "dojo/_base/lang", + "dojo/date", + "./_DataExprs" +], function(declare, lang, date, exprs){ +//This is the main file that should be 'required' if filter expression facility is necessary. + + /* Logic Operations */ + var LogicAND = declare("dojox.grid.enhanced.plugins.filter.LogicAND", exprs._BiOpExpr, { + // summary: + // A logic AND condition expression. + _name: "and", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = left_operand.applyRow(datarow, getter).getValue() && + right_operand.applyRow(datarow, getter).getValue(); + return new exprs.BooleanExpr(res); //_ConditionExpr + } + }); + var LogicOR = declare("dojox.grid.enhanced.plugins.filter.LogicOR", exprs._BiOpExpr, { + // summary: + // A logic OR condition expression. + _name: "or", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = left_operand.applyRow(datarow, getter).getValue() || + right_operand.applyRow(datarow, getter).getValue(); + return new exprs.BooleanExpr(res); //_ConditionExpr + } + }); + var LogicXOR = declare("dojox.grid.enhanced.plugins.filter.LogicXOR", exprs._BiOpExpr, { + // summary: + // A logic XOR condition expression. + _name: "xor", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var left_res = left_operand.applyRow(datarow, getter).getValue(); + var right_res = right_operand.applyRow(datarow, getter).getValue(); + return new exprs.BooleanExpr((!!left_res) != (!!right_res)); //_ConditionExpr + } + }); + var LogicNOT = declare("dojox.grid.enhanced.plugins.filter.LogicNOT", exprs._UniOpExpr, { + // summary: + // A logic NOT condition expression. + _name: "not", + _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _UniOpExpr + return new exprs.BooleanExpr(!operand.applyRow(datarow, getter).getValue()); //_ConditionExpr + } + }); + var LogicALL = declare("dojox.grid.enhanced.plugins.filter.LogicALL", exprs._OperatorExpr, { + // summary: + // A logic ALL condition expression, equals a sequence of logic ANDs + _name: "all", + applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){ + // summary: + // Override from _ConditionExpr + for(var i = 0, res = true; res && (this._operands[i] instanceof exprs._ConditionExpr); ++i){ + res = this._operands[i].applyRow(datarow,getter).getValue(); + } + return new exprs.BooleanExpr(res); //_ConditionExpr + } + }); + var LogicANY = declare("dojox.grid.enhanced.plugins.filter.LogicANY", exprs._OperatorExpr, { + // summary: + // A logic ANY condition expression, equals a sequence of logic ORs + _name: "any", + applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){ + for(var i = 0,res = false; !res && (this._operands[i] instanceof exprs._ConditionExpr); ++i){ + res = this._operands[i].applyRow(datarow,getter).getValue(); + } + return new exprs.BooleanExpr(res); //_ConditionExpr + } + }); + + /* Comparison Operations */ + function compareFunc(left,right,row,getter){ + left = left.applyRow(row, getter); + right = right.applyRow(row, getter); + var left_res = left.getValue(); + var right_res = right.getValue(); + if(left instanceof exprs.TimeExpr){ + return date.compare(left_res,right_res,"time"); + }else if(left instanceof exprs.DateExpr){ + return date.compare(left_res,right_res,"date"); + }else{ + if(left instanceof exprs.StringExpr){ + left_res = left_res.toLowerCase(); + right_res = String(right_res).toLowerCase(); + } + return left_res == right_res ? 0 : (left_res < right_res ? -1 : 1); + } + } + var EqualTo = declare("dojox.grid.enhanced.plugins.filter.EqualTo", exprs._BiOpExpr, { + // summary: + // An "equal to" condition expression. + _name: "equal", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = compareFunc(left_operand,right_operand,datarow,getter); + return new exprs.BooleanExpr(res === 0); //_ConditionExpr + } + }); + var LessThan = declare("dojox.grid.enhanced.plugins.filter.LessThan", exprs._BiOpExpr, { + // summary: + // A "less than" condition expression. + _name: "less", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = compareFunc(left_operand,right_operand,datarow,getter); + return new exprs.BooleanExpr(res < 0); //_ConditionExpr + } + }); + var LessThanOrEqualTo = declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", exprs._BiOpExpr, { + // summary: + // A "less than or equal to" condition expression. + _name: "lessEqual", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = compareFunc(left_operand,right_operand,datarow,getter); + return new exprs.BooleanExpr(res <= 0); //_ConditionExpr + } + }); + var LargerThan = declare("dojox.grid.enhanced.plugins.filter.LargerThan", exprs._BiOpExpr, { + // summary: + // A "larger than" condition expression. + _name: "larger", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = compareFunc(left_operand,right_operand,datarow,getter); + return new exprs.BooleanExpr(res > 0); //_ConditionExpr + } + }); + var LargerThanOrEqualTo = declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", exprs._BiOpExpr, { + // summary: + // A "larger than or equal to" condition expression. + _name: "largerEqual", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = compareFunc(left_operand,right_operand,datarow,getter); + return new exprs.BooleanExpr(res >= 0); //_ConditionExpr + } + }); + + /* String Operations */ + var Contains = declare("dojox.grid.enhanced.plugins.filter.Contains", exprs._BiOpExpr, { + // summary: + // A "contains" condition expression. + _name: "contains", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase(); + var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase(); + return new exprs.BooleanExpr(left_res.indexOf(right_res) >= 0); //_ConditionExpr + } + }); + var StartsWith = declare("dojox.grid.enhanced.plugins.filter.StartsWith", exprs._BiOpExpr, { + // summary: + // A "starts with" condition expression. + _name: "startsWith", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase(); + var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase(); + return new exprs.BooleanExpr(left_res.substring(0, right_res.length) == right_res); //_ConditionExpr + } + }); + var EndsWith = declare("dojox.grid.enhanced.plugins.filter.EndsWith", exprs._BiOpExpr, { + // summary: + // An "ends with" condition expression. + _name: "endsWith", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase(); + var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase(); + return new exprs.BooleanExpr(left_res.substring(left_res.length - right_res.length) == right_res); //_ConditionExpr + } + }); + var Matches = declare("dojox.grid.enhanced.plugins.filter.Matches", exprs._BiOpExpr, { + // summary: + // A "regular expression match" condition expression. + // The second operand's value will be regarded as an regular expression string. + _name: "matches", + _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand, + /* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var left_res = String(left_operand.applyRow(datarow, getter).getValue()); + var right_res = new RegExp(right_operand.applyRow(datarow, getter).getValue()); + return new exprs.BooleanExpr(left_res.search(right_res) >= 0); //_ConditionExpr + } + }); + var IsEmpty = declare("dojox.grid.enhanced.plugins.filter.IsEmpty", exprs._UniOpExpr, { + // summary: + // Check empty + _name: "isEmpty", + _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){ + // summary: + // Override from _BiOpExpr + var res = operand.applyRow(datarow, getter).getValue(); + return new exprs.BooleanExpr(res === "" || res == null); + } + }); + + return lang.mixin({ + LogicAND: LogicAND, + LogicOR: LogicOR, + LogicXOR: LogicXOR, + LogicNOT: LogicNOT, + LogicALL: LogicALL, + LogicANY: LogicANY, + EqualTo: EqualTo, + LessThan: LessThan, + LessThanOrEqualTo: LessThanOrEqualTo, + LargerThan: LargerThan, + LargerThanOrEqualTo: LargerThanOrEqualTo, + Contains: Contains, + StartsWith: StartsWith, + EndsWith: EndsWith, + Matches: Matches, + IsEmpty: IsEmpty + }, exprs); +}); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css new file mode 100644 index 0000000..fc3d346 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css @@ -0,0 +1,27 @@ +/* Indirect Selection */ +.dojoxGridRowSelector { + cursor: pointer; +} +.dojoxGridRowSelectorStatusText{ + visibility:hidden; +} +.dijit_a11y .dojoxGridRowSelected { + opacity:0.8 !important; +} +.dijit_a11y .dojoxGridBorderDIV { + border:2px solid #000 !important; +} +.dijit_a11y .dojoxGridRowSelector { + height:100% !important; +} +.dijit_a11y .dojoxGridRowSelectorStatusText{ + font-size:larger !important; + visibility:visible; +} +.dijit_a11y .dijitCheckBox .dojoxGridRowSelectorStatusText{ + font-weight:bolder !important; + font-size:x-large !important; +} +.dijit_a11y .dijitCheckBoxChecked .dojoxGridRowSelectorStatusText{ + font-size:small !important; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css new file mode 100644 index 0000000..796e935 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css @@ -0,0 +1,15 @@ +.dojoxGridRtl .dojoxGridLoading, +.dojoxGridRtl .dojoxGridError, +.dojoxGridRtl .dojoxGridNoData { + background-position:right; + padding-right:25px; + padding-left:0px; +} +.dojoxGridRtl .dojoxGridHeader { + margin-left: 0; + margin-right: -1px; +} + +.dojoxGridRtl .dojoxGridCell { + text-align: right; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css new file mode 100644 index 0000000..c364b0e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css @@ -0,0 +1,78 @@ +.dojoxGridBorderDIV { + width:2px; + background-color: gray; + font-size:0em; + position:absolute; + z-index:9999; +} +.dojoxGridCellBorderDIV { + position:absolute; + background-color: transparent; + border: none; +} +.dojoxGridCellBorderLeftTopDIV { + position: absolute; + left: 0; + top: 0; + border-style: solid; + border-width: 2px 0 0 2px; + border-color: gray transparent transparent gray; +} +.dojoxGridCellBorderRightBottomDIV { + position: absolute; + right: 0; + bottom: 0; + border-style: solid; + border-width: 0 2px 2px 0; + border-color: transparent gray gray transparent; +} +.dojoxGridDnDItemIcon { + background-image: url("images/sprite_icons.png"); +} +.dojoxGridDnDIconRowSingle { + background-position: -256px 5px; +} +.dojoxGridDnDIconRowMulti { + background-position: -256px -16px; +} +.dojoxGridDnDIconColSingle { + background-position: -277px 3px; +} +.dojoxGridDnDIconColMulti { + background-position: -277px -17px; +} +.dojoxGridDnDIconCellSingle { + background-position: -235px 5px; +} +.dojoxGridDnDIconCellMulti { + background-position: -236px -16px; +} +.dojoxGridDndAvatar { + background-color:white; + border: 1px solid #CCCCCC; + padding: 0px; + -moz-box-shadow: 5px 5px 7px #999; + -webkit-box-shadow: 5px 5px 7px #999; + box-shadow: 5px 5px 7px #999; + z-index: 999; +} +.dojoxGridDndAvatar td { + padding: 3px; +} +.dojoxGridDnDIcon, +.dojoxGridDnDItemIcon { + width: 16px; + height: 16px; +} +.dojoDndMove .dojoxGridDnDIcon { + background: url(../../../../dojo/resources/images/dndNoMove.png) no-repeat center center; +} +.dojoDndCopy .dojoxGridDnDIcon { + background: url(../../../../dojo/resources/images/dndNoCopy.png) no-repeat center center; +} +.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDnDIcon { + background: url(../../../../dojo/resources/images/dndMove.png) no-repeat center center; +} +.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDnDIcon { + background: url(../../../../dojo/resources/images/dndCopy.png) no-repeat center center; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css new file mode 100644 index 0000000..d7f270f --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css @@ -0,0 +1,12 @@ +.dojoxGridRtl .dojoxGridCellBorderLeftTopDIV{ + left: auto; + right: 0; + border-width: 2px 2px 0 0; + border-color: gray gray transparent transparent; +} +.dojoxGridRtl .dojoxGridCellBorderRightBottomDIV{ + right: auto; + left: 0; + border-width: 0 0 2px 2px; + border-color: transparent transparent gray gray; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css new file mode 100644 index 0000000..7f02773 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css @@ -0,0 +1,8 @@ +@import url("Common.css"); +@import url("Filter.css"); +@import url("Pagination.css"); +@import url("DnD.css"); +@import url("Sorter.css"); +@import url("../../../widget/Toaster/Toaster.css"); +@import url("../../../html/resources/ellipsis.css"); + diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css new file mode 100644 index 0000000..0aae662 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css @@ -0,0 +1,6 @@ +@import url("../../resources/Grid_rtl.css"); +@import url("Common_rtl.css"); +@import url("Filter_rtl.css"); +@import url("Pagination_rtl.css"); +@import url("DnD_rtl.css"); +@import url("Sorter_rtl.css"); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css new file mode 100644 index 0000000..46ca5fe --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css @@ -0,0 +1,292 @@ +/* filter bar */ +.dojoxGridFBar { + width: 100%; + cursor: pointer; +} +.dojoxGridFBar .dojoxGridFBarBtn { + margin: 0; +} +.dojoxGridFBarBtnTD { + width: 38px; +} +.dojoxGridFBar .dojoxGridFBarBtn .dijitButtonNode { + -moz-border-radius: 1px; + -webkit-border-radius: 1px; + padding-top: 0; + padding-bottom: 0; + padding-right: 2px; +} +.dojoxGridFBarDefFilterBtnIcon { + background: url("images/sprite_icons.png") no-repeat; + background-position: -100px -18px; + width: 14px; + height: 14px; +} +.dj_ie .dojoxGridFBarInner{ + display: inline-block; + width: 100%; +} +.dojoxGridFBarStatus { + margin-left: 9px; + float: left; +} +.dojoxGridFBarClearFilterBtn { + margin: 0 0 0 10px; + vertical-align: top; + float: left; +} +.dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn .dijitButtonNode, +.dojoxGridFBarInfoTD .dojoxGridFBarCloseBtn .dijitButtonNode, +.dojoxGridFDPane .dijitAccordionTitle .dijitButtonNode, +.dojoxGridFStatusTipDetail .dijitButton .dijitButtonNode { + -moz-border-radius: 0; + -moz-box-shadow: none; + -webkit-border-radius: 0; + -webkit-box-shadow: none; + background-image: none; + background-color: transparent; + margin: 0; + padding: 0; + border: none; +} +.dj_ie .dojoxGridFBarInner { + position: relative; +} +.dojoxGridFBarCloseBtn { + margin: 0 4px 0 0; + float: right; +} +.dj_ie .dojoxGridFBarCloseBtn { + float: none; + position: absolute; + right: 0; +} +.dojoxGridFBarCloseBtnIcon { + background: url("images/sprite_icons.png") no-repeat; + background-position: -119px -20px; + width: 14px; + height: 14px; +} +.dijitButtonHover .dojoxGridFBarCloseBtnIcon { + background-position: -140px -20px; +} +.dijitButtonActive .dojoxGridFBarCloseBtnIcon { + background-position: -160px -20px; +} + +/* filter def dialog */ +.dojoxGridFDTitlePane { + width: 316px; + height: 330px; +} +.dijit_a11y .dojoxGridFDTitlePane .dijitArrowButtonInner{ + /* This should be fixed in dijit */ + display:none !important; +} +.dojoxGridFDTitlePane .dijitDialogPaneContent { + padding: 7px 5px 9px 5px; + height: 290px !important; +} +.dojoxGridFDTitlePane .dijitTitlePaneTitle { + cursor: move; +} +.dojoxGridFDPaneRelation { + margin: 0 0 3px 4px; +} +.dojoxGridFDPane { + width: 100%; + height: 100%; + position: relative; +} +.dojoxGridFDPaneRulePane { + height: 222px; + overflow: auto; + /* for ie6/7 only */ + position: relative; +} +.dj_ie6 .dojoxGridFDPaneRulePane { + width: 100%; +} +.dojoxGridFDPane .dijitAccordionContainer .dijitContentPane { + padding: 6px 9px; +} +.dojoxGridFDPane .dijitAccordionTitle { + position: relative; + /* for non-claro theme, this can ensure a correct height change when adding/removing child */ + min-height: 17px; +} +.dojoxGridFDPane .dijitAccordionTitle .dijitButton { + position: absolute; + margin: 0; + right: 3px; + top: 4px; +} +.dj_ie6 .dojoxGridFDPane .dijitAccordionTitle .dijitButton { + top: 2px; +} +.dojoxGridFDPane .dijitAccordionTitleFocus { + margin-right: 14px; +} +.dojoxGridFDPane .dijitAccordionText { + display: inline-block; + position: relative; +} +.dojoxGridFCBoxRemoveCBoxBtnIcon { + background-image: url("images/sprite_icons.png"); + background-position: -198px -18px; + width: 16px; + height: 16px; +} +.dijitButtonHover .dojoxGridFCBoxRemoveCBoxBtnIcon { + background-position: -198px 2px; +} +.dojoxGridRuleTitleCondition { + font-style: italic; +} +.dojoxGridFDPaneModes .dijitSelect { + position: relative; +} +.dojoxGridFDPaneBtns { + position: absolute; + right: 0; + bottom: 0; +} +.dj_ie7 .dojoxGridFDPaneBtns, +.dj_ie6 .dojoxGridFDPaneBtns { + z-index: -1; +} +.dojoxGridFDPaneBtns .dijitButton { + float: right; +} +.dojoxGridFDPaneAddCBoxBtn { + margin-top: 9px; +} +.dojoxGridFDPaneAddCBoxBtnIcon { + background-image: url("images/sprite_icons.png"); + background-position: -218px 2px; + width: 16px; + height: 16px; +} +.dijitButtonDisabled .dojoxGridFDPaneAddCBoxBtnIcon { + background-position: -218px -18px; +} + +/* criteria box */ +.dojoxGridFCBox { + height: 125px; +} +.dojoxGridFCBoxSelCol, +.dojoxGridFCBoxCondition { + height: 40px; +} +.dojoxGridFCBox .dojoxGridFCBoxColSelect, +.dojoxGridFCBox .dojoxGridFCBoxCondSelect, +.dojoxGridFCBox .dojoxGridFCBoxValueBox { + margin: 0.1em 0 0 0; + width: 100%; + /* inherited is inline-block this will cause width "error" in non IE for html tables */ + display: inline-table; +} +.dojoxGridFCBoxCondSelectAlt { + width: 100%; + padding: 5px 0 0 0; + font-weight: bold; +} +.dojoxGridFCBox .dijitSelect .dijitArrowButton { + width: 18px; +} +.dojoxGridFCBoxStartValue { + width: 45%; +} +.dojoxGridFCBoxEndValue { + float: right; + width: 45%; +} +.dojoxGridFCBoxRangeValueTxt { + margin-left: 4px; +} + +/* status tip */ +.dojoxGridFStatusTipDialog .dijitTooltipContainer { + padding: 9px 5px; +} +.dojoxGridFStatusTip thead, +.dojoxGridFStatusTip tr { + height: 19px; +} +.dojoxGridFStatusTip th { + max-width: 150px; + width: expression(this.clientWidth > 150 ? "150px" : "auto"); +} +.dojoxGridFStatusTip th div { + padding: 2px 5px; +} +.dojoxGridFStatusTip td { + padding: 2px 6px; + max-width: 150px; + overflow: hidden; + width: expression(this.clientWidth > 150 ? "150px" : "auto"); +} +.dojoxGridFStatusTipHead { + margin-bottom: 9px; +} +.dojoxGridFStatusTipTitle { + font-weight: bold; + margin-right: 1em; +} +.dojoxGridFStatusTipHandle { + position: relative; + padding-right: 16px; +} +.dojoxGridFStatusTipDetail .dijitButton { + position: absolute; + margin: 0; + padding: 0; + top: -1px; + right:0; +} +.dojoxGridFStatusTipDelRuleBtnIcon { + background-image: url("images/sprite_icons.png"); + background-position: -198px -18px; + height: 16px; + width: 16px; +} +.dijitButtonHover .dojoxGridFStatusTipDelRuleBtnIcon { + background-position: -198px 2px; +} + +/* clear dlg */ +.dj_ie7 .dojoxGridClearFilterConfirm, +.dj_ie6 .dojoxGridClearFilterConfirm { + width: 300px; +} +.dojoxGridClearFilterBtns{ + padding: 10px; + height: 18px; +} +.dojoxGridClearFilterBtns .dijitButton { + float: right; +} + +/* bool value box */ +.dojoxGridTrueBox { + float: left; + width: 49%; +} +.dojoxGridFalseBox { + float: left; + width: 49%; +} +.dojoxGridBoolValueBox .dijitRadio { + vertical-align: middle; +} +.dojoxGridTrueLabel, +.dojoxGridFalseLabel { + width: 116px; + display:inline-block; + vertical-align: middle; +} +.dj_ie7 .dojoxGridTrueLabel, +.dj_ie7 .dojoxGridFalseLabel { + display: inline; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css new file mode 100644 index 0000000..c9f2333 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css @@ -0,0 +1,84 @@ +/* filter bar */ +.dojoxGridRtl .dojoxGridFBarDefFilterBtnIcon { + background: url("images/sprite_icons.png") no-repeat; + background-position: -180px -18px; +} +.dojoxGridRtl .dojoxGridFBarStatus { + margin-left: 0; + margin-right: 9px; + float: right; +} +.dojoxGridRtl .dojoxGridFBarClearFilterBtn { + margin-left: 0; + margin-right: 10px; + float: right; +} +.dojoxGridRtl .dojoxGridFBarCloseBtn { + margin: 0 0 0 4px; + float: left; +} +.dj_ie .dojoxGridRtl .dojoxGridFBarCloseBtn { + left: 2px; + right: auto; +} +/* filter def dialog */ +.dijitRtl .dojoxGridFDPaneRelation { + margin: 0 4px 3px 0; +} +.dijitRtl .dojoxGridFDPane .dijitAccordionTitleFocus { + margin-right: 0; + margin-left: 14px; +} +.dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton { + left: 3px; + right: auto; +} +.dj_ie6 .dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton{ + left: -290px; +} +.dijitRtl .dojoxGridFDPaneBtns { + left: 0; + right: auto; +} +.dijitRtl .dojoxGridFDPaneBtns .dijitButton, +.dijitRtl .dojoxGridClearFilterBtns .dijitButton, +.dijitRtl .dojoxGridFCBoxEndValue { + float: left; +} +.dijitRtl .dojoxGridFCBoxRangeValueTxt { + margin-left: 0; + margin-right: 4px; +} + +/* status tip */ +.dijitRtl .dojoxGridFStatusTipTitle { + margin-left: 1em; + margin-right: 0; +} +.dijitRtl .dojoxGridFStatusTipHandle { + padding-left: 16px; + padding-right: 0; +} +.dijitRtl .dojoxGridFStatusTipDetail .dijitButton { + left: 0; + right: auto; +} + +/* bool value box */ +.dijitRtl .dojoxGridTrueBox, +.dijitRtl .dojoxGridFalseBox { + float: right; +} + +/* For Claro */ +.claro .dojoxGridRtl .dojoxGridFBar { + border-right: 1px solid white; +} + +.claro .dijitRtl .dojoxGridFStatusTip th div { + border-left: 1px solid #BCBCBC; + border-right: 1px solid white; +} +.claro .dijitRtl .dojoxGridFStatusTip th.lastColumn div { + border-left: 1px solid #BCBCBC; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css new file mode 100644 index 0000000..bc1ae55 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css @@ -0,0 +1,147 @@ +.dojoxGridPaginator { + border-top:1px #DBDBDB solid; + text-align:center; + width: 100%; + height: 24px; + table-layout : fixed; + background-color: #EAEAEA; +} +.dojoxGridDescriptionTd { + text-align: left; + width: 35%; +} +.dojoxGridDescription { + text-align: left; + margin-left: 9px; + overflow: hidden; +} +.dojoxGridPaginatorFastStep { + text-align: right; + width: 35%; + overflow: hidden; +} +.dojoxGridPaginatorStep { + float: right; +} +.dojoxGridPaginatorGotoTd { + width: 20px!important; +} +.dojoxGridPaginatorGotoDiv { + cursor: pointer; + width: 12px!important; + height: 16px!important; + margin: 0 6px 0 2px; + background: url("images/sprite_icons.png") no-repeat -77px 4px; +} +.dojoxGridPaginatorGotoDivDisabled { + cursor: not-allowed; + background: url("images/sprite_icons.png") no-repeat -77px -16px; +} +.dojoxGridWardButton { + margin-top: 2px; + width: 12px!important; + height: 12px!important; + float: left; + background: url("images/sprite_icons.png") no-repeat; +} +.dojoxGridWardButtonInner { + visibility: hidden; +} +.dijit_a11y .dojoxGridWardButtonInner { + visibility: visible; + margin-bottom: 8px; +} +.dojoxGridfirstPageBtn { + cursor: pointer; + margin-left: 1px; + background-position: -57px 3px; +} +.dojoxGridfirstPageBtnDisable { + margin-left: 1px; + cursor: not-allowed; + background-position: -57px -17px; +} +.dojoxGridprevPageBtn { + cursor: pointer; + margin: 2px 2px 0 9px; + background-position: 3px 3px; +} +.dojoxGridprevPageBtnDisable { + cursor: not-allowed; + margin: 2px 2px 0 9px; + background-position: 3px -17px; +} +.dojoxGridlastPageBtn { + cursor: pointer; + margin: 2px 9px 0 9px; + background-position: -37px 3px; +} +.dojoxGridlastPageBtnDisable { + cursor: not-allowed; + margin: 2px 9px 0 9px; + background-position: -37px -17px; +} + +.dojoxGridnextPageBtn { + cursor: pointer; + margin-left: 3px; + background-position: -17px 3px; +} +.dojoxGridnextPageBtnDisable { + margin-left: 3px; + cursor: not-allowed; + background-position: -17px -17px; +} +.dojoxGridInactived { + font-weight: normal; + color: #5D88AF; + cursor: pointer; + margin: 1px 6px 0 5px; + float: left; + zoom: 1; /* for IE */ +} +.dojoxGridActived { + font-weight: bold; + color: black; + margin: 1px 6px 0 5px; + float: left; + text-decoration: none!important; + zoom: 1; /* for IE */ +} +.dojoxGridInactiveSwitch { + font-weight: normal; + color: #5D88AF; + float: left; + cursor: pointer; + margin: 1px 7px 0 7px; + zoom: 1; /* for IE */ +} +.dojoxGridActivedSwitch { + font-weight: bold; + color: black; + float: left; + margin: 1px 7px 0 7px; + text-decoration: none!important; + zoom: 1; /* for IE */ +} +.dojoxGridSeparator { + float: left; +} +.dojoxGridPageTextHover { + text-decoration: underline; +} +.dojoxGridDialogMargin { + width: 220px!important; + margin-bottom: 10px; +} +.dj_ie6 .dojoxGridDialogMargin { + position: relative; +} +.dojoxGridDialogButton { + width: 220px!important; + text-align: right; +} +.dojoxGridButtonFocus { + outline: none; + border: 0.5px dotted darkblue !important; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css new file mode 100644 index 0000000..e3a2dd1 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css @@ -0,0 +1,68 @@ +.dojoxGridRtl .dojoxGridDescription { + text-align: right; + margin-right: 9px; +} +.dojoxGridRtl .dojoxGridPaginatorStep { + float: left; +} +.dojoxGridRtl .dojoxGridPaginatorGotoDiv { + margin: 0 2px 0 6px; +} +.dojoxGridRtl .dojoxGridWardButton { + float: right; +} +.dojoxGridRtl .dojoxGridInactived { + margin: 1px 5px 0 6px; + float: right; +} +.dojoxGridRtl .dojoxGridActived { + margin: 1px 5px 0 6px; + float: right; +} +.dijitRtl .dojoxGridDialogButton { + float: left; + margin-bottom: 10px; +} +.dijitRtl .dojoxGridInactiveSwitch { + float: right; +} +.dijitRtl .dojoxGridActivedSwitch { + float: right; +} +.dijitRtl .dojoxGridSeparator { + float: right; +} +.dijitRtl .dojoxGridfirstPageBtn { + cursor: pointer; + margin: 2px 1px 0 0; + background-position: -37px 3px; +} +.dijitRtl .dojoxGridfirstPageBtnDisable { + margin: 2px 1px 0 0; + background-position: -37px -17px; +} +.dijitRtl .dojoxGridprevPageBtn { + cursor: pointer; + margin: 2px 9px 0 5px; + background-position: -17px 3px; +} +.dijitRtl .dojoxGridprevPageBtnDisable { + margin: 2px 9px 0 5px; + background-position: -17px -17px; +} +.dijitRtl .dojoxGridlastPageBtn { + cursor: pointer; + background-position: -57px 3px; +} +.dijitRtl .dojoxGridlastPageBtnDisable { + background-position: -57px -17px; +} +.dijitRtl .dojoxGridnextPageBtn { + cursor: pointer; + margin: 2px 3px 0 0; + background-position: 3px 3px; +} +.dijitRtl .dojoxGridnextPageBtnDisable { + margin: 2px 3px 0 0; + background-position: 3px -17px; +}
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css new file mode 100644 index 0000000..11e6fc5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css @@ -0,0 +1,179 @@ +/* +.dojoxGrid + Sorted, SingleSorted | NestSorted +.dojoxGridCell + Over, SortFocus, ShowIndex +.dojoxGridSortNode + Asc | Desc, Main|Sub +.dojoxGridSortBtn + :hover, Single|Nested +*/ +.dojoxGrid .dojoxGridSortNode { + position: relative; + border: 1px solid transparent; + cursor: pointer; +} +.dj_ie6 .dojoxGrid .dojoxGridSortNode, +.dj_ie7 .dojoxGrid .dojoxGridSortNode { + overflow: hidden; + width:100%; +} +.dojoxGrid .dojoxGridSortNoWrap { + white-space:nowrap; + word-wrap: normal; +} +.dojoxGridSortBtn { + width: 10px; + height:100%; + visibility: hidden; + top: 0; + display:block; + position: absolute; + color: #000; + background: #DFEAF1 url(images/sprite_icons.png) no-repeat 100px 0; + text-decoration: none; + outline: none; + right: 0; + border: 1px solid transparent; + box-sizing: border-box; /* css3 rec */ + -moz-box-sizing: border-box; /* ff */ + -ms-box-sizing: border-box; /* ie8 */ + -webkit-box-sizing: border-box; /* safari3 */ + -khtml-box-sizing: border-box; /* konqueror */ +} +.dj_ie6 .dojoxGridSortBtn, +.dj_ie6 .dojoxGrid .dojoxGridSortNode { + border: none; +} +.dojoxGridSortBtnNested { + right: 10px; +} +.dojoxGridCellSortFocus .dojoxGridSortBtn { + border-left: 1px solid #999999; + background-color: #DFEAF1; +} +.dojoxGridCellOver .dojoxGridSortBtn { + border-left: 1px solid #999999; + background-color: #9dcfff; +} +.dojoxGridSortNode { + outline: none; +} + +/*Control the title node width*/ +.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode, +.dojoxGridCellSortFocus .dojoxGridSortNode, +.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain, +.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain { + margin-right: 5px; +} +.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode, +.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode { + margin-right: 24px; +} +/*html > body used for !dj_ie6, TBD - a better way*/ +html > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle { + right: -5px; +} +html > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle, +html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle, +html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle { + right: -10px; +} +html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle, +html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle, +html > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle, +html > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle { + right: -28px; +} +html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested, +html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + right: -17px; +} + +.dojoxGrid .dojoxGridHeader .dojoxGridRowTable .dojoxGridNoSort .dojoxGridSortNode { + margin: 0!important; +} + +.dj_ie7 .dojoxGridSortBtn { + right: 0!important; +} +.dj_ie7 .dojoxGridSortBtnNested { + right: 10px!important; +} + +/*Focus border*/ +/*Control visibility*/ +.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle, /* single sort btn is always visible when mouseover*/ +.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle, +.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnNested, /* in a sorted grid, nest btn is always visible when mouseover (except 1)*/ +.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnNested, +.dojoxGrid .dojoxGridCellShowIndex .dojoxGridSortNode .dojoxGridSortBtnNested, /* in a single sort grid, when mouseover other columns, show 1 on the main sort column*/ +.dojoxGrid .dojoxGridSortNodeSorted .dojoxGridSortBtn { /* in a sorted column, single or nested sort btn are always visible (except 2)*/ + visibility: visible; +} +.dojoxGridSingleSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnNested, /*(1)in a single sorted grid, nest btn is hidden in sort column when mouseover*/ +.dojoxGridSingleSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnNested, +.dojoxGridSingleSorted .dojoxGridSortNode .dojoxGridSortBtnNested { /*(2)all nested btn is hidden in single sort grid without mouse over*/ + visibility: hidden; +} + +/* +-119 asc +-99 desc +-159 do asc +-139 do desc +-179 no sort +*/ +/*Control background image*/ +.dojoxGridSortNodeAsc .dojoxGridSortBtnSingle { + background-position: -119px 5px; + visibility: visible; +} +.dojoxGridSortNodeDesc .dojoxGridSortBtnSingle { + background-position: -99px 5px; + visibility: visible; +} +/*hover single sort*/ +.dojoxGridCellOver .dojoxGridSortBtnSingle, +.dojoxGridCellSortFocus .dojoxGridSortBtnSingle { + background-position: -159px 5px; +} +.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle, +.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle, +.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc, +.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc { + background-position: -139px 5px; +} +.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, +.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, +.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc, +.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc { + background-position: -179px 5px; +} +/*hover nested sort*/ +.dojoxGridCellOver .dojoxGridSortBtnNested, +.dojoxGridCellSortFocus .dojoxGridSortBtnNested { + background-position: -149px 5px; + width: 19px; +} +.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested, +.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested { + background-position: -129px 5px; +} +.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested, +.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested { + background-position: -169px 5px; +} +.dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle, +.dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle { + background-position: -159px 5px; +} +.dojoxGridCellOver .dojoxGridSortBtn:hover { + background-color:#A3E4FF; +} +.dojoxGrid .dojoxGridSortNodeFocus, +.dojoxGridCellSortFocus .dojoxGridRowSelector, +.dojoxGridCellSortFocus .dojoxGridSortBtnFocus { + border: 1px dashed #666; +}
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css new file mode 100644 index 0000000..3faaedb --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css @@ -0,0 +1,78 @@ +.dojoxGridRtl .dojoxGridSortBtnSingle { + right: auto; + left: 0px; +} +.dojoxGridRtl .dojoxGridSortBtnNested { + right: auto; + left: 10px; +} + +.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn, +.dj_ie6 dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn, +.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtn { + border-left: none; + border-right: 1px solid #999999; +} + +/*Control the title node width*/ +.dijitRtl .dojoxGridCellOver .dojoxGridSortNode, +.dijitRtl .dojoxGridCellSortFocus .dojoxGridSortNode, +.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain, +.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain { + margin-right: auto; + margin-left: 10px; +} +.dijitRtl .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode, +.dijitRtl .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode { + margin-right: auto; + margin-left: 24px; +} +/*html > body used for !dj_ie6, TBD - a better way*/ +html.dijitRtl > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle { + right: auto; + left: -10px; +} +html.dijitRtl > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle, +html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle, +html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle { + right: auto; + left: -10px; +} +html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle, +html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle, +html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle, +html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle { + right: auto; + left: -28px; +} +html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested, +html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + right: auto; + left: -17px; +} +.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested, +.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + background-position: -159px 5px; + padding-left:8px; +} +.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested, +.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested { + background-position: -139px 5px; +} + +.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested, +.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested { + background-position: -179px 5px; +} +.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested, +.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + padding-left: 8px; + padding-right: 0; +} + +.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested, +.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested, +.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested, +.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + padding-left:0px; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css new file mode 100644 index 0000000..cec6c02 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css @@ -0,0 +1,26 @@ +.claro .dojoxGridHeader .dojoxGridHeaderActive { + background-color:#91c9fe; +} +.claro td.dojoxGridRowSelected { + border-collapse:separate; + background:url("../../../resources/images/row_back.png") #CEE6FA repeat-x; +} +.claro .dojoxGridRowOver td.dojoxGridRowSelected { + border-top:1px solid #769DC0; + border-bottom:1px solid #769DC0; +} +.claro .dojoxGridRowActive td.dojoxGridRowSelected { + background-image:url("../../../resources/images/td_button_down.png"); +} +.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell { + border-color: #ABD6FF; +} +.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell { + border-color: #7DBEFA; +} + +/* Pagination */ +.claro .dojoxGridPaginator{ + background: url("../../../resources/images/header_shadow.png") repeat-x scroll center bottom #E5EDF4; + /*background-color: #EAF1F6;*/ +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css new file mode 100644 index 0000000..5c3b1a6 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css @@ -0,0 +1,4 @@ +@import url("../../../resources/claroGrid.css"); +@import url("../EnhancedGrid.css"); +@import url("Common.css"); +@import url("Filter.css"); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css new file mode 100644 index 0000000..f2069f6 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css @@ -0,0 +1,58 @@ +.claro .dojoxGridFBarInfoTD { + background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom; + background: -moz-linear-gradient(top, #F2F9FF, #EAF5FF); + background: -webkit-gradient(linear, left top, left bottom, from(#F2F9FF), to(#EAF5FF)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFF2F9FF, endColorstr=#FFEAF5FF); +} +.claro .dojoxGridFBarHover .dojoxGridFBarInfoTD { + background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom; + background: -moz-linear-gradient(top, #ECF6FF 2px, #F2F9FF, #EAF5FF 6px); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #ECF6FF), color-stop(0.6, #F2F9FF), color-stop(0.8, #EAF5FF)); +} +.dj_gecko .claro .dojoxGridFBarInfoTD, +.dj_webkit .claro .dojoxGridFBarInfoTD { + border-top: 1px solid #BFD6EB; + border-bottom: 1px solid #BFD6EB; +} +.dj_ie .claro .dojoxGridFBarInner{ + border-top: 1px solid #BFD6EB; + border-bottom: 1px solid #BFD6EB; + display:inline-block; + width: 100%; +} +.claro .dojoxGridFBarClearFilterBtn { + color: #5B83B6; +} +.claro .dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn.dijitButtonHover .dijitButtonText { + text-decoration: underline; +} +.claro .dojoxGridFBar { + border-left: 1px solid white; +} +.claro .dojoxGridFStatusTip table { + border: 1px solid #BCBCBC; +} +.claro .dojoxGridFStatusTip th { + background-color: #E8EFF4; + border-bottom: 1px solid #BCBCBC; +} +.claro .dojoxGridFStatusTip th div { + background-color: #E8EFF4; + border-left: 1px solid white; + border-right: 1px solid #BCBCBC; + border-top: 1px solid white; + border-bottom: 1px solid white; +} +.claro .dojoxGridFStatusTip th.lastColumn div { + border-right: 1px solid white; +} +.claro .dojoxGridFStatusTip td { + border-top: 1px solid white; + border-bottom: 1px solid white; +} +.claro .dojoxGridFStatusTipCondition { + font-style: italic; +} +.claro .dojoxGridFStatusTipOddRow { + background-color: #F1F8FF; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css new file mode 100644 index 0000000..2cbc1de --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css @@ -0,0 +1,2 @@ +/*backward compatible*/ +@import "claro/EnhancedGrid.css";
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.png b/js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.png Binary files differnew file mode 100644 index 0000000..28be879 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.png diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css new file mode 100644 index 0000000..81287aa --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css @@ -0,0 +1,40 @@ +/* overwrite */ +.tundra .dojoxGridHeader .dojoxGridCell{ + background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left; + border-top: 1px solid #bfbfbf; + /*border-left-width: 0px;*/ +} +.tundra .dojoxGridCell { + padding:0px; + /*display:inline;*/ + /*position:relative;*/ + /*border-left-width: 0px;*/ +} +.dj_ie6 .tundra .dojoxGridMasterView .dojoxGridCellOver{ + border: 1px dashed #e9e9e9; +} +.dj_ie6 .tundra .dojoxGridHeader .dojoxGridCellOver{ + border-bottom: none !important; + border-right: 1px solid #D5CDB5 !important; + border-top: 1px solid #D5CDB5 !important; +} +.tundra .dojoxGridRowbarInner { + width:20px; +} +.tundra .dojoxGridCellOver .dojoxGridSortNode, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNode { + cursor:pointer; + background: #f8fafd url("../../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x; +} +/* end overwrite */ + +/* fix safari focus border - overwrite */ +.dj_webkit .tundra .dojoxGridCell, +.dj_webkit .tundra .dojoxGridCellFocus { + outline: none; +} + +/*Pagination*/ +.tundra .dojoxGridPaginator { + background: url("../../../../../dijit/themes/tundra/images/titleBar.png") repeat-x top left; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css new file mode 100644 index 0000000..f8159c8 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css @@ -0,0 +1,5 @@ +@import url("../../../resources/tundraGrid.css"); +@import url("../EnhancedGrid.css"); +@import url("Common.css"); +@import url("Filter.css"); +@import url("Sorter.css"); diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css new file mode 100644 index 0000000..b7b7b83 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css @@ -0,0 +1,38 @@ +.tundra .dojoxGridFBar { + background-color: #eeeeee; + border: 1px solid #bfbfbf; +} +.tundra .dojoxGridFBarFiltered { + background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left; +} +.tundra .dojoxGridFBarHover { + background-color: #cccccc; + background-image: none; +} +.tundra .dojoxGridFStatusTip table { + border: 1px solid #eeeeee; +} +.tundra .dojoxGridFStatusTip th { + background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left; + border-bottom: 1px solid #eeeeee; +} +.tundra .dojoxGridFStatusTip th div { + border-left: 1px solid white; + border-right: 1px solid #eeeeee; + border-top: 1px solid white; + border-bottom: 1px solid white; +} +.tundra .dojoxGridFStatusTip th.lastColumn div { + border-right: 1px solid white; +} +.tundra .dojoxGridFStatusTip td { + border-top: 1px solid white; + border-bottom: 1px solid white; +} +.tundra .dojoxGridFStatusTipRel, +.tundra .dojoxGridFStatusTipCondition { + font-style: italic; +} +.tundra .dojoxGridFStatusTipOddRow { + background-color: #f2f5f9; +} diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css new file mode 100644 index 0000000..480dd7e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css @@ -0,0 +1,83 @@ +.tundra .dojoxGridSortBtn { + padding-top: 3px; +} +.tundra .dojoxGridSortBtnNested { + right: 11px; +} +.tundra .dojoxGridCellOver .dojoxGridSortBtn, +.tundra .dojoxGridCellSortFocus .dojoxGridSortBtn { + background-color: #ccc; +} + +/*Control the title node width*/ +.tundra .dojoxGridCellOver .dojoxGridSortNode, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNode, +.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain, +.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain { + margin-right: 12px; +} +.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode, +.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode { + margin-right: 31px; +} + +/*ie 6 doesn't need below*/ +.tundra .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle, +.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle, +.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle { + right: -12px; +} +.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle, +.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle, +.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle, +.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle { + right: -31px; +} +.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested, +.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + right: -20px; +} +/*ie6 hack end*/ + +/*Control background image*/ +.tundra .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle { + background-position: -119px 8px; +} +.tundra .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle { + background-position: -99px 8px; +} +/*hover single sort*/ +.tundra .dojoxGridCellOver .dojoxGridSortBtnSingle, +.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnSingle { + background-position: -159px 8px; +} +.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle, +.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc, +.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc { + background-position: -139px 8px; +} +.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, +.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc, +.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc { + background-position: -179px 8px; +} +/*hover nested sort*/ +.tundra .dojoxGridCellOver .dojoxGridSortBtnNested, +.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnNested { + background-position: -150px 8px; +} +.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested { + background-position: -130px 8px; +} +.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested, +.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested { + background-position: -170px 8px; +} +.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle, +.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle { + background-position: -159px 8px; +}
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css new file mode 100644 index 0000000..a770d0c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css @@ -0,0 +1,2 @@ +/*backward compatible*/ +@import "tundra/EnhancedGrid.css";
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html new file mode 100644 index 0000000..1637b2e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html @@ -0,0 +1,9 @@ +<div class="dojoxGridClearFilterConfirm"> + <div class="dojoxGridClearFilterMsg"> + ${_clearFilterMsg} + </div> + <div class="dojoxGridClearFilterBtns" dojoAttachPoint="btnsNode"> + <span dojoType="dijit.form.Button" label="${_cancelBtnLabel}" dojoAttachPoint="cancelBtn" dojoAttachEvent="onClick:_onCancel"></span> + <span dojoType="dijit.form.Button" label="${_clearBtnLabel}" dojoAttachPoint="clearBtn" dojoAttachEvent="onClick:_onClear"></span> + </div> +</div> diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html new file mode 100644 index 0000000..ad9a1ec --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html @@ -0,0 +1,20 @@ +<div class="dojoxGridFCBox"> + <div class="dojoxGridFCBoxSelCol" dojoAttachPoint="selColNode"> + <span class="dojoxGridFCBoxField">${_colSelectLabel}</span> + <select dojoAttachPoint="_colSelect" dojoType="dijit.form.Select" + class="dojoxGridFCBoxColSelect" + dojoAttachEvent="onChange:_onChangeColumn"> + </select> + </div> + <div class="dojoxGridFCBoxCondition" dojoAttachPoint="condNode"> + <span class="dojoxGridFCBoxField">${_condSelectLabel}</span> + <select dojoAttachPoint="_condSelect" dojoType="dijit.form.Select" + class="dojoxGridFCBoxCondSelect" + dojoAttachEvent="onChange:_onChangeCondition"> + </select> + <div class="dojoxGridFCBoxCondSelectAlt" dojoAttachPoint="_condSelectAlt" style="display:none;"></div> + </div> + <div class="dojoxGridFCBoxValue" dojoAttachPoint="valueNode"> + <span class="dojoxGridFCBoxField">${_valueBoxLabel}</span> + </div> +</div> diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html new file mode 100644 index 0000000..cbcb68d --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html @@ -0,0 +1,15 @@ +<table class="dojoxGridFBar" border="0" cellspacing="0" dojoAttachEvent="onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove" + ><tr><td class="dojoxGridFBarBtnTD" + ><span dojoType="dijit.form.Button" class="dojoxGridFBarBtn" dojoAttachPoint="defineFilterButton" label="..." iconClass="dojoxGridFBarDefFilterBtnIcon" showLabel="true" dojoAttachEvent="onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span + ></td><td class="dojoxGridFBarInfoTD" + ><span class="dojoxGridFBarInner" + ><span class="dojoxGridFBarStatus" dojoAttachPoint="statusBarNode">${_noFilterMsg}</span + ><span dojoType="dijit.form.Button" class="dojoxGridFBarClearFilterBtn" dojoAttachPoint="clearFilterButton" + label="${_filterBarClearBtnLabel}" iconClass="dojoxGridFBarClearFilterBtnIcon" showLabel="true" + dojoAttachEvent="onClick:_clearFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span + ><span dojotype="dijit.form.Button" class="dojoxGridFBarCloseBtn" dojoAttachPoint="closeFilterBarButton" + label="${_closeFilterBarBtnLabel}" iconClass="dojoxGridFBarCloseBtnIcon" showLabel="false" + dojoAttachEvent="onClick:_closeFilterBar, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span + ></span + ></td></tr +></table> diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html new file mode 100644 index 0000000..6779e70 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html @@ -0,0 +1,11 @@ +<div class="dojoxGridBoolValueBox"> + <div class="dojoxGridTrueBox"> + <input dojoType="dijit.form.RadioButton" type='radio' name='a1' id='${_baseId}_rbTrue' checked="true" + dojoAttachPoint="rbTrue" dojoAttachEvent="onChange: onChange"/> + <div class="dojoxGridTrueLabel" for='${_baseId}_rbTrue'>${_lblTrue}</div> + </div> + <div class="dojoxGridFalseBox"> + <input dojoType="dijit.form.RadioButton" dojoAttachPoint="rbFalse" type='radio' name='a1' id='${_baseId}_rbFalse'/> + <div class="dojoxGridTrueLabel" for='${_baseId}_rbFalse'>${_lblFalse}</div> + </div> +</div> diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html new file mode 100644 index 0000000..5783f36 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html @@ -0,0 +1,27 @@ +<div class="dojoxGridFDPane"> + <div class="dojoxGridFDPaneRelation">${_relMsgFront} + <span class="dojoxGridFDPaneModes" dojoAttachPoint="criteriaModeNode"> + <select dojoAttachPoint="_relSelect" dojoType="dijit.form.Select" dojoAttachEvent="onChange: _onRelSelectChange"> + <option value="0">${_relAll}</option> + <option value="1">${_relAny}</option> + </select> + </span> + ${_relMsgTail} + </div> + <div dojoAttachPoint="criteriaPane" class="dojoxGridFDPaneRulePane"></div> + <div dojoAttachPoint="_addCBoxBtn" dojoType="dijit.form.Button" + class="dojoxGridFDPaneAddCBoxBtn" iconClass="dojoxGridFDPaneAddCBoxBtnIcon" + dojoAttachEvent="onClick:_onAddCBox" label="${_addRuleBtnLabel}" showLabel="false"> + </div> + <div class="dojoxGridFDPaneBtns" dojoAttachPoint="buttonsPane"> + <span dojoAttachPoint="_cancelBtn" dojoType="dijit.form.Button" + dojoAttachEvent="onClick:_onCancel" label="${_cancelBtnLabel}"> + </span> + <span dojoAttachPoint="_clearFilterBtn" dojoType="dijit.form.Button" + dojoAttachEvent="onClick:_onClearFilter" label="${_clearBtnLabel}" disabled="true"> + </span> + <span dojoAttachPoint="_filterBtn" dojoType="dijit.form.Button" + dojoAttachEvent="onClick:_onFilter" label="${_filterBtnLabel}" disabled="true"> + </span> + </div> +</div> diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html new file mode 100644 index 0000000..67be8d4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html @@ -0,0 +1,8 @@ +<div class="dojoxGridFStatusTip" + ><div class="dojoxGridFStatusTipHead" + ><span class="dojoxGridFStatusTipTitle" dojoAttachPoint="statusTitle"></span + ><span class="dojoxGridFStatusTipRel" dojoAttachPoint="statusRel"></span + ></div + ><div class="dojoxGridFStatusTipDetail" dojoAttachPoint="statusDetailNode" + ></div +></div> diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html new file mode 100644 index 0000000..ad55539 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html @@ -0,0 +1,18 @@ +<div dojoAttachPoint="paginatorBar" + ><table cellpadding="0" cellspacing="0" class="dojoxGridPaginator" + ><tr + ><td dojoAttachPoint="descriptionTd" class="dojoxGridDescriptionTd" + ><div dojoAttachPoint="descriptionDiv" class="dojoxGridDescription"></div + ></div></td + ><td dojoAttachPoint="sizeSwitchTd"></td + ><td dojoAttachPoint="pageStepperTd" class="dojoxGridPaginatorFastStep" + ><div dojoAttachPoint="pageStepperDiv" class="dojoxGridPaginatorStep"></div + ></td + ><td dojoAttachPoint="gotoPageTd" class="dojoxGridPaginatorGotoTd" + ><div dojoAttachPoint="gotoPageDiv" class="dojoxGridPaginatorGotoDiv" dojoAttachEvent="onclick:_openGotopageDialog, onkeydown:_openGotopageDialog" + ><span class="dojoxGridWardButtonInner">⊥</span + ></div + ></td + ></tr + ></table +></div> diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js new file mode 100644 index 0000000..390c46a --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/ar/loading':function(){ +define( +"dijit/nls/ar/loading", //begin v1.x content +({ + loadingState: "جاري التحميل...", + errorState: "عفوا، حدث خطأ" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_ar", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js new file mode 100644 index 0000000..1feb0e3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js @@ -0,0 +1,14 @@ +require({cache:{ +'dijit/nls/ca/loading':function(){ +define( +"dijit/nls/ca/loading", //begin v1.x content +({ + loadingState: "S'està carregant...", + errorState: "Ens sap greu. S'ha produït un error." +}) + +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_ca", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js new file mode 100644 index 0000000..b94f219 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/cs/loading':function(){ +define( +"dijit/nls/cs/loading", //begin v1.x content +({ + loadingState: "Probíhá načítání...", + errorState: "Omlouváme se, došlo k chybě" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_cs", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js new file mode 100644 index 0000000..5c34308 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/da/loading':function(){ +define( +"dijit/nls/da/loading", //begin v1.x content +({ + loadingState: "Indlæser...", + errorState: "Der er opstået en fejl" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_da", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js new file mode 100644 index 0000000..accf1f4 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/de/loading':function(){ +define( +"dijit/nls/de/loading", //begin v1.x content +({ + loadingState: "Wird geladen...", + errorState: "Es ist ein Fehler aufgetreten." +}) +//end v1.x content +); + +}, +'dijit/nls/de-de/loading':function(){ +define('dijit/nls/de-de/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_de-de", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js new file mode 100644 index 0000000..4435820 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/el/loading':function(){ +define( +"dijit/nls/el/loading", //begin v1.x content +({ + loadingState: "Φόρτωση...", + errorState: "Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_el", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js new file mode 100644 index 0000000..8f29801 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js @@ -0,0 +1,8 @@ +require({cache:{ +'dijit/nls/en/loading':function(){ +define('dijit/nls/en/loading',{}); +}, +'dijit/nls/en-gb/loading':function(){ +define('dijit/nls/en-gb/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_en-gb", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js new file mode 100644 index 0000000..b976308 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js @@ -0,0 +1,8 @@ +require({cache:{ +'dijit/nls/en/loading':function(){ +define('dijit/nls/en/loading',{}); +}, +'dijit/nls/en-us/loading':function(){ +define('dijit/nls/en-us/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_en-us", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js new file mode 100644 index 0000000..28678e3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/es/loading':function(){ +define( +"dijit/nls/es/loading", //begin v1.x content +({ + loadingState: "Cargando...", + errorState: "Lo siento, se ha producido un error" +}) +//end v1.x content +); + +}, +'dijit/nls/es-es/loading':function(){ +define('dijit/nls/es-es/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_es-es", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js new file mode 100644 index 0000000..179a611 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/fi/loading':function(){ +define( +"dijit/nls/fi/loading", //begin v1.x content +({ + loadingState: "Lataus on meneillään...", + errorState: "On ilmennyt virhe." +}) +//end v1.x content +); + +}, +'dijit/nls/fi-fi/loading':function(){ +define('dijit/nls/fi-fi/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_fi-fi", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js new file mode 100644 index 0000000..cc3b0b6 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/fr/loading':function(){ +define( +"dijit/nls/fr/loading", //begin v1.x content +({ + loadingState: "Chargement...", + errorState: "Une erreur est survenue" +}) +//end v1.x content +); + +}, +'dijit/nls/fr-fr/loading':function(){ +define('dijit/nls/fr-fr/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_fr-fr", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js new file mode 100644 index 0000000..4860cea --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/he/loading':function(){ +define( +"dijit/nls/he/loading", //begin v1.x content +({ + loadingState: "טעינה...", + errorState: "אירעה שגיאה" +}) +//end v1.x content +); + +}, +'dijit/nls/he-il/loading':function(){ +define('dijit/nls/he-il/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_he-il", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js new file mode 100644 index 0000000..727babd --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/hu/loading':function(){ +define( +"dijit/nls/hu/loading", //begin v1.x content +({ + loadingState: "Betöltés...", + errorState: "Sajnálom, hiba történt" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_hu", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js new file mode 100644 index 0000000..e1e511f --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/it/loading':function(){ +define( +"dijit/nls/it/loading", //begin v1.x content +({ + loadingState: "Caricamento in corso...", + errorState: "Si è verificato un errore" +}) +//end v1.x content +); + +}, +'dijit/nls/it-it/loading':function(){ +define('dijit/nls/it-it/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_it-it", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js new file mode 100644 index 0000000..11bd0e3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/ja/loading':function(){ +define( +"dijit/nls/ja/loading", //begin v1.x content +({ + loadingState: "ロード中...", + errorState: "エラーが発生しました。" +}) +//end v1.x content +); + +}, +'dijit/nls/ja-jp/loading':function(){ +define('dijit/nls/ja-jp/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_ja-jp", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js new file mode 100644 index 0000000..2b41718 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/ko/loading':function(){ +define( +"dijit/nls/ko/loading", //begin v1.x content +({ + loadingState: "로드 중...", + errorState: "죄송합니다. 오류가 발생했습니다." +}) +//end v1.x content +); + +}, +'dijit/nls/ko-kr/loading':function(){ +define('dijit/nls/ko-kr/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_ko-kr", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js new file mode 100644 index 0000000..5a97924 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/nb/loading':function(){ +define( +"dijit/nls/nb/loading", //begin v1.x content +({ + loadingState: "Laster inn...", + errorState: "Det oppsto en feil" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_nb", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js new file mode 100644 index 0000000..9ea82a6 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/nl/loading':function(){ +define( +"dijit/nls/nl/loading", //begin v1.x content +({ + loadingState: "Bezig met laden...", + errorState: "Er is een fout opgetreden" +}) +//end v1.x content +); + +}, +'dijit/nls/nl-nl/loading':function(){ +define('dijit/nls/nl-nl/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_nl-nl", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js new file mode 100644 index 0000000..b05d618 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/pl/loading':function(){ +define( +"dijit/nls/pl/loading", //begin v1.x content +({ + loadingState: "Ładowanie...", + errorState: "Niestety, wystąpił błąd" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_pl", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js new file mode 100644 index 0000000..adc10b5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/pt/loading':function(){ +define( +"dijit/nls/pt/loading", //begin v1.x content +({ + loadingState: "Carregando...", + errorState: "Desculpe, ocorreu um erro" +}) +//end v1.x content +); + +}, +'dijit/nls/pt-br/loading':function(){ +define('dijit/nls/pt-br/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_pt-br", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js new file mode 100644 index 0000000..9166a57 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js @@ -0,0 +1,24 @@ +require({cache:{ +'dijit/nls/pt/loading':function(){ +define( +"dijit/nls/pt/loading", //begin v1.x content +({ + loadingState: "Carregando...", + errorState: "Desculpe, ocorreu um erro" +}) +//end v1.x content +); + +}, +'dijit/nls/pt-pt/loading':function(){ +define( +"dijit/nls/pt-pt/loading", //begin v1.x content +({ + loadingState: "A carregar...", + errorState: "Lamentamos, mas ocorreu um erro" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_pt-pt", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js new file mode 100644 index 0000000..82e1d68 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/ru/loading':function(){ +define( +"dijit/nls/ru/loading", //begin v1.x content +({ + loadingState: "Загрузка...", + errorState: "Извините, возникла ошибка" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_ru", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js new file mode 100644 index 0000000..7131b05 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js @@ -0,0 +1,14 @@ +require({cache:{ +'dijit/nls/sk/loading':function(){ +define( +"dijit/nls/sk/loading", //begin v1.x content +({ + loadingState: "Zavádzanie...", + errorState: "Nastala chyba" +}) + +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_sk", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js new file mode 100644 index 0000000..d77812e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/sl/loading':function(){ +define( +"dijit/nls/sl/loading", //begin v1.x content +({ + loadingState: "Nalaganje ...", + errorState: "Oprostite, prišlo je do napake." +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_sl", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js new file mode 100644 index 0000000..349064c --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/sv/loading':function(){ +define( +"dijit/nls/sv/loading", //begin v1.x content +({ + loadingState: "Läser in...", + errorState: "Det uppstod ett fel." +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_sv", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js new file mode 100644 index 0000000..103309b --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js @@ -0,0 +1,14 @@ +require({cache:{ +'dijit/nls/th/loading':function(){ +define( +"dijit/nls/th/loading", //begin v1.x content +({ + loadingState: "กำลังโหลด...", + errorState: "ขออภัย เกิดข้อผิดพลาด" +}) + +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_th", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js new file mode 100644 index 0000000..a90dfaa --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js @@ -0,0 +1,13 @@ +require({cache:{ +'dijit/nls/tr/loading':function(){ +define( +"dijit/nls/tr/loading", //begin v1.x content +({ + loadingState: "Yükleniyor...", + errorState: "Üzgünüz, bir hata oluştu" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_tr", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js new file mode 100644 index 0000000..61e19ec --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js @@ -0,0 +1,16 @@ +require({cache:{ +'dijit/nls/zh/loading':function(){ +define( +"dijit/nls/zh/loading", //begin v1.x content +({ + loadingState: "正在加载...", + errorState: "对不起,发生了错误" +}) +//end v1.x content +); + +}, +'dijit/nls/zh-cn/loading':function(){ +define('dijit/nls/zh-cn/loading',{}); +}}}); +define("dojox/grid/nls/DataGrid_zh-cn", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js new file mode 100644 index 0000000..a4aa781 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js @@ -0,0 +1,24 @@ +require({cache:{ +'dijit/nls/zh/loading':function(){ +define( +"dijit/nls/zh/loading", //begin v1.x content +({ + loadingState: "正在加载...", + errorState: "对不起,发生了错误" +}) +//end v1.x content +); + +}, +'dijit/nls/zh-tw/loading':function(){ +define( +"dijit/nls/zh-tw/loading", //begin v1.x content +({ + loadingState: "載入中...", + errorState: "抱歉,發生錯誤" +}) +//end v1.x content +); + +}}}); +define("dojox/grid/nls/DataGrid_zh-tw", [], 1); diff --git a/js/dojo-1.7.2/dojox/grid/resources/Expando.html b/js/dojo-1.7.2/dojox/grid/resources/Expando.html new file mode 100644 index 0000000..c7e7c22 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/Expando.html @@ -0,0 +1,5 @@ +<div class="dojoxGridExpando" + ><div class="dojoxGridExpandoNode" dojoAttachEvent="onclick:onToggle" + ><div class="dojoxGridExpandoNodeInner" dojoAttachPoint="expandoInner"></div + ></div +></div> diff --git a/js/dojo-1.7.2/dojox/grid/resources/Grid.css b/js/dojo-1.7.2/dojox/grid/resources/Grid.css new file mode 100644 index 0000000..037d906 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/Grid.css @@ -0,0 +1,415 @@ +.dojoxGrid { + position: relative; + background-color: #EBEADB; + font-family: Geneva, Arial, Helvetica, sans-serif; + -moz-outline-style: none; + outline: none; + overflow: hidden; + height: 0; +} + +.dojoxGrid table { + padding: 0; +} + +.dojoxGrid td { + -moz-outline: none; +} + +/* master header */ + +.dojoxGridMasterHeader { + position: relative; +} + +/* master view */ + +.dojoxGridMasterView { + position: relative; +} + +/* master messages */ + +.dojoxGridMasterMessages { + position: relative; + padding: 1em; + text-align: center; + background-color: white; +} + +/* views */ + +.dojoxGridView { + position: absolute; + overflow: hidden; +} + +/* header */ + +.dojoxGridHeader { + position: absolute; + overflow: hidden; + cursor: default; +} + +.dojoxGridHeader { + background-color: #E8E1CF; +} + +.dojoxGridHeader table { + text-align: center; +} + +.dojoxGridHeader .dojoxGridCell { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; + padding-bottom: 2px; +} + +.dojoxGridHeader .dojoxGridCellOver { + background-image: none; + background-color: white; + border-bottom-color: #FEBE47; + margin-bottom: 0; + padding-bottom: 0; + border-bottom-width: 3px; +} + +.dojoxGridHeader .dojoxGridCellFocus { + border: 1px dashed blue; +} + +.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver { + background-image: none; + background-color: white; + border-bottom-color: #FEBE47; + margin-bottom: 0; + padding-bottom: 0; + border-bottom-width: 3px; +} +.dojoxGridArrowButtonNode { + display: none; + padding-left: 16px; +} +.dojoxGridArrowButtonChar { + display:inline; +} + +/* Need to explicitly define how to treat hovering over the arrow on IE */ +.dojoxGridArrowButtonNode:hover { + cursor: default; +} +.dojoxGridArrowButtonChar:hover { + cursor: default; +} +.dojoxGridSortUp:hover { + cursor: default; +} +.dojoxGridSortDown:hover { + cursor: default; +} + +.dijit_a11y .dojoxGridArrowButtonChar { + display:inline !important; +} + +/* content */ + +.dojoxGridScrollbox { + position: relative; + overflow: auto; + background-color: white; + width: 100%; +} + +.dojoxGridContent { + position: relative; + overflow: hidden; + -moz-outline-style: none; + outline: none; +} + +/* rowbar */ + +.dojoxGridRowbar { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + border-top: none; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; +} + +.dojoxGridRowbarInner { + border-top: 1px solid #F6F4EB; +} + +.dojoxGridRowbarOver { + background-image: none; + background-color: white; + border-top-color: #FEBE47; + border-bottom-color: #FEBE47; +} + +.dojoxGridRowbarSelected { + background-color: #D9E8F9; +} + +/* rows */ + +.dojoxGridRow { + position: relative; + width: 9000em; +} + +.dojoxGridRow { + /*border: 1px solid #E8E4D8;*/ + border: 1px solid #E8E4D8; + border-color: #F8F7F1; + /*padding: 0 0 1px 0;*/ + border-left: none; + border-right: none; + background-color: white; + border-top: none; +} + +.dojoxGridRowOver { + border-top-color: #FEBE47; + border-bottom-color: #FEBE47; + /*border-bottom-width: 2px; + padding-bottom: 0;*/ + /*background-color: #FFDD9D;*/ + /*background-color: #FDFDFD;*/ +} + +.dojoxGridRowOdd { + background-color: #FFFDF3; + /*background-color: #F9F7E8;*/ +} + +.dojoxGridRowSelected { + background-color: #D9E8F9; +} + +.dojoxGridRowTable { + table-layout: fixed; + width: 0; + empty-cells: show; +} +.dj_ie .dojoxGridRowTable { + border-collapse: collapse; +} + +.dojoxGridInvisible { + visibility: hidden; +} + +.Xdojo-ie .dojoxGridInvisible { + display: none; +} + +.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td { + border-top-width: 0; + border-bottom-width: 0; + padding-top: 0; + padding-bottom: 0; + height: 0; + overflow: hidden; +} + +/* cells */ + +.dojoxGridCell { + border: 1px solid; + border-color: #EBEADB; + border-right-color: #D5CDB5; + padding: 3px 3px 3px 3px; + text-align: left; + overflow: hidden; +} + +.dojoxGridCellFocus { + border: 1px dashed blue; +} + +.dojoxGridCellOver { + border: 1px dotted #FEBE47; +} + +.dojoxGridCellFocus.dojoxGridCellOver { + border: 1px dashed green; +} + +/* editing */ + +.dojoxGridRowEditing td { + background-color: #F4FFF4; +} + +.dojoxGridRow-inserting td { + background-color: #F4FFF4; +} +.dojoxGridRow-inflight td { + background-color: #F2F7B7; +} +.dojoxGridRow-error td { + background-color: #F8B8B6; +} + +.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea { + margin: 0; + padding: 0; + border-style: none; + width: 100%; + font-size: 100%; + font-family: inherit; +} + +.dojoxGridHiddenFocus { + position: absolute; + top: -1000px; + height: 0; + width: 0; +} + +.dijit_a11y .dojoxGridRowbarSelected { + border-top: 1px solid white; + border-bottom: 1px dashed black; + border-top: 0; + background: none; +} + +.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner { + border: 0; + border-top: 1px solid white; +} + +.dijit_a11y .dojoxGridRowSelected { + border: 1px solid black !important; +} + +/* Drag and Drop */ +.dojoxGridDndAvatar { + font-size: 100%; +} +.dojoxGrid .dojoDndItemBefore { + border-left-color: red; +} +.dojoxGrid .dojoDndItemAfter { + border-right-color: red; +} +.dijit_a11y .dojoDndItemBefore { + border-left: double; +} +.dijit_a11y .dojoDndItemAfter { + border-right: double; +} +.dojoxGridDndAvatarItem td { + border: 1px solid; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x; + padding: 0pt; + margin: 0pt; +} +.dojoxGridDndAvatarItem td.dojoxGridDndAvatarItemImage { + border: 0; + border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB; + background-color: transparent; + padding: 3px; + padding-bottom: 2px; + margin: 0; +} +.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage { + background-image: url(../../../dojo/resources/images/dndNoMove.png); + background-repeat: no-repeat; + background-position: center center; +} +.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage { + background-image: url(../../../dojo/resources/images/dndNoCopy.png); + background-repeat: no-repeat; + background-position: center center; +} +.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage { + background-image: url(../../../dojo/resources/images/dndMove.png); + background-repeat: no-repeat; + background-position: center center; +} +.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage { + background-image: url(../../../dojo/resources/images/dndCopy.png); + background-repeat: no-repeat; + background-position: center center; +} + +.dojoxGridColPlaceBottom { + background: transparent url(images/grid_sort_up.gif) no-repeat scroll left top; +} +.dojoxGridColPlaceTop { + background: transparent url(images/grid_sort_down.gif) no-repeat scroll left top; +} + +.dojoxGridColPlaceTop, .dojoxGridColPlaceBottom { + font-size:1px; + height:6px; + z-index:10000; + top:0; + overflow:hidden; + position:absolute; + line-height:1px; + width:8px; +} +.dojoxGridResizeColLine { + width: 1px; + background-color: #777; + position: absolute; + cursor: col-resize; + z-index:10000; +} +.dojoxGridColNoResize, +.dojoxGridColNoResize .dojoDndItemOver { + cursor: not-allowed !important; +} +.dojoxGridColResize, +.dojoxGridColResize .dojoDndItemOver, +.dojoxGridColumnResizing, +.dojoxGridColumnResizing .dojoDndItemOver, +.dojoxGridColumnResizing .dojoxGridHeader { + cursor: col-resize !important; +} + +.dojoxGridColPlaceBottom { + background: transparent url(images/grid_sort_up.gif) no-repeat scroll left top; +} +.dojoxGridColPlaceTop { + background: transparent url(images/grid_sort_down.gif) no-repeat scroll left top; +} + +.dojoxGridColPlaceTop, .dojoxGridColPlaceBottom { + font-size:1px; + height:6px; + z-index:10000; + top:0; + overflow:hidden; + position:absolute; + line-height:1px; + width:8px; +} +.dojoxGridResizeColLine { + width: 1px; + background-color: #777; + position: absolute; +} + +/* Tree Grid */ +.dojoxGridExpandoCell { + vertical-align: middle; +} +.dojoxGridSummarySpan { + visibility: hidden; +} +.dojoxGridSummaryRow .dojoxGridSummarySpan, +.dojoxGridRowCollapsed .dojoxGridSummarySpan { + visibility: visible; +} +.dojoxGridNoChildren .dojoxGridExpando { + visibility: hidden !important; + width: 0px !important; +}
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css b/js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css new file mode 100644 index 0000000..77d2dd5 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css @@ -0,0 +1,15 @@ +.dj_ie .dojoxGridRtl .dojoxGridHeader table { + float:none; +} + +.dojoxGridRtl .dojoxGridCell { + text-align:right; +} + +.dj_ie8 .dojoxGridRtl .dojoxGridCell { + border-left: none; +} + +.dojoxGridRtl .dojoxGridArrowButtonNode { + float:left; +}
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/grid/resources/View.html b/js/dojo-1.7.2/dojox/grid/resources/View.html new file mode 100644 index 0000000..578b705 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/View.html @@ -0,0 +1,12 @@ +<div class="dojoxGridView" role="presentation"> + <div class="dojoxGridHeader" dojoAttachPoint="headerNode" role="presentation"> + <div dojoAttachPoint="headerNodeContainer" style="width:9000em" role="presentation"> + <div dojoAttachPoint="headerContentNode" role="row"></div> + </div> + </div> + <input type="checkbox" class="dojoxGridHiddenFocus" dojoAttachPoint="hiddenFocusNode" role="presentation" /> + <input type="checkbox" class="dojoxGridHiddenFocus" role="presentation" /> + <div class="dojoxGridScrollbox" dojoAttachPoint="scrollboxNode" role="presentation"> + <div class="dojoxGridContent" dojoAttachPoint="contentNode" hidefocus="hidefocus" role="presentation"></div> + </div> +</div> diff --git a/js/dojo-1.7.2/dojox/grid/resources/_Grid.html b/js/dojo-1.7.2/dojox/grid/resources/_Grid.html new file mode 100644 index 0000000..2db90e1 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/_Grid.html @@ -0,0 +1,6 @@ +<div hidefocus="hidefocus" role="grid" dojoAttachEvent="onmouseout:_mouseOut"> + <div class="dojoxGridMasterHeader" dojoAttachPoint="viewsHeaderNode" role="presentation"></div> + <div class="dojoxGridMasterView" dojoAttachPoint="viewsNode" role="presentation"></div> + <div class="dojoxGridMasterMessages" style="display: none;" dojoAttachPoint="messagesNode"></div> + <span dojoAttachPoint="lastFocusNode" tabindex="0"></span> +</div> diff --git a/js/dojo-1.7.2/dojox/grid/resources/claroGrid.css b/js/dojo-1.7.2/dojox/grid/resources/claroGrid.css new file mode 100644 index 0000000..f15ff84 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/claroGrid.css @@ -0,0 +1,311 @@ +/* Claro styles for DataGrid */ +@import url("Grid.css"); + +.claro .dojoxGrid { + margin:0px; + padding:0px; + border-collapse:collapse; + background-color: #fff; + border: 1px solid #DBDBDB; +} +/* messages */ +.claro .dojoxGridMasterMessages { + background-color: #fefefe; +} +.claro .dojoxGridLoading, +.claro .dojoxGridError { + background-position:left center; + background-repeat: no-repeat; + padding-left:25px; +} +.claro .dojoxGridLoading { + background-image:url("../../../dijit/themes/claro/images/loadingAnimation.gif"); +} +.claro .dojoxGridError { + background-image: url('../../../dijit/icons/images/commonIconsObjActEnabled.png'); + background-position: -496px; + width: 16px; + height: 16px; +} + +/* header */ +.claro .dojoxGridHeader { + background: transparent; + margin-left: -2px; +} +.claro .dojoxGridHeader .dojoxGridCell { + padding: 2px 5px; + vertical-align: top; + background: transparent; + border-style:solid; + border-width:1px; + border-color: #FFFFFF #BCBCBC #BCBCBC #FFFFFF; +} +.dj_ie6 .claro .dojoxGridHeader .dojoxGridCell { + border-color:#BCBCBC #BCBCBC #BCBCBC #e5edf4; +} +.claro .dojoxGridHeader .dojoxGridCellOver { + background: #9dcfff; +} + +/* header sorting arrow */ +.claro .dojoxGridSortNode { + text-decoration:none; + display:block; + white-space: normal; + background: none; + border: none; + padding: 0; +} +.claro .dojoxGridCellOver .dojoxGridSortNode { + background-color:#9dcfff; +} +.claro .dojoxGridArrowButtonChar { + display:none; + float:right; +} +.claro .dojoxGridArrowButtonNode { + background:transparent url("../../../dijit/themes/claro/images/spriteArrows.png") no-repeat scroll left center; + display:block; + float:right; + height:1em; + margin:2px 4px 0 5px; + padding-left:0; + width:7px; +} +.claro .dojoxGridSortUp .dojoxGridArrowButtonNode { + background-position:-21px 50%; +} + +/* header rows */ +.claro .dojoxGridMasterHeader { + background: url("images/header.png") #EDF2F7 repeat-x bottom; + background: -moz-linear-gradient(top, #EDF2F7, #D0DFEA); + background: -webkit-gradient(linear, left top, left bottom, from(#EDF2F7), to(#D0DFEA)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFEDF2F7, endColorstr=#FFD0DFEA); + border: 1px solid #FFFFFF; + border-right: none; +} +.claro .dojoxGridMasterHeader .dojoxGridRowTable { + border-left: 1px solid #BCBCBC; + border-right: 1px solid #FFFFFF; + background-color: transparent; +} +.dj_ie .claro .dojoxGridHeader .dojoxGridRowTable { + border-collapse:separate; +} +.claro .dojoxGridHeader .dojoxGridRowTable tr { + background: none; +} +.claro .dojoxGridHeader tr:first-child .dojoxGridCell { + border-top: 1px solid transparent; +} +.claro .dojoxGridHeader:first-child .dojoxGridRowTable { + border-left-width: 0; +} +.claro .dojoxGridHeader:first-child { + margin-left: -1px; +} +/* Grid view content */ +.claro .dojoxGridScrollbox { + background-color: #fefefe; +} + +/* rowbar - row headers */ +.claro .dojoxGridRowbar { + background:url("images/header.png") #e5edf4 repeat-x top; + border:none; + border-right:1px solid #BCBCBC; +} +.claro .dojoxGridRowbarTable { + background:transparent url("images/header_shadow.png") repeat-x scroll center bottom; +} +.dj_ie6 .claro .dojoxGridRowbar, +.dj_ie6 .claro .dojoxGridRowbarTable { + background-image:none; +} +.claro .dojoxGridRowbarInner { + border:none; + border-bottom:1px solid #ccc; +} +.claro .dojoxGridRowbarOver .dojoxGridRowbarTable { + background-color:#abd5fd; +} +.claro .dojoxGridRowbarSelected { + background-color:#abd5fd; + border-right:1px solid #ccc; +} + +/* rows */ +.claro .dojoxGridRow { + border:none; + background-color:#fff; +} +.dj_ie .claro .dojoxGridMasterView .dojoxGridRowTable { + border-collapse:separate;/*IE, separate is must to show the border of tr and td*/ +} +.claro .dojoxGridRowTable tr { + background:url("images/row_back.png") #fff repeat-x; +} +.claro .dojoxGridRowOdd .dojoxGridRowTable tr { + background-color:#f7fcff; +} +.claro .dojoxGridRowSelected .dojoxGridRowTable tr { + background-color:#cee6fa; +} + +/* cells */ +.claro .dojoxGridCell { + outline: none; + padding: 3px 5px; + word-wrap: break-word; + border:1px solid transparent; + border-color: transparent #E5DAC8 #E5DAC8 transparent; +} +.dj_ie6 .claro .dojoxGridCell { + border-color: #F5F5F5; +} +.dj_ie6 .claro .dojoxGridRowOdd .dojoxGridCell { + border-left-color:#f4f9fd; + border-right-color:#f4f9fd; +} +.dj_ie6 .claro .dojoxGridRowSelected .dojoxGridCell { + border-left-color:#d3e9fb; + border-right-color:#d3e9fb; +} +.claro .dojoxGridRowSelected .dojoxGridCell { + border-top:1px solid #BFD6EB; + border-bottom:1px solid #BFD6EB; +} +.claro .dojoxGridCellFocus { + outline: none; + border:1px dashed darkblue !important; +} + +/* Single Affordance Hover Effect */ +.claro .dojoxGridRowOver .dojoxGridCell { + background:url("images/row_back.png") #ABD6FF repeat-x; + border-top:1px solid #769DC0; + border-bottom:1px solid #769DC0; +} +.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell, +.dj_ie7 .claro .dojoxGridRowOver .dojoxGridCell { + border-left:1px solid #ABD6FF; + border-right:1px solid #ABD6FF; +} +.claro .dojoxGridRowActive .dojoxGridCell { + background:url("images/td_button_down.png") #7DBEFA repeat-x; +} +.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell, +.dj_ie7 .claro .dojoxGridRowActive .dojoxGridCell { + border-left:1px solid #7DBEFA; + border-right:1px solid #7DBEFA; +} + +/* Double Affordance Hover Effect */ +.claro .dojoxGridDoubleAffordance .dojoxGridRowOver .dojoxGridCellOver { + border:solid 1px #769dc0; + background-color:#93cafe; + border-collapse:separate;/*FF*/ +} +.claro .dojoxGridDoubleAffordance .dojoxGridRowActive .dojoxGridCell{ + background-image:url("images/row_back.png"); +} +.claro .dojoxGridDoubleAffordance .dojoxGridRowActive .dojoxGridCellActive { + background:url("images/td_button_down.png") #93cafe repeat-x; +} +.dj_ie6 .claro .dojoxGridCell { + background-image:none !important; +} + +/* editing */ +.claro .dojoxGridRowEditing td { + /* background-color: #F4FFF4; */ + background-color: #cee6fa; + /* padding: 0px 3px 0px 3px; */ +} +.claro .dojoxGridRow-inserting td { + background-color: #F4FFF4; +} +.claro .dojoxGridRow-inflight td { + background-color: #F2F7B7; +} +.claro .dojoxGridRow-error td { + background-color: #F8B8B6; +} + +/* Drag and Drop */ +.claro .dojoxGrid .dojoDndItemBefore { + border-left-color: #3559ac; +} +.claro .dojoxGrid .dojoDndItemAfter { + border-right-color: #3559ac; +} + +/* Tree Grid */ +.claro .dojoxGridExpando { + float: left; + height: 18px; + width: 18px; + text-align: center; + margin-top: -3px; +} +.dijitRtl .claro .dojoxGridExpando { + float: right; +} +.claro .dojoxGridExpandoCell { + padding-top: 5px; + background-position: left top !important; +} +.claro .dojoxGridExpandoNode { + background-image: url('../../../dijit/themes/claro/images/treeExpandImages.png'); + width: 16px; + height: 16px; + cursor: pointer; + background-position: 1px 0px; /* for closed state */ +} +.dj_ie6 .claro .dojoxGridExpandoNode { + background-image: url('../../../dijit/themes/claro/images/treeExpandImages8bit.png'); +} +.claro .dojoxGridRowOver .dojoxGridExpandoNode { + background-position: -17px 0px; +} +.claro .dojoxGridExpandoOpened .dojoxGridExpandoNode { + background-position: -35px 0px; +} +.claro .dojoxGridRowOver .dojoxGridExpandoOpened .dojoxGridExpandoNode { + background-position: -53px 0px; +} +.claro .dojoxGridExpandoLoading .dojoxGridExpandoNode { + background-image: url('../../../dijit/themes/claro/images/loadingAnimation.gif'); +} +.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando { + visibility: visible !important; + width: 18px !important; +} +.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode, +.dj_ie6 .claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode { + background-image:none; +} +.claro .dojoxGridExpandoNodeInner { + visibility: hidden; +} +.dijit_a11y .dojoxGridExpandoNodeInner { + visibility: visible; +} + +.claro .dojoxGridSummaryRow .dojoxGridCell { + border:1px solid transparent; +} +.dj_ie6 .claro .dojoxGridSummaryRow .dojoxGridCell { + border-color:#fff +} +.claro tr.dojoxGridSubRowAlt { + background-color:#f4f9fd; +} +.claro .dojoxGridRowOdd tr.dojoxGridSubRowAlt { + background-color:#fff; +} +.claro .dojoxGridRow .dojoxGridRowTable tr.dojoxGridRowSelected { + background-color:#cee6fa; +} diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gif b/js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gif Binary files differnew file mode 100644 index 0000000..57f67ba --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gif diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gif b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gif Binary files differnew file mode 100644 index 0000000..7a73f82 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gif diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gif b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gif Binary files differnew file mode 100644 index 0000000..9452da0 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gif diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/header.png b/js/dojo-1.7.2/dojox/grid/resources/images/header.png Binary files differnew file mode 100644 index 0000000..aa3e5ba --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/header.png diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.png b/js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.png Binary files differnew file mode 100644 index 0000000..59b2c83 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.png diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/row_back.png b/js/dojo-1.7.2/dojox/grid/resources/images/row_back.png Binary files differnew file mode 100644 index 0000000..643db07 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/row_back.png diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.png b/js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.png Binary files differnew file mode 100644 index 0000000..e326abd --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.png diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.png b/js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.png Binary files differnew file mode 100644 index 0000000..1a30e10 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.png diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.png b/js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.png Binary files differnew file mode 100644 index 0000000..ab27e3e --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.png diff --git a/js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css b/js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css new file mode 100644 index 0000000..4fc1bcc --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css @@ -0,0 +1,237 @@ +@import url("Grid.css"); + +.nihilo .dojoxGrid { + background-color: #e9e9e9; + font-size: 0.85em; /* inherit font-family from dojo.css */ +} + +/* master messages */ + +.nihilo .dojoxGridMasterMessages { + background-color: #fefefe; +} + +/* header */ + +.nihilo .dojoxGridHeader { + background-color: #e9e9e9; +} + +.nihilo .dojoxGridHeader .dojoxGridCell { + border-width: 1px; + padding-bottom: 0px; + border-color: transparent #ACA899 #919191 transparent; + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top; + color: #000 !important; +} + +.nihilo .dojoxGridHeader .dojoxGridCellOver { + background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top; +} + +.nihilo .dojoxGridHeader .dojoxGridCellFocus { + border-color: #ACA899 #919191; + border-style: dashed; +} + +.nihilo .dojoxGridArrowButtonChar { + float: right; + display: none; +} +.nihilo .dojoxGridArrowButtonNode { + display: block !important; + padding-left: 0px; + float: right; + background:url("../../../dijit/themes/nihilo/images/spriteArrows.png") left center no-repeat; + width: 11px; + height: 1em; + margin-top: 1px; +} +.dj_ie6 .nihilo .dojoxGridArrowButtonNode { + background-image:url("../../../dijit/themes/nihilo/images/spriteArrows.gif"); + margin-left: 0px; +} + +.nihilo .dojoxGridSortUp .dojoxGridArrowButtonNode { + background-position: -21px; +} +.dijit_a11y .nihilo .dojoxGridArrowButtonNode { + display: none !important; +} + +/* content */ + +.nihilo .dojoxGridScrollbox { + background-color: #fefefe; +} + +/* rowbar */ + +.nihilo .dojoxGridRowbar { + border: none; + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-y right; + border-right: 1px solid #ccc; + padding: 0px; +} + +.nihilo .dojoxGridRowbarInner { + border: none; + border-bottom: 1px solid #ccc; +} + +.nihilo .dojoxGridRowbarOver { + background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-y right; +} + +.nihilo .dojoxGridRowbarSelected { + background: url(../../../dijit/themes/nihilo/images/titleBar.png) #D9E8F9 no-repeat center; + border-right: 1px solid #ccc; +} + +/* rows */ + +.nihilo .dojoxGridRow { + border: none; + background-color: white; +} + +.nihilo .dojoxGridRowOver { + border-top-color: #ccc; + border-bottom-color: #ccc; +} + +.nihilo .dojoxGridRowOver .dojoxGridCell { + background-color: #ffe284; +} + +.nihilo .dojoxGridRowOdd { + background-color: #f2f5f9; +} + +.nihilo .dojoxGridRowSelected { + background-color: #aec7e3; +} + +.dijit_a11y .nihilo .dojoxGridRowSelected { + background-color: #aec7e3; + border-style: solid; +} + +/* cells */ + +.nihilo .dojoxGridCell { + border: 1px dotted #D5CDB5; + border-left-color: transparent; + border-top-color: transparent; +} + +.dj_ff2 .nihilo .dojoxGridCell { + border-left-width: 0px; + border-top-width: 0px; +} + +.dj_ie6 .nihilo .dojoxGridCell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} + +.nihilo .dojoxGridCellFocus { + border: 1px dashed darkblue; +} + +.nihilo .dojoxGridCellOver { + border: 1px dotted #a6a6a6; +} + +.nihilo .dojoxGridCellFocus.dojoxGridCellOver { + border: 1px dashed darkblue; +} + +/* editing */ + +/* FIXME: these colors are off! */ +.nihilo .dojoxGridRowEditing td { + /* background-color: #F4FFF4; */ + background-color: #ffe284; + /* padding: 0px 3px 0px 3px; */ +} + +.nihilo .dojoxGridRow-inserting td { + background-color: #F4FFF4; +} +.nihilo .dojoxGridRow-inflight td { + background-color: #F2F7B7; +} +.nihilo .dojoxGridRow-error td { + background-color: #F8B8B6; +} + +/* Drag and Drop */ + +.nihilo .dojoxGrid .dojoDndItemBefore { + border-left-color: #ffe284; +} +.nihilo .dojoxGrid .dojoDndItemAfter { + border-right-color: #ffe284; +} + + +/* Tree Grid */ +.nihilo .dojoxGridExpando { + float: left; + height: 18px; + width: 18px; + text-align: center; + margin-top: -3px; +} +.dijitRtl .nihilo .dojoxGridExpando { + float: right; +} +.nihilo .dojoxGridExpandoCell { + padding-top: 5px; +} +.nihilo .dojoxGridExpandoNode { + height: 18px; + background-image: url('../../../dijit/themes/nihilo/images/spriteTree.gif'); +} +.nihilo .dojoxGridExpandoOpened .dojoxGridExpandoNode { + background: url('../../../dijit/themes/nihilo/images/spriteTree.gif') no-repeat -18px top; +} +.nihilo .dojoxGridExpandoLoading .dojoxGridExpandoNode { + background: url('../../../dijit/themes/nihilo/images/treeExpand_loading.gif'); +} +.nihilo .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando { + visibility: visible !important; + width: 18px !important; +} +.nihilo .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode { + background: url('../../../dijit/themes/nihilo/images/spriteTree.gif') no-repeat -36px top; +} +.nihilo .dojoxGridExpandoNodeInner { + visibility: hidden; +} +.dijit_a11y .dojoxGridExpandoNodeInner { + visibility: visible; +} + +.nihilo .dojoxGridSummaryRow .dojoxGridCell { + border-top-color: #999; + border-top-style: solid; +} +.nihilo .dojoxGridSpacerCell, +.nihilo .dojoxGridExpandoCell, +.nihilo .dojoxGridSummaryRow .dojoxGridSpacerCell { + border-color: transparent; + border-right-color: #D5CDB5; +} +.nihilo .dojoxGridSummaryRow .dojoxGridTotalCell, +.nihilo .dojoxGridRowCollapsed .dojoxGridExpandoCell, +.nihilo .dojoxGridTreeModel .dojoxGridExpandoCell { + border-bottom-color: #D5CDB5; +} +.nihilo .dojoxGridSubRowAlt { + background-color: #F8F8F8; +} +.nihilo .dojoxGridRowOdd .dojoxGridSubRowAlt { + background-color: #EDEFF3; +} diff --git a/js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css b/js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css new file mode 100644 index 0000000..330ddf3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css @@ -0,0 +1,245 @@ +@import url("Grid.css"); + +.soria .dojoxGrid { + background-color: #e9e9e9; + font-size: 0.85em; /* inherit font-family from dojo.css */ +} + +/* master messages */ + +.soria .dojoxGridMasterMessages { + background-color: #fefefe; +} + +/* header */ + +.soria .dojoxGridHeader { + background-color: #e9e9e9; +} + +.soria .dojoxGridHeader .dojoxGridCell { + border-width: 1px; + padding-bottom: 0px; + border-color: transparent #ACA899 #919191 transparent; + background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top; + color: #000 !important; +} + +.soria .dojoxGridHeader .dojoxGridCellOver { + background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top; +} + +.soria .dojoxGridHeader .dojoxGridCellFocus { + border-color: #ACA899 #919191; + border-style: dashed; +} + +.soria .dojoxGridArrowButtonChar { + float: right; + display: none; +} +.soria .dojoxGridArrowButtonNode { + display: block !important; + padding-left: 0px; + float: right; + background:url("../../../dijit/themes/soria/images/spriteArrows.png") no-repeat left center; + margin-top: 2px; + width: 11px; + height: 1em; +} +.dj_ie6 .soria .dojoxGridArrowButtonNode { + background-image:url("../../../dijit/themes/soria/images/spriteArrows.gif"); + margin-left: 0px; +} + +.soria .dojoxGridSortUp .dojoxGridArrowButtonNode { + background-position: -21px; +} +.dijit_a11y .soria .dojoxGridArrowButtonNode { + display: none !important; +} + +/* content */ + +.soria .dojoxGridScrollbox { + background-color: #fefefe; +} + +/* rowbar */ + +.soria .dojoxGridRowbar { + border: none; + background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-y right; + border-right: 1px solid #ccc; + padding: 0px; +} + +.soria .dojoxGridRowbarInner { + border: none; + border-bottom: 1px solid #ccc; +} + +.soria .dojoxGridRowbarOver { + background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-y right; +} + +.soria .dojoxGridRowbarSelected { + background: url(../../../dijit/themes/soria/images/titleBar.png) #D9E8F9 no-repeat center; + border-right: 1px solid #ccc; +} + +/* rows */ + +.soria .dojoxGridRow { + border: none; + background-color: white; +} + +.soria .dojoxGridRowOver { + border-top-color: #ccc; + border-bottom-color: #ccc; +} + +.soria .dojoxGridRowOver .dojoxGridCell { + background-color: #60a1ea; + color:#fff; +} + +.soria .dojoxGridRowOver .dojoxGridCell .dijit { + color: #000; +} + +.soria .dojoxGridRowOver .dojoxGridCell .dijitDisabled { + color: gray; +} + +.soria .dojoxGridRowOdd { + background-color: #f2f5f9; +} + +.soria .dojoxGridRowSelected { + background-color: #aec7e3; +} + +.dijit_a11y .soria .dojoxGridRowSelected { + background-color: #aec7e3; + border-style: solid; +} + +/* cells */ + +.soria .dojoxGridCell { + border: 1px dotted #D5CDB5; + border-left-color: transparent; + border-top-color: transparent; +} + +.dj_ff2 .soria .dojoxGridCell { + border-left-width: 0px; + border-top-width: 0px; +} + +.dj_ie6 .soria .dojoxGridCell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} + +.soria .dojoxGridCellFocus { + border: 1px dashed darkblue; +} + +.soria .dojoxGridCellOver { + border: 1px dotted #a6a6a6; +} + +.soria .dojoxGridCellFocus.dojoxGridCellOver { + border: 1px dashed darkblue; +} + +/* editing */ + +/* FIXME: these colors are off! */ +.soria .dojoxGridRowEditing td { + /* background-color: #F4FFF4; */ + background-color: #60a1ea; + /* padding: 0px 3px 0px 3px; */ +} + +.soria .dojoxGridRow-inserting td { + background-color: #F4FFF4; +} +.soria .dojoxGridRow-inflight td { + background-color: #F2F7B7; +} +.soria .dojoxGridRow-error td { + background-color: #F8B8B6; +} + +/* Drag and Drop */ + +.soria .dojoxGrid .dojoDndItemBefore { + border-left-color: #4B5AAA; +} +.soria .dojoxGrid .dojoDndItemAfter { + border-right-color: #4B5AAA; +} + +/* Tree Grid */ +.soria .dojoxGridExpando { + float: left; + height: 18px; + width: 18px; + text-align: center; + margin-top: -3px; +} +.dijitRtl .soria .dojoxGridExpando { + float: right; +} +.soria .dojoxGridExpandoCell { + padding-top: 5px; +} +.soria .dojoxGridExpandoNode { + height: 18px; + background-image: url('../../../dijit/themes/soria/images/spriteTree.gif'); +} +.soria .dojoxGridExpandoOpened .dojoxGridExpandoNode { + background: url('../../../dijit/themes/soria/images/spriteTree.gif') no-repeat -18px top; +} +.soria .dojoxGridExpandoLoading .dojoxGridExpandoNode { + background: url('../../../dijit/themes/soria/images/treeExpand_loading.gif'); +} +.soria .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando { + visibility: visible !important; + width: 18px !important; +} +.soria .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode { + background: url('../../../dijit/themes/soria/images/spriteTree.gif') no-repeat -36px top; +} +.soria .dojoxGridExpandoNodeInner { + visibility: hidden; +} +.dijit_a11y .dojoxGridExpandoNodeInner { + visibility: visible; +} + +.soria .dojoxGridSummaryRow .dojoxGridCell { + border-top-color: #999; + border-top-style: solid; +} +.soria .dojoxGridSpacerCell, +.soria .dojoxGridExpandoCell, +.soria .dojoxGridSummaryRow .dojoxGridSpacerCell { + border-color: transparent; + border-right-color: #D5CDB5; +} +.soria .dojoxGridSummaryRow .dojoxGridTotalCell, +.soria .dojoxGridRowCollapsed .dojoxGridExpandoCell, +.soria .dojoxGridTreeModel .dojoxGridExpandoCell { + border-bottom-color: #D5CDB5; +} +.soria .dojoxGridSubRowAlt { + background-color: #F8F8F8; +} +.soria .dojoxGridRowOdd .dojoxGridSubRowAlt { + background-color: #EDEFF3; +} diff --git a/js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css b/js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css new file mode 100644 index 0000000..18ba271 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css @@ -0,0 +1,268 @@ +@import url("Grid.css"); + +.tundra .dojoxGrid { + background-color: #e9e9e9; + font-size: 0.85em; /* inherit font-family from dojo.css */ +} + +/* master messages */ + +.tundra .dojoxGridMasterMessages { + background-color: #fefefe; +} + +.tundra .dojoxGridLoading, +.tundra .dojoxGridError { + background-position:left center; + background-repeat: no-repeat; + padding-left:25px; +} + +.dijitRtl .tundra .dojoxGridLoading, +.dijitRtl .tundra .dojoxGridError, +.dijitRtl .tundra .dojoxGridNoData { + background-position:right; + padding-right:25px; + padding-left:0px; +} + +.tundra .dojoxGridLoading { + background-image: url('../../../dijit/themes/tundra/images/loading.gif'); +} + +.tundra .dojoxGridError { + background-image: url('../../../dijit/themes/tundra/images/warning.png'); +} + +/* header */ + +.tundra .dojoxGridHeader { + background-color: #e9e9e9; +} + +.tundra .dojoxGridHeader .dojoxGridCell { + border-width: 1px; + padding-bottom: 0px; + border-color: transparent #ACA899 #919191 transparent; + background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top; + color: #000 !important; +} + +.tundra .dojoxGridHeader .dojoxGridCellOver { + background: url(../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top; + color: #000 !important; +} +.tundra .dojoxGridHeader .dojoxGridCellFocus { + border-color: #ACA899 #919191; + border-style: dashed; +} +.tundra .dojoxGridArrowButtonChar { + float: right; + display: none; +} +.tundra .dojoxGridArrowButtonNode { + display: block !important; + padding-left: 0px; + float: right; + background:url("../../../dijit/themes/tundra/images/spriteArrows.png") no-repeat left center; + width: 7px; + height: 1em; + margin: 2px 4px 0px 5px; +} +.dj_ie6 .tundra .dojoxGridArrowButtonNode { + background-image:url("../../../dijit/themes/tundra/images/spriteArrows.gif"); + margin-left: 0px; +} + +.tundra .dojoxGridSortUp .dojoxGridArrowButtonNode { + background-position: -21px; +} +.dijit_a11y .tundra .dojoxGridArrowButtonNode { + display: none !important; +} + +/* content */ + +.tundra .dojoxGridScrollbox { + background-color: #fefefe; +} + +/* rowbar */ + +.tundra .dojoxGridRowbar { + border: none; + background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right; + border-right: 1px solid #ccc; + padding: 0px; +} + +.tundra .dojoxGridRowbarInner { + border: none; + border-bottom: 1px solid #ccc; +} + +.tundra .dojoxGridRowbarOver { + background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right; +} + +.tundra .dojoxGridRowbarSelected { + background: url(../../../dijit/themes/tundra/images/tabDisabled.png) #D8E8F9 no-repeat center; + border-right: 1px solid #ccc; +} + +/* rows */ + +.tundra .dojoxGridRow { + border: none; + background-color: white; +} + +.tundra .dojoxGridRowOver { + border-top-color: #ccc; + border-bottom-color: #ccc; +} + +.tundra .dojoxGridRowOver .dojoxGridCell { + background-color: #60a1ea; + color:#fff; +} + +.tundra .dojoxGridRowOver .dojoxGridCell .dijit { + color: #000; +} + +.tundra .dojoxGridRowOver .dojoxGridCell .dijitDisabled { + color: gray; +} + +.tundra .dojoxGridRowOdd { + background-color: #f2f5f9; +} + +.tundra .dojoxGridRowSelected { + background-color: #aec7e3 !important; +} + +.dijit_a11y .tundra .dojoxGridRowSelected { + background-color: #aec7e3; + border-style: solid; +} + +/* cells */ + +.tundra .dojoxGridCell { + border: 1px dotted #D5CDB5; + border-left-color: transparent; + border-top-color: transparent; +} + +.dj_ff2 .tundra .dojoxGridCell { + border-left-width: 0px; + border-top-width: 0px; +} + +.dj_ie6 .tundra .dojoxGridCell { + border: 1px solid white; + border-right: 1px solid #D5CDB5; +} + +.tundra .dojoxGridCellFocus { + border: 1px dashed darkblue !important; +} + +.tundra .dojoxGridCellOver { + border: 1px dotted #a6a6a6; +} + +.tundra .dojoxGridCellFocus .dojoxGridCellOver { + border: 1px dashed darkblue !important; +} + +/* editing */ + +/* FIXME: these colors are off! */ +.tundra .dojoxGridRowEditing td { + /* background-color: #F4FFF4; */ + background-color: #60a1ea; + /* padding: 0px 3px 0px 3px; */ +} + +.tundra .dojoxGridRow-inserting td { + background-color: #F4FFF4; +} +.tundra .dojoxGridRow-inflight td { + background-color: #F2F7B7; +} +.tundra .dojoxGridRow-error td { + background-color: #F8B8B6; +} + +/* Drag and Drop */ + +.tundra .dojoxGrid .dojoDndItemBefore { + border-left-color: #3559ac; +} +.tundra .dojoxGrid .dojoDndItemAfter { + border-right-color: #3559ac; +} + +/* Tree Grid */ +.tundra .dojoxGridExpando { + float: left; + height: 18px; + width: 18px; + text-align: center; + margin-top: -3px; +} +.dijitRtl .tundra .dojoxGridExpando { + float: right; +} +.tundra .dojoxGridExpandoCell { + padding-top: 5px; +} +.tundra .dojoxGridExpandoNode { + height: 18px; + background-image: url('../../../dijit/themes/tundra/images/treeExpand_plus.gif'); +} +.tundra .dojoxGridExpandoOpened .dojoxGridExpandoNode { + background-image: url('../../../dijit/themes/tundra/images/treeExpand_minus.gif'); +} +.tundra .dojoxGridExpandoLoading .dojoxGridExpandoNode { + background-image: url('../../../dijit/themes/tundra/images/treeExpand_loading.gif'); +} +.tundra .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando { + visibility: visible !important; + width: 18px !important; +} +.tundra .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode { + background-image: url('../../../dijit/themes/tundra/images/treeExpand_leaf.gif'); + background-position: -3px; +} +.tundra .dojoxGridExpandoNodeInner { + visibility: hidden; +} +.dijit_a11y .dojoxGridExpandoNodeInner { + visibility: visible; +} + +.tundra .dojoxGridSummaryRow .dojoxGridCell { + border-top-color: #999; + border-top-style: solid; +} +.tundra .dojoxGridSpacerCell, +.tundra .dojoxGridExpandoCell, +.tundra .dojoxGridSummaryRow .dojoxGridSpacerCell { + border-color: transparent; + border-right-color: #D5CDB5; +} +.tundra .dojoxGridSummaryRow .dojoxGridTotalCell, +.tundra .dojoxGridRowCollapsed .dojoxGridExpandoCell, +.tundra .dojoxGridTreeModel .dojoxGridExpandoCell { + border-bottom-color: #D5CDB5; +} +.tundra .dojoxGridSubRowAlt { + background-color: #F8F8F8; +} +.tundra .dojoxGridRowOdd .dojoxGridSubRowAlt { + background-color: #EDEFF3; +} diff --git a/js/dojo-1.7.2/dojox/grid/util.js b/js/dojo-1.7.2/dojox/grid/util.js new file mode 100644 index 0000000..b186c85 --- /dev/null +++ b/js/dojo-1.7.2/dojox/grid/util.js @@ -0,0 +1,75 @@ +//>>built +define("dojox/grid/util", [ + "../main", + "dojo/_base/lang", + "dojo/dom" +], function(dojox, lang, dom){ + +// summary: grid utility library + var dgu = lang.getObject("grid.util", true, dojox); + + dgu.na = '...'; + dgu.rowIndexTag = "gridRowIndex"; + dgu.gridViewTag = "gridView"; + + + dgu.fire = function(ob, ev, args){ + var fn = ob && ev && ob[ev]; + return fn && (args ? fn.apply(ob, args) : ob[ev]()); + }; + + dgu.setStyleHeightPx = function(inElement, inHeight){ + if(inHeight >= 0){ + var s = inElement.style; + var v = inHeight + 'px'; + if(inElement && s['height'] != v){ + s['height'] = v; + } + } + }; + + dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ]; + + dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ]; + + dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){ + var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents)); + for (var i=0, l=evts.length; i<l; i++){ + inObject.connect(inNode, 'on' + evts[i], inMethod); + } + }; + + dgu.removeNode = function(inNode){ + inNode = dom.byId(inNode); + inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode); + return inNode; + }; + + dgu.arrayCompare = function(inA, inB){ + for(var i=0,l=inA.length; i<l; i++){ + if(inA[i] != inB[i]){return false;} + } + return (inA.length == inB.length); + }; + + dgu.arrayInsert = function(inArray, inIndex, inValue){ + if(inArray.length <= inIndex){ + inArray[inIndex] = inValue; + }else{ + inArray.splice(inIndex, 0, inValue); + } + }; + + dgu.arrayRemove = function(inArray, inIndex){ + inArray.splice(inIndex, 1); + }; + + dgu.arraySwap = function(inArray, inI, inJ){ + var cache = inArray[inI]; + inArray[inI] = inArray[inJ]; + inArray[inJ] = cache; + }; + + return dojox.grid.util; + +});
\ No newline at end of file |
