clickable-rail-debug.js revision 34fdaac0f4e44371745512e507385385dfeb6246
943N/AYUI.add('clickable-rail', function(Y) {
830N/A
830N/A/**
919N/A * Adds support for mouse interaction with the Slider rail triggering thumb
919N/A * movement.
919N/A *
919N/A * @module slider
919N/A * @submodule clickable-rail
830N/A */
919N/A
919N/A/**
919N/A * Slider extension that allows clicking on the Slider's rail element,
830N/A * triggering the thumb to align with the location of the click.
919N/A *
919N/A * @class ClickableRail
919N/A */
919N/Afunction ClickableRail() {
919N/A this._initClickableRail();
919N/A}
919N/A
830N/AY.ClickableRail = Y.mix(ClickableRail, {
830N/A
830N/A // Prototype methods added to host class
830N/A prototype: {
830N/A
830N/A /**
830N/A * Initializes the internal state and sets up events.
830N/A *
830N/A * @method _initClickableRail
830N/A * @protected
830N/A */
830N/A _initClickableRail: function () {
830N/A this._evtGuid = this._evtGuid || (Y.guid() + '|');
830N/A
830N/A /**
830N/A * Broadcasts when the rail has received a mousedown event and
830N/A * triggers the thumb positioning. Use
830N/A * <code>e.preventDefault()</code> or
830N/A * <code>set(&quot;clickableRail&quot;, false)</code> to prevent
830N/A * the thumb positioning.
830N/A *
830N/A * @event railMouseDown
830N/A * @preventable _defRailMouseDownFn
830N/A */
830N/A this.publish('railMouseDown', {
830N/A defaultFn: this._defRailMouseDownFn
830N/A });
830N/A
830N/A this.after('render', this._bindClickableRail);
830N/A this.on('destroy', this._unbindClickableRail);
830N/A },
830N/A
830N/A /**
830N/A * Attaches DOM event subscribers to support rail interaction.
830N/A *
830N/A * @method _bindClickableRail
830N/A * @protected
830N/A */
830N/A _bindClickableRail: function () {
830N/A this._dd.addHandle(this.rail);
830N/A
830N/A this.rail.on(this._evtGuid + Y.DD.Drag.START_EVENT,
830N/A Y.bind(this._onRailMouseDown, this));
830N/A },
830N/A
830N/A /**
830N/A * Detaches DOM event subscribers for cleanup/destruction cycle.
830N/A *
830N/A * @method _unbindClickableRail
830N/A * @protected
830N/A */
830N/A _unbindClickableRail: function () {
830N/A if (this.get('rendered')) {
830N/A var contentBox = this.get('contentBox'),
830N/A rail = contentBox.one('.' + this.getClassName('rail'));
830N/A
830N/A rail.detach(this.evtGuid + '*');
830N/A }
830N/A },
830N/A
830N/A /**
830N/A * Dispatches the railMouseDown event.
830N/A *
830N/A * @method _onRailMouseDown
830N/A * @param e {DOMEvent} the mousedown event object
830N/A * @protected
830N/A */
830N/A _onRailMouseDown: function (e) {
830N/A if (this.get('clickableRail') && !this.get('disabled')) {
830N/A this.fire('railMouseDown', { ev: e });
830N/A this.thumb.focus();
830N/A }
830N/A },
830N/A
830N/A /**
830N/A * Default behavior for the railMouseDown event. Centers the thumb at
830N/A * the click location and passes control to the DDM to behave as though
830N/A * the thumb itself were clicked in preparation for a drag operation.
830N/A *
830N/A * @method _defRailMouseDownFn
830N/A * @param e {Event} the EventFacade for the railMouseDown custom event
830N/A * @protected
830N/A */
830N/A _defRailMouseDownFn: function (e) {
830N/A e = e.ev;
830N/A
830N/A // Logic that determines which thumb should be used is abstracted
830N/A // to someday support multi-thumb sliders
830N/A var dd = this._resolveThumb(e),
830N/A i = this._key.xyIndex,
830N/A length = parseFloat(this.get('length'), 10),
830N/A thumb,
830N/A thumbSize,
830N/A xy;
830N/A
830N/A if (dd) {
830N/A thumb = dd.get('dragNode');
830N/A thumbSize = parseFloat(thumb.getStyle(this._key.dim), 10);
830N/A
830N/A // Step 1. Allow for aligning to thumb center or edge, etc
830N/A xy = this._getThumbDestination(e, thumb);
830N/A
830N/A // Step 2. Remove page offsets to give just top/left style val
830N/A xy = xy[ i ] - this.rail.getXY()[i];
830N/A
830N/A // Step 3. Constrain within the rail in case of attempt to
830N/A // center the thumb when clicking on the end of the rail
830N/A xy = Math.min(
830N/A Math.max(xy, 0),
830N/A (length - thumbSize));
830N/A
830N/A this._uiMoveThumb(xy, { source: 'rail' });
830N/A
830N/A // Set e.target for DD's IE9 patch which calls
830N/A // e.target._node.setCapture() to allow imgs to be dragged.
830N/A // Without this, setCapture is called from the rail and rail
830N/A // clicks on other Sliders may have their thumb movements
830N/A // overridden by a different Slider (the thumb on the wrong
830N/A // Slider moves).
830N/A e.target = this.thumb.one('img') || this.thumb;
830N/A
830N/A // Delegate to DD's natural behavior
830N/A dd._handleMouseDownEvent(e);
830N/A
830N/A // TODO: this won't trigger a slideEnd if the rail is clicked
830N/A // check if dd._move(e); dd._dragThreshMet = true; dd.start();
830N/A // will do the trick. Is that even a good idea?
830N/A }
830N/A },
830N/A
830N/A /**
830N/A * Resolves which thumb to actuate if any. Override this if you want to
830N/A * support multiple thumbs. By default, returns the Drag instance for
830N/A * the thumb stored by the Slider.
830N/A *
830N/A * @method _resolveThumb
830N/A * @param e {DOMEvent} the mousedown event object
830N/A * @return {DD.Drag} the Drag instance that should be moved
830N/A * @protected
830N/A */
830N/A _resolveThumb: function (e) {
830N/A /* Temporary workaround
830N/A var primaryOnly = this._dd.get('primaryButtonOnly'),
830N/A validClick = !primaryOnly || e.button <= 1;
830N/A
830N/A return (validClick) ? this._dd : null;
830N/A */
830N/A return this._dd;
830N/A },
830N/A
830N/A /**
830N/A * Calculates the top left position the thumb should be moved to to
830N/A * align the click XY with the center of the specified node.
830N/A *
830N/A * @method _getThumbDestination
830N/A * @param e {DOMEvent} The mousedown event object
830N/A * @param node {Node} The node to position
830N/A * @return {Array} the [top, left] pixel position of the destination
830N/A * @protected
830N/A */
830N/A _getThumbDestination: function (e, node) {
830N/A var offsetWidth = node.get('offsetWidth'),
830N/A offsetHeight = node.get('offsetHeight');
830N/A
830N/A // center
830N/A return [
830N/A (e.pageX - Math.round((offsetWidth / 2))),
830N/A (e.pageY - Math.round((offsetHeight / 2)))
830N/A ];
830N/A }
830N/A
830N/A },
830N/A
830N/A // Static properties added onto host class
830N/A ATTRS: {
830N/A /**
830N/A * Enable or disable clickable rail support.
830N/A *
830N/A * @attribute clickableRail
830N/A * @type {Boolean}
830N/A * @default true
830N/A */
830N/A clickableRail: {
830N/A value: true,
830N/A validator: Y.Lang.isBoolean
830N/A }
830N/A }
830N/A
830N/A}, true);
830N/A
830N/A
830N/A
830N/A}, '@VERSION@' ,{requires:['slider-base']});
830N/A