MDL-32843 import YUI 3.5.1
[moodle.git] / lib / yui / 3.5.1 / build / clickable-rail / clickable-rail-debug.js
blob748ae6100805827cd8c93c82fdd0b6e381528cd6
1 /*
2 YUI 3.5.1 (build 22)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('clickable-rail', function(Y) {
9 /**
10  * Adds support for mouse interaction with the Slider rail triggering thumb
11  * movement.
12  *
13  * @module slider
14  * @submodule clickable-rail
15  */
17 /**
18  * Slider extension that allows clicking on the Slider's rail element,
19  * triggering the thumb to align with the location of the click.
20  *
21  * @class ClickableRail
22  */
23 function ClickableRail() {
24     this._initClickableRail();
27 Y.ClickableRail = Y.mix(ClickableRail, {
29     // Prototype methods added to host class
30     prototype: {
32         /**
33          * Initializes the internal state and sets up events.
34          *
35          * @method _initClickableRail
36          * @protected
37          */
38         _initClickableRail: function () {
39             this._evtGuid = this._evtGuid || (Y.guid() + '|');
41             /**
42              * Broadcasts when the rail has received a mousedown event and
43              * triggers the thumb positioning.  Use
44              * <code>e.preventDefault()</code> or
45              * <code>set(&quot;clickableRail&quot;, false)</code> to prevent
46              * the thumb positioning.
47              *
48              * @event railMouseDown
49              * @preventable _defRailMouseDownFn
50              */
51             this.publish('railMouseDown', {
52                 defaultFn: this._defRailMouseDownFn
53             });
55             this.after('render', this._bindClickableRail);
56             this.on('destroy', this._unbindClickableRail);
57         },
59         /** 
60          * Attaches DOM event subscribers to support rail interaction.
61          *
62          * @method _bindClickableRail
63          * @protected
64          */
65         _bindClickableRail: function () {
66             this._dd.addHandle(this.rail);
68             this.rail.on(this._evtGuid + Y.DD.Drag.START_EVENT,
69                 Y.bind(this._onRailMouseDown, this));
70         },
72         /**
73          * Detaches DOM event subscribers for cleanup/destruction cycle.
74          *
75          * @method _unbindClickableRail
76          * @protected
77          */
78         _unbindClickableRail: function () {
79             if (this.get('rendered')) {
80                 var contentBox = this.get('contentBox'),
81                     rail = contentBox.one('.' + this.getClassName('rail'));
83                 rail.detach(this.evtGuid + '*');
84             }
85         },
87         /**
88          * Dispatches the railMouseDown event.
89          *
90          * @method _onRailMouseDown
91          * @param e {DOMEvent} the mousedown event object
92          * @protected
93          */
94         _onRailMouseDown: function (e) {
95             if (this.get('clickableRail') && !this.get('disabled')) {
96                 this.fire('railMouseDown', { ev: e });
97                 this.thumb.focus();
98             }
99         },
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;
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);
126                 // Step 1. Allow for aligning to thumb center or edge, etc
127                 xy = this._getThumbDestination(e, thumb);
129                 // Step 2. Remove page offsets to give just top/left style val
130                 xy = xy[ i ] - this.rail.getXY()[i];
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));
138                 this._uiMoveThumb(xy, { source: 'rail' });
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;
148                 // Delegate to DD's natural behavior
149                 dd._handleMouseDownEvent(e);
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         },
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 {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;
172             return (validClick) ? this._dd : null;
173              */
174             return this._dd;
175         },
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');
191             // center
192             return [
193                 (e.pageX - Math.round((offsetWidth  / 2))),
194                 (e.pageY - Math.round((offsetHeight / 2)))
195             ];
196         }
198     },
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     }
215 }, true);
219 }, '3.5.1' ,{requires:['slider-base']});