123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- define("dojox/layout/ToggleSplitter", ["dojo", "dijit", "dijit/layout/BorderContainer"], function(dojo, dijit) {
- dojo.experimental("dojox.layout.ToggleSplitter");
- dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
- // summary:
- // A draggable and clickable spacer between two items in a dijit.layout.BorderContainer`.
- // description:
- // This is instantiated by `dijit.layout.BorderContainer. Users should not
- // create it directly.
- // tags:
- // private
- /*=====
- // container: [const] dijit.layout.BorderContainer
- // Pointer to the parent BorderContainer
- container: null,
- // child: [const] dijit.layout._LayoutWidget
- // Pointer to the pane associated with this splitter
- child: null,
- // region: [const] String
- // Region of pane associated with this splitter.
- // "top", "bottom", "left", "right".
- region: null,
- =====*/
- // state: String
- // the initial and current state of the splitter (and its attached pane)
- // It has three values: full, collapsed (optional), closed
- state: "full",
- // _closedSize: String
- // the css height/width value to apply by default when the attached pane is closed
- _closedSize: "0",
- baseClass: "dojoxToggleSplitter",
- templateString: '<div class="dijitSplitter dojoxToggleSplitter" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_startDrag,onmouseenter:_onMouse,onmouseleave:_onMouse">' +
- '<div dojoAttachPoint="toggleNode" class="dijitSplitterThumb dojoxToggleSplitterIcon" tabIndex="0" role="separator" ' +
- 'dojoAttachEvent="onmousedown:_onToggleNodeMouseDown,onclick:_toggle,onmouseenter:_onToggleNodeMouseMove,onmouseleave:_onToggleNodeMouseMove,onfocus:_onToggleNodeMouseMove,onblur:_onToggleNodeMouseMove">' +
- '<span class="dojoxToggleSplitterA11y" dojoAttachPoint="a11yText"></span></div>' +
- '</div>',
- postCreate: function(){
- this.inherited(arguments);
- // add a region css hook so that it can figure out the region correctly
- var region = this.region;
- dojo.addClass(this.domNode, this.baseClass + region.charAt(0).toUpperCase() + region.substring(1));
- },
- startup: function(){
- this.inherited(arguments);
- // we have to wait until startup to be sure the child exists in the dom
- // and has non-zero size (if its supposed to be showing)
- var parentPane = this.child,
- paneNode = this.child.domNode,
- intPaneSize = dojo.style(paneNode, (this.horizontal ? "height" : "width"));
- this.domNode.setAttribute("aria-controls", paneNode.id);
- // creation of splitters is an opaque process in BorderContainer,
- // so if we want to get init params, we have to retrieve them from the attached BC child
- // NOTE: for this to work we have to extend the prototype of dijit._Widget (some more)
- dojo.forEach(["toggleSplitterState", "toggleSplitterFullSize", "toggleSplitterCollapsedSize"], function(name){
- var pname = name.substring("toggleSplitter".length);
- pname = pname.charAt(0).toLowerCase() + pname.substring(1);
- if(name in this.child){
- this[pname] = this.child[name];
- }
- }, this);
- if(!this.fullSize){
- // Store the current size as the fullSize if none was provided
- // dojo.style always returns a integer (pixel) value for height/width
- // use an arbitrary default if a pane was initialized closed and no fullSize provided
- // If collapsedSize is not specified, collapsed state does not exist.
- this.fullSize = this.state == "full" ? intPaneSize + "px" : "75px";
- }
- this._openStyleProps = this._getStyleProps(paneNode, "full");
- // update state
- this._started = true;
- this.set("state", this.state);
- return this;
- },
- _onKeyPress: function(evt){
- if(this.state == "full"){
- this.inherited(arguments);
- }
- if(evt.charCode == dojo.keys.SPACE || evt.keyCode == dojo.keys.ENTER){
- this._toggle(evt);
- }
- },
- _onToggleNodeMouseDown: function(evt){
- dojo.stopEvent(evt);
- this.toggleNode.focus();
- },
- _startDrag: function(e){
- if(this.state == "full"){
- this.inherited(arguments);
- }
- },
- _stopDrag: function(e){
- this.inherited(arguments);
- this.toggleNode.blur();
- },
- _toggle: function(evt){
- var state;
- switch(this.state){
- case "full":
- state = this.collapsedSize ? "collapsed" : "closed";
- break;
- case "collapsed":
- state = "closed";
- break;
- default:
- state = "full";
- }
- this.set("state", state);
- },
- _onToggleNodeMouseMove: function(evt){
- var baseClass = this.baseClass,
- toggleNode = this.toggleNode,
- on = this.state == "full" || this.state == "collapsed",
- leave = evt.type == "mouseout" || evt.type == "blur";
- dojo.toggleClass(toggleNode, baseClass + "IconOpen", leave && on);
- dojo.toggleClass(toggleNode, baseClass + "IconOpenHover", !leave && on);
- dojo.toggleClass(toggleNode, baseClass + "IconClosed", leave && !on);
- dojo.toggleClass(toggleNode, baseClass + "IconClosedHover", !leave && !on);
- },
- _handleOnChange: function(preState){
- // summary
- // Effect the state change with the new value of this.state
- var paneNode = this.child.domNode,
- openProps, paneStyle,
- dim = this.horizontal ? "height" : "width";
- if(this.state == "full"){
- // change to full open state
- var styleProps = dojo.mixin({
- display: "block",
- overflow: "auto",
- visibility: "visible"
- }, this._openStyleProps);
- styleProps[dim] = (this._openStyleProps && this._openStyleProps[dim]) ? this._openStyleProps[dim] : this.fullSize;
- dojo.style(this.domNode, "cursor", "");
- dojo.style(paneNode, styleProps);
- }else if(this.state == "collapsed"){
- paneStyle = dojo.getComputedStyle(paneNode);
- openProps = this._getStyleProps(paneNode, "full", paneStyle);
- this._openStyleProps = openProps;
- dojo.style(this.domNode, "cursor", "auto");
- dojo.style(paneNode, dim, this.collapsedSize);
- }else{
- // change to closed state
- if(!this.collapsedSize){
- paneStyle = dojo.getComputedStyle(paneNode);
- openProps = this._getStyleProps(paneNode, "full", paneStyle);
- this._openStyleProps = openProps;
- }
- var closedProps = this._getStyleProps(paneNode, "closed", paneStyle);
- dojo.style(this.domNode, "cursor", "auto");
- dojo.style(paneNode, closedProps);
- }
- this._setStateClass();
- if(this.container._started){
- this.container._layoutChildren(this.region);
- }
- },
- _getStyleProps: function(paneNode, state, paneStyle){
- // summary:
- // Create an object with the style property name: values
- // that will need to be applied to the child pane render the given state
- if(!paneStyle){
- paneStyle = dojo.getComputedStyle(paneNode);
- }
- var styleProps = {},
- dim = this.horizontal ? "height" : "width";
- styleProps["overflow"] = (state != "closed") ? paneStyle["overflow"] : "hidden";
- styleProps["visibility"] = (state != "closed") ? paneStyle["visibility"] : "hidden";
- // Use the inline width/height style value, in preference to the computedStyle
- // for the open width/height
- styleProps[dim] = (state != "closed") ? paneNode.style[dim] || paneStyle[dim] : this._closedSize;
- // We include the padding, border, margin width values for restoring on state full open
- var edgeNames = ["Top", "Right", "Bottom", "Left"];
- dojo.forEach(["padding", "margin", "border"], function(pname){
- for(var i = 0; i < edgeNames.length; i++){
- var fullName = pname + edgeNames[i];
- if(pname == "border"){
- fullName += "Width";
- }
- if(undefined !== paneStyle[fullName]){
- styleProps[fullName] = (state != "closed") ? paneStyle[fullName] : 0;
- }
- }
- });
- return styleProps;
- },
- _setStateClass: function(){
- // Summary:
- // Apply the appropriate classes for the current open state
- var arrow = "▴", region = this.region.toLowerCase(),
- baseClass = this.baseClass,
- toggleNode = this.toggleNode,
- on = this.state == "full" || this.state == "collapsed",
- focused = this.focused;
- dojo.toggleClass(toggleNode, baseClass + "IconOpen", on && !focused);
- dojo.toggleClass(toggleNode, baseClass + "IconClosed", !on && !focused);
- dojo.toggleClass(toggleNode, baseClass + "IconOpenHover", on && focused);
- dojo.toggleClass(toggleNode, baseClass + "IconClosedHover", !on && focused);
- // For a11y
- if(region == "top" && on || region == "bottom" && !on){
- arrow = "▲";
- }else if(region == "top" && !on || region == "bottom" && on){
- arrow = "▼";
- }else if(region == "right" && on || region == "left" && !on){
- arrow = "▶";
- }else if(region == "right" && !on || region == "left" && on){
- arrow = "◀";
- }
- this.a11yText.innerHTML = arrow;
- },
- _setStateAttr: function(/*Strring*/ state){
- // summary:
- // setter for the state property
- if(!this._started) {
- return;
- }
- var preState = this.state;
- this.state = state;
- this._handleOnChange(preState);
- var evtName;
- switch(state){
- case "full":
- this.domNode.setAttribute("aria-expanded", true);
- evtName = "onOpen";
- break;
- case "collapsed":
- this.domNode.setAttribute("aria-expanded", true);
- evtName = "onCollapsed";
- break;
- default:
- this.domNode.setAttribute("aria-expanded", false);
- evtName = "onClosed";
- }
- this[evtName](this.child);
- },
- onOpen: function(pane){ /*Stub*/ },
- onCollapsed: function(pane){ /*Stub*/ },
- onClosed: function(pane){ /*Stub*/ }
- });
- // As BC places no constraints on what kind of widgets can be children
- // we have to extend the base class to ensure the properties we need can be set (both in markup and programatically)
- dojo.extend(dijit._Widget, {
- // toggleSplitterOpen: Boolean
- toggleSplitterState: "full",
- // toggleSplitterClosedThreshold: String
- // A css size value (e.g. "100px")
- toggleSplitterFullSize: "",
- toggleSplitterCollapsedSize: ""
- });
- });
|