DIR : /home/kozerus/public_html/pn/uize/site-source/js/Uize/Widgets/Button/Widget.js

/home/kozerus/public_html/pn/uize/site-source/js/Uize/Widgets/Button

/*______________
|       ______  |   U I Z E    J A V A S C R I P T    F R A M E W O R K
|     /      /  |   ---------------------------------------------------
|    /    O /   |    MODULE : Uize.Widgets.Button.Widget Class
|   /    / /    |
|  /    / /  /| |    ONLINE : http://www.uize.com
| /____/ /__/_| | COPYRIGHT : (c)2004-2016 UIZE
|          /___ |   LICENSE : Available under MIT License or GNU General Public License
|_______________|             http://www.uize.com/license.html
*/

/* Module Meta Data
	type: Class
	importance: 8
	codeCompleteness: 100
	docCompleteness: 80
*/

/*?
	Introduction
		The =Uize.Widgets.Button.Widget= class implements the button widget - the most basic and atomic widget that is used in the implementation of many other widgets.

		*DEVELOPERS:* `Chris van Rensburg`

		Visual Sampler
			Below is a visual sampler of the =Uize.Widgets.Button.Widget= class...

			..............................................
			<< widget >>

			widgetClass: Uize.Widgets.Button.VisualSampler
			..............................................
*/

