]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/slider/clickable-rail.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / slider / clickable-rail.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('clickable-rail', function(Y) {
9
10 /**
11  * Adds support for mouse interaction with the Slider rail triggering thumb
12  * movement.
13  *
14  * @module slider
15  * @submodule clickable-rail
16  */
17
18 /**
19  * Slider extension that allows clicking on the Slider's rail element,
20  * triggering the thumb to align with the location of the click.
21  *
22  * @class ClickableRail
23  */
24 function ClickableRail() {
25     this._initClickableRail();
26 }
27
28 Y.ClickableRail = Y.mix(ClickableRail, {
29
30     // Prototype methods added to host class
31     prototype: {
32
33         /**
34          * Initializes the internal state and sets up events.
35          *
36          * @method _initClickableRail
37          * @protected
38          */
39         _initClickableRail: function () {
40             this._evtGuid = this._evtGuid || (Y.guid() + '|');
41
42             /**
43              * Broadcasts when the rail has received a mousedown event and
44              * triggers the thumb positioning.  Use
45              * <code>e.preventDefault()</code> or
46              * <code>set(&quot;clickableRail&quot;, false)</code> to prevent
47              * the thumb positioning.
48              *
49              * @event railMouseDown
50              * @preventable _defRailMouseDownFn
51              */
52             this.publish('railMouseDown', {
53                 defaultFn: this._defRailMouseDownFn
54             });
55
56             this.after('render', this._bindClickableRail);
57             this.on('destroy', this._unbindClickableRail);
58         },
59
60         /** 
61          * Attaches DOM event subscribers to support rail interaction.
62          *
63          * @method _bindClickableRail
64          * @protected
65          */
66         _bindClickableRail: function () {
67             this._dd.addHandle(this.rail);
68
69             this.rail.on(this._evtGuid + Y.DD.Drag.START_EVENT,
70                 Y.bind(this._onRailMouseDown, this));
71         },
72
73         /**
74          * Detaches DOM event subscribers for cleanup/destruction cycle.
75          *
76          * @method _unbindClickableRail
77          * @protected
78          */
79         _unbindClickableRail: function () {
80             if (this.get('rendered')) {
81                 var contentBox = this.get('contentBox'),
82                     rail = contentBox.one('.' + this.getClassName('rail'));
83
84                 rail.detach(this.evtGuid + '*');
85             }
86         },
87
88         /**
89          * Dispatches the railMouseDown event.
90          *
91          * @method _onRailMouseDown
92          * @param e {DOMEvent} the mousedown event object
93          * @protected
94          */
95         _onRailMouseDown: function (e) {
96             if (this.get('clickableRail') && !this.get('disabled')) {
97                 this.fire('railMouseDown', { ev: e });
98             }
99         },
100
101         /**
102          * Default behavior for the railMouseDown event.  Centers the thumb at
103          * the click location and passes control to the DDM to behave as though
104          * the thumb itself were clicked in preparation for a drag operation.
105          *
106          * @method _defRailMouseDownFn
107          * @param e {Event} the EventFacade for the railMouseDown custom event
108          * @protected
109          */
110         _defRailMouseDownFn: function (e) {
111             e = e.ev;
112
113             // Logic that determines which thumb should be used is abstracted
114             // to someday support multi-thumb sliders
115             var dd     = this._resolveThumb(e),
116                 i      = this._key.xyIndex,
117                 length = parseFloat(this.get('length'), 10),
118                 thumb,
119                 thumbSize,
120                 xy;
121                 
122             if (dd) {
123                 thumb = dd.get('dragNode');
124                 thumbSize = parseFloat(thumb.getStyle(this._key.dim), 10);
125
126                 // Step 1. Allow for aligning to thumb center or edge, etc
127                 xy = this._getThumbDestination(e, thumb);
128
129                 // Step 2. Remove page offsets to give just top/left style val
130                 xy = xy[ i ] - this.rail.getXY()[i];
131
132                 // Step 3. Constrain within the rail in case of attempt to
133                 // center the thumb when clicking on the end of the rail
134                 xy = Math.min(
135                         Math.max(xy, 0),
136                         (length - thumbSize));
137
138                 this._uiMoveThumb(xy);
139
140                 // Set e.target for DD's IE9 patch which calls
141                 // e.target._node.setCapture() to allow imgs to be dragged.
142                 // Without this, setCapture is called from the rail and rail
143                 // clicks on other Sliders may have their thumb movements
144                 // overridden by a different Slider (the thumb on the wrong
145                 // Slider moves).
146                 e.target = this.thumb.one('img') || this.thumb;
147
148                 // Delegate to DD's natural behavior
149                 dd._handleMouseDownEvent(e);
150
151                 // TODO: this won't trigger a slideEnd if the rail is clicked
152                 // check if dd._move(e); dd._dragThreshMet = true; dd.start();
153                 // will do the trick.  Is that even a good idea?
154             }
155         },
156
157         /**
158          * Resolves which thumb to actuate if any.  Override this if you want to
159          * support multiple thumbs.  By default, returns the Drag instance for
160          * the thumb stored by the Slider.
161          *
162          * @method _resolveThumb
163          * @param e {DOMEvent} the mousedown event object
164          * @return {Y.DD.Drag} the Drag instance that should be moved
165          * @protected
166          */
167         _resolveThumb: function (e) {
168             /* Temporary workaround
169             var primaryOnly = this._dd.get('primaryButtonOnly'),
170                 validClick  = !primaryOnly || e.button <= 1;
171
172             return (validClick) ? this._dd : null;
173              */
174             return this._dd;
175         },
176
177         /**
178          * Calculates the top left position the thumb should be moved to to
179          * align the click XY with the center of the specified node.
180          *
181          * @method _getThumbDestination
182          * @param e {DOMEvent} The mousedown event object
183          * @param node {Node} The node to position
184          * @return {Array} the [top, left] pixel position of the destination
185          * @protected
186          */
187         _getThumbDestination: function (e, node) {
188             var offsetWidth  = node.get('offsetWidth'),
189                 offsetHeight = node.get('offsetHeight');
190
191             // center
192             return [
193                 (e.pageX - Math.round((offsetWidth  / 2))),
194                 (e.pageY - Math.round((offsetHeight / 2)))
195             ];
196         }
197
198     },
199
200     // Static properties added onto host class
201     ATTRS: {
202         /**
203          * Enable or disable clickable rail support.
204          *
205          * @attribute clickableRail
206          * @type {Boolean}
207          * @default true
208          */
209         clickableRail: {
210             value: true,
211             validator: Y.Lang.isBoolean
212         }
213     }
214
215 }, true);
216
217
218 }, '3.3.0' ,{requires:['slider-base']});