Uize.module ({
	name:'Uize.Widgets.Button.Widget',
	superclass:'Uize.Widget.V2',
	required:[
		'Uize.Widgets.Button.Html',
		'Uize.Widgets.Button.Css'
	],
	builder:function (_superclass) {
		'use strict';

		var
			/*** Variables for Scruncher Optimization ***/
				_class,
				_undefined,
				_true = true,
				_false = false,

			/*** General Variables ***/
				_overButton,

				/*** state precedence mechanism ***/
					_statePrecedenceMaps = {},
					_stateNamesToBitMasks = {
						disabled:16,
						'':8,
						over:4,
						active:2,
						playing:1
					},

				/*** events map ***/
					_eventInfoMap = {
						mouseover:['over','Over'],
						mouseout:['','Out'],
						mousedown:['down','Down'],
						mouseup:['over','Up'],
						click:['over','Click'],
						dblclick:['over','Double Click']
					}
		;

		return _class = _superclass.subclass ({
			instanceMethods:{
				wireUi:function () {
					function _setStateAndFireEvent (_domEvent) {
						if (m.isWired) {
							var
								_domEventType = _domEvent.type,
								_isClickEvent = _domEventType == 'click'
							;

							/*** deferred wiring of other events (for performance) ***/
								if (!m._allEventsWired) {
									m._allEventsWired = _true;
									m.wireNode (
										m._rootNode,
										{
											mouseout:_setStateAndFireEvent,
											mousedown:_setStateAndFireEvent,
											mouseup:_setStateAndFireEvent,
											dblclick:_setStateAndFireEvent
										}
									);
								}

							if (_isClickEvent) _domEvent.cancelBubble = _true;

							if (
								m.get ('enabledInherited') && !m.get ('busyInherited') &&
								(_domEventType == 'dblclick' || !m._selected || m._clickToDeselect || m._allowClickWhenSelected)
							) {
								var _eventInfo = _eventInfoMap [_domEventType];
								m.set ({_state:_eventInfo [0]});
								m.fire ({name:_eventInfo [1],domEvent:_domEvent});
								/*?
									Instance Events
										Click
											An instance event that is fired when the user clicks the instance's =Root Node=.

											This event is fired after the related =Up= instance event. When this event is fired, the value of the =state= state property will be ='over'=. The event object for this event will have a =domEvent= property that is a reference to the browser event object associated to the event on the DOM node. This =domEvent= object can be used to determine what modifier keys were being used, along with other properties of the event.

											NOTES
											- see the companion =Double Click=, =Down=, =Out=, =Over=, and =Up= instance events

										Double Click
											An instance event that is fired when the user double clicks the instance's =Root Node=.

											This event is fired after the related =Up= and =Click= instance events. When this event is fired, the value of the =state= state property will be ='over'=. The event object for this event will have a =domEvent= property that is a reference to the browser event object associated to the event on the DOM node. This =domEvent= object can be used to determine what modifier keys were being used, along with other properties of the event.

											NOTES
											- see the companion =Click=, =Down=, =Out=, =Over=, and =Up= instance events

										Down
											An instance event that is fired when the user mouses down on the instance's =Root Node=.

											When this event is fired, the value of the =state= state property will be ='down'=. The event object for this event will have a =domEvent= property that is a reference to the browser event object associated to the event on the DOM node. This =domEvent= object can be used to determine what modifier keys were being used, along with other properties of the event.

											NOTES
											- see the companion =Click=, =Double Click=, =Out=, =Over=, and =Up= instance events

										Out
											An instance event that is fired when the user mouses out of the instance's =Root Node=.

											When this event is fired, the value of the =state= state property will be =''= (empty string). The event object for this event will have a =domEvent= property that is a reference to the browser event object associated to the event on the DOM node. This =domEvent= object can be used to determine what modifier keys were being used, along with other properties of the event.

											NOTES
											- see the companion =Click=, =Double Click=, =Down=, =Over=, and =Up= instance events

										Over
											An instance event that is fired when the user mouses over the instance's =Root Node=.

											When this event is fired, the value of the =state= state property will be ='over'=. The event object for this event will have a =domEvent= property that is a reference to the browser event object associated to the event on the DOM node. This =domEvent= object can be used to determine what modifier keys were being used, along with other properties of the event.

											NOTES
											- see the companion =Click=, =Double Click=, =Down=, =Out=, and =Up= instance events

										Up
											An instance event that is fired when the user mouses up after first having moused down on the instance's =Root Node=.

											This event is fired before the related =Click= instance event. When this event is fired, the value of the =state= state property will be ='over'=. The event object for this event will have a =domEvent= property that is a reference to the browser event object associated to the event on the DOM node. This =domEvent= object can be used to determine what modifier keys were being used, along with other properties of the event.

											NOTES
											- see the companion =Click=, =Double Click=, =Down=, =Out=, and =Over= instance events
								*/
								if (_isClickEvent) {
									m._action && m._action (_domEvent);
									(m._selected ? m._clickToDeselect : m._clickToSelect) && m.toggle ('selected');
								}
							}
						}
					}
					var m = this;
					if (!m.isWired) {
						var _rootNode = m._rootNode = m.getNode ();
						if (_rootNode) {
							/*** wire up event handlers ***/
								m.wireNode (
									_rootNode,
									{
										mouseover:_setStateAndFireEvent,
										click:_setStateAndFireEvent
									}
								);

							_superclass.doMy (m,'wireUi');
						}
					}
				}
			},

			staticProperties:{
				cssModule:Uize.Widgets.Button.Css,

				addChildButton:function (_buttonName,_clickHandler) {
					var
						m = this,
						_button = m.addChild (_buttonName,_class)
					;
					_button.wire (
						'Click',
						function (_event) {
							if (_clickHandler)
								typeof _clickHandler == 'string' ? m.fire (_clickHandler) : _clickHandler (_event)
							;
							m.fire (_event);
						}
					);
					return _button;
					/*?
						Static Properties
							Uize.Widgets.Button.Widget.addChildButton
								A function, that can be "stitched in" to other widget classes as an instance method in order to ease adding of child button widgets to instances of those classes, and that is most useful in widget class that add a lot of child buttons.

								SYNTAX
								............................................................................
								myButton = myWidgetInstance.addChildButton (buttonNameSTR,clickHandlerFUNC);
								............................................................................

								In order for the above syntax to work, the =Uize.Widgets.Button.Widget.addChildButton= function would first need to be "stitched in" as an instance method of the class of which =myWidgetInstance= is an instance. This can be done with a statement such as...

								STITCHING IN
								............................................................
								// stitching in as a public method
								MyWidgetClass.instanceMethods ({
									addChildButton:Uize.Widgets.Button.Widget.addChildButton
								});

								// stitching in as a private method
								MyWidgetClass.instanceMethods ({
									_addChildButton:Uize.Widgets.Button.Widget.addChildButton
								});
								............................................................

								VARIATION 1
								........................................................................
								myButton = myWidgetInstance.addChildButton (buttonNameSTR,eventNameSTR);
								........................................................................

								When the =eventNameSTR= parameter is specified in place of the =clickHandlerFUNC= parameter, then clicking the added child button will fire an event of the name specified by the =eventNameSTR= parameter on the instance to which the child button was added, rather than executing click handler code.

								VARIATION 2
								...........................................................
								myButton = myWidgetInstance.addChildButton (buttonNameSTR);
								...........................................................

								When only the =buttonNameSTR= parameter is specified, then no custom event will be fired and no click hander function will be executed. Instead, only the button's ='Click'= instance event will be relayed to the widget instance to which the child button was added. Any handler code for this ='Click'= event fired on the button's parent would then have to use the event object's =source= property to determine which button was clicked.

								Calling Without Stitching In

									SYNTAX
									...........................................................
									myButton = Uize.Widgets.Button.Widget.addChildButton.call (
										myWidgetInstance,
										buttonNameSTR,
										clickHandlerFUNCorEventNameSTR
									);
									...........................................................

									VARIATION
									...........................................................................................
									myButton = Uize.Widgets.Button.Widget.addChildButton.call (myWidgetInstance,buttonNameSTR);
									...........................................................................................
					*/
				}
			},

			stateProperties:{
				_action:'action',
					/*?
						State Properties
							action

								NOTES
								- the initial value is =undefined=
					*/
				_allowClickWhenSelected:'allowClickWhenSelected',
					/*?
						State Properties
							allowClickWhenSelected

								NOTES
								- the initial value is =undefined=
					*/
				_clickToSelect:'clickToSelect',
					/*?
						State Properties
							clickToSelect

								NOTES
								- the initial value is =undefined=
					*/
				_clickToDeselect:'clickToDeselect',
					/*?
						State Properties
							clickToDeselect

								NOTES
								- the initial value is =undefined=
					*/
				_displayState:{
					name:'displayState',
					derived:{
						properties:[
							'state',
							'isOver',
							'selected',
							'playing',
							'flavor',
							'enabledInherited',
							'busyInherited',
							'statePrecedence',
							'statePrecedenceMap'
						],
						derivation:function (
							_state,
							_isOver,
							_selected,
							_playing,
							_flavor,
							_enabledInherited,
							_busyInherited,
							_statePrecedence,
							_statePrecedenceMap
						) {
							var
								m = this,
								_stateCombinationNo =
									/* disabled state  */ !_enabledInherited * 16 |
									/* default state */ (!_state || _busyInherited) * 8 |
									/* over state    */ _isOver * 4 |
									/* active state  */ (_state == 'down' || _selected) * 2 |
									/* playing state */ +_playing
								,
								_displayState = _statePrecedenceMap [_stateCombinationNo]
							;
							if (_displayState == _undefined) {
								for (
									var
										_stateNo = -1,
										_statePrecedenceLength = _statePrecedence.length
									;
									++_stateNo < _statePrecedenceLength;
								) {
									var _stateName = _statePrecedence [_stateNo];
									if (_stateCombinationNo & _stateNamesToBitMasks [_stateName]) {
										_displayState = _stateName;
										break;
									}
								}
								_statePrecedenceMap [_stateCombinationNo] = _displayState;
							}
							return _flavor + (_displayState && ('-' + _displayState));
						}
						/*?
							State Properties
								displayState

									NOTES
									- the initial value is =''= (empty string)
						*/
					}
				},
				_playing:{
					name:'playing',
					value:_false
					/*?
						State Properties
							playing

								NOTES
								- the initial value is ='false'=
					*/
				},
				_selected:{
					name:'selected',
					value:_false
					/*?
						State Properties
							selected

								NOTES
								- the initial value is ='false'=
					*/
				},
				_state:{
					name:'state',
					onChange:function () {
						var m = this;
						if (!m._state) {
							if (_overButton == m)
								_overButton = _undefined
							;
						} else if (m._state == 'over') {
							_overButton && _overButton != m && _overButton.set ({_state:''});
							_overButton = m;
						}
					},
					value:''
					/*?
						State Properties
							state
								A string, indicating the mouseover or mousedown state of the instance.

								Possible values for this property are...

								- =''= (empty string) - the default state, when the user is neither mousing over or mousing down on the instance's =Root Node=
								- ='over'= - indicates that the user is mousing over the instance's =Root Node=
								- ='down'= - indicates that the user is mousing down on the instance's =Root Node=

								NOTES
								- the initial value is =''= (an empty string)
								- this state property should not be confused with the related =playing= and =selected= state properties
								- while the instance is not wired, the value of this property will remain =''= (empty string)
					*/
				},
				_isOver:{
					name:'isOver',
					derived:'state: state == "over" || state == "down"'
				},
				_statePrecedence:{
					name:'statePrecedence',
					value:['playing','active','disabled','over','']
					/*?
						State Properties
							statePrecedence

								NOTES
								- the initial value is =['playing','active','disabled','over','']=
					*/
				},
				_statePrecedenceMap:{
					name:'statePrecedenceMap',
					derived:{
						properties:'statePrecedence',
						derivation:function (_statePrecedence) {
							var _statePrecedenceAsJoinedStr =
								_statePrecedence._asJoinedStr ||
								(_statePrecedence._asJoinedStr = _statePrecedence.join (','))
							;
							return (
								_statePrecedenceMaps [_statePrecedenceAsJoinedStr] ||
								(_statePrecedenceMaps [_statePrecedenceAsJoinedStr] = {})
							);
						}
					}
				},
				_text:{
					name:'text',
					value:''
					/*?
						State Properties
							text
								A string, whose value will be used to set the value of the =innerHTML= property of the =text DOM Node=.

								The =innerHTML= value of the =text DOM Node= will be updated to reflect the value of the =text= state property whenever the value of this property is changed, is not =null= or =undefined=, and the instance is wired up.

								NOTES
								- the initial value is =undefined=
					*/
				},
				_displayedTipText:{
					name:'displayedTipText',
					derived:'tipText,enabledInherited,busyInherited: enabledInherited && !busyInherited ? tipText : ""'
				},
				_tipText:{
					name:'tipText',
					value:''
					/*?
						State Properties
							tipText
								.
					*/
				},
				_tooltip:'tooltip',
					/*?
						State Properties
							tooltip
								An object reference to a DOM node, or a string whose value is the =id= for a DOM node, that should be displayed as a tooltip for the instance whenever the user mouses over the =Root Node= and the instance is in a state where clicking on this node would have an action.

								Clicking on the =Root Node= would have an action when the following conditions are met: the =over= state property is set to =true=, the =enabledInherited= state property is set to =true=, the =selected= state property is set to =false=, and the instance is wired.

								NOTES
								- the initial value is =undefined=
								- in order for the value of this property to be honored, the =Uize.Tooltip= module must already be loaded, but the =Uize.Widgets.Button.Widget= module does not explicitly require the =Uize.Tooltip= module
					*/
				_tooltipShown:{
					name:'tooltipShown',
					derived:
						'tooltip,wired,state,enabledInherited,selected: !!(tooltip && wired && state == "over" && enabledInherited && !selected)',
					onChange:function () {
						Uize.Tooltip && Uize.Tooltip.showTooltip (this._tooltip,this._tooltipShown);
					}
				},
				_flavor:{
					name:'flavor',
					value:'normal' // values can be 'normal' | 'primary' | 'positive' | 'negative' | 'subdued'
				}
			},

			set:{
				html:Uize.Widgets.Button.Html
			},

			cssBindings:{
				displayState:'value',
				busyInherited:['','busy']
			},

			htmlBindings:{
				text:'text:html',
					/*?
						DOM Nodes
							text DOM Node
								An optional node whose contents will be replaced with the value of the =text= state property, if this property's value is not =null= or =undefined=.

								The =innerHTML= value of the =text DOM Node= will be updated to reflect the value of the =text= state property whenever the value of this property is changed, is not =null= or =undefined=, and the instance is wired up.

								NOTES
								- this DOM node is optional
					*/
				displayedTipText:':title'
					/*?
						DOM Nodes
							Root Node
								The root node is the DOM node with the name =''= (empty string), and is required for this widget class.

								The =className= property of this node is updated to reflect the state of the instance's =playing=, =selected=, and =state= state properties. In such cases, the value used to set the =className= property is constructed by using the values of the =state=, =selected=, =playing=, =busyInherited=, =enabledInherited=, and =statePrecedenceMap= state properties.

								NOTES
								- this DOM node is required
					*/
			}
		});
	}
});

//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer