~ubuntu-branches/ubuntu/utopic/moodle/utopic

« back to all changes in this revision

Viewing changes to lib/yuilib/3.13.0/event-flick/event-flick.js

  • Committer: Package Import Robot
  • Author(s): Thijs Kinkhorst
  • Date: 2014-05-12 16:10:38 UTC
  • mfrom: (36.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20140512161038-puyqf65k4e0s8ytz
Tags: 2.6.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.13.0 (build 508226d)
 
3
Copyright 2013 Yahoo! Inc. All rights reserved.
 
4
Licensed under the BSD License.
 
5
http://yuilibrary.com/license/
 
6
*/
 
7
 
 
8
YUI.add('event-flick', function (Y, NAME) {
 
9
 
 
10
/**
 
11
 * The gestures module provides gesture events such as "flick", which normalize user interactions
 
12
 * across touch and mouse or pointer based input devices. This layer can be used by application developers
 
13
 * to build input device agnostic components which behave the same in response to either touch or mouse based
 
14
 * interaction.
 
15
 *
 
16
 * <p>Documentation for events added by this module can be found in the event document for the <a href="../classes/YUI.html#events">YUI</a> global.</p>
 
17
 *
 
18
 *
 
19
 @example
 
20
 
 
21
     YUI().use('event-flick', function (Y) {
 
22
         Y.one('#myNode').on('flick', function (e) {
 
23
         });
 
24
     });
 
25
 
 
26
 *
 
27
 * @module event-gestures
 
28
 */
 
29
 
 
30
/**
 
31
 * Adds support for a "flick" event, which is fired at the end of a touch or mouse based flick gesture, and provides
 
32
 * velocity of the flick, along with distance and time information.
 
33
 *
 
34
 * <p>Documentation for the flick event can be found on the <a href="../classes/YUI.html#event_flick">YUI</a> global,
 
35
 * along with the other supported events.</p>
 
36
 *
 
37
 * @module event-gestures
 
38
 * @submodule event-flick
 
39
 */
 
40
var GESTURE_MAP = Y.Event._GESTURE_MAP,
 
41
    EVENT = {
 
42
        start: GESTURE_MAP.start,
 
43
        end: GESTURE_MAP.end,
 
44
        move: GESTURE_MAP.move
 
45
    },
 
46
    START = "start",
 
47
    END = "end",
 
48
    MOVE = "move",
 
49
 
 
50
    OWNER_DOCUMENT = "ownerDocument",
 
51
    MIN_VELOCITY = "minVelocity",
 
52
    MIN_DISTANCE = "minDistance",
 
53
    PREVENT_DEFAULT = "preventDefault",
 
54
 
 
55
    _FLICK_START = "_fs",
 
56
    _FLICK_START_HANDLE = "_fsh",
 
57
    _FLICK_END_HANDLE = "_feh",
 
58
    _FLICK_MOVE_HANDLE = "_fmh",
 
59
 
 
60
    NODE_TYPE = "nodeType";
 
61
 
 
62
/**
 
63
 * Sets up a "flick" event, that is fired whenever the user initiates a flick gesture on the node
 
64
 * where the listener is attached. The subscriber can specify a minimum distance or velocity for
 
65
 * which the event is to be fired. The subscriber can also specify if there is a particular axis which
 
66
 * they are interested in - "x" or "y". If no axis is specified, the axis along which there was most distance
 
67
 * covered is used.
 
68
 *
 
69
 * <p>It is recommended that you use Y.bind to set up context and additional arguments for your event handler,
 
70
 * however if you want to pass the context and arguments as additional signature arguments to "on",
 
71
 * you need to provide a null value for the configuration object, e.g: <code>node.on("flick", fn, null, context, arg1, arg2, arg3)</code></p>
 
72
 *
 
73
 * @event flick
 
74
 * @for YUI
 
75
 * @param type {string} "flick"
 
76
 * @param fn {function} The method the event invokes. It receives an event facade with an e.flick object containing the flick related properties: e.flick.time, e.flick.distance, e.flick.velocity and e.flick.axis, e.flick.start.
 
77
 * @param cfg {Object} Optional. An object which specifies any of the following:
 
78
 * <dl>
 
79
 * <dt>minDistance (in pixels, defaults to 10)</dt>
 
80
 * <dd>The minimum distance between start and end points, which would qualify the gesture as a flick.</dd>
 
81
 * <dt>minVelocity (in pixels/ms, defaults to 0)</dt>
 
82
 * <dd>The minimum velocity which would qualify the gesture as a flick.</dd>
 
83
 * <dt>preventDefault (defaults to false)</dt>
 
84
 * <dd>Can be set to true/false to prevent default behavior as soon as the touchstart/touchend or mousedown/mouseup is received so that things like scrolling or text selection can be
 
85
 * prevented. This property can also be set to a function, which returns true or false, based on the event facade passed to it.</dd>
 
86
 * <dt>axis (no default)</dt>
 
87
 * <dd>Can be set to "x" or "y" if you want to constrain the flick velocity and distance to a single axis. If not
 
88
 * defined, the axis along which the maximum distance was covered is used.</dd>
 
89
 * </dl>
 
90
 * @return {EventHandle} the detach handle
 
91
 */
 
92
 
 
93
Y.Event.define('flick', {
 
94
 
 
95
    on: function (node, subscriber, ce) {
 
96
 
 
97
        var startHandle = node.on(EVENT[START],
 
98
            this._onStart,
 
99
            this,
 
100
            node,
 
101
            subscriber,
 
102
            ce);
 
103
 
 
104
        subscriber[_FLICK_START_HANDLE] = startHandle;
 
105
    },
 
106
 
 
107
    detach: function (node, subscriber, ce) {
 
108
 
 
109
        var startHandle = subscriber[_FLICK_START_HANDLE],
 
110
            endHandle = subscriber[_FLICK_END_HANDLE];
 
111
 
 
112
        if (startHandle) {
 
113
            startHandle.detach();
 
114
            subscriber[_FLICK_START_HANDLE] = null;
 
115
        }
 
116
 
 
117
        if (endHandle) {
 
118
            endHandle.detach();
 
119
            subscriber[_FLICK_END_HANDLE] = null;
 
120
        }
 
121
    },
 
122
 
 
123
    processArgs: function(args) {
 
124
        var params = (args.length > 3) ? Y.merge(args.splice(3, 1)[0]) : {};
 
125
 
 
126
        if (!(MIN_VELOCITY in params)) {
 
127
            params[MIN_VELOCITY] = this.MIN_VELOCITY;
 
128
        }
 
129
 
 
130
        if (!(MIN_DISTANCE in params)) {
 
131
            params[MIN_DISTANCE] = this.MIN_DISTANCE;
 
132
        }
 
133
 
 
134
        if (!(PREVENT_DEFAULT in params)) {
 
135
            params[PREVENT_DEFAULT] = this.PREVENT_DEFAULT;
 
136
        }
 
137
 
 
138
        return params;
 
139
    },
 
140
 
 
141
    _onStart: function(e, node, subscriber, ce) {
 
142
 
 
143
        var start = true, // always true for mouse
 
144
            endHandle,
 
145
            moveHandle,
 
146
            doc,
 
147
            preventDefault = subscriber._extra.preventDefault,
 
148
            origE = e;
 
149
 
 
150
        if (e.touches) {
 
151
            start = (e.touches.length === 1);
 
152
            e = e.touches[0];
 
153
        }
 
154
 
 
155
        if (start) {
 
156
 
 
157
            if (preventDefault) {
 
158
                // preventDefault is a boolean or function
 
159
                if (!preventDefault.call || preventDefault(e)) {
 
160
                    origE.preventDefault();
 
161
                }
 
162
            }
 
163
 
 
164
            e.flick = {
 
165
                time : new Date().getTime()
 
166
            };
 
167
 
 
168
            subscriber[_FLICK_START] = e;
 
169
 
 
170
            endHandle = subscriber[_FLICK_END_HANDLE];
 
171
 
 
172
            doc = (node.get(NODE_TYPE) === 9) ? node : node.get(OWNER_DOCUMENT);
 
173
            if (!endHandle) {
 
174
                endHandle = doc.on(EVENT[END], Y.bind(this._onEnd, this), null, node, subscriber, ce);
 
175
                subscriber[_FLICK_END_HANDLE] = endHandle;
 
176
            }
 
177
 
 
178
            subscriber[_FLICK_MOVE_HANDLE] = doc.once(EVENT[MOVE], Y.bind(this._onMove, this), null, node, subscriber, ce);
 
179
        }
 
180
    },
 
181
 
 
182
    _onMove: function(e, node, subscriber, ce) {
 
183
        var start = subscriber[_FLICK_START];
 
184
 
 
185
        // Start timing from first move.
 
186
        if (start && start.flick) {
 
187
            start.flick.time = new Date().getTime();
 
188
        }
 
189
    },
 
190
 
 
191
    _onEnd: function(e, node, subscriber, ce) {
 
192
 
 
193
        var endTime = new Date().getTime(),
 
194
            start = subscriber[_FLICK_START],
 
195
            valid = !!start,
 
196
            endEvent = e,
 
197
            startTime,
 
198
            time,
 
199
            preventDefault,
 
200
            params,
 
201
            xyDistance,
 
202
            distance,
 
203
            velocity,
 
204
            axis,
 
205
            moveHandle = subscriber[_FLICK_MOVE_HANDLE];
 
206
 
 
207
        if (moveHandle) {
 
208
            moveHandle.detach();
 
209
            delete subscriber[_FLICK_MOVE_HANDLE];
 
210
        }
 
211
 
 
212
        if (valid) {
 
213
 
 
214
            if (e.changedTouches) {
 
215
                if (e.changedTouches.length === 1 && e.touches.length === 0) {
 
216
                    endEvent = e.changedTouches[0];
 
217
                } else {
 
218
                    valid = false;
 
219
                }
 
220
            }
 
221
 
 
222
            if (valid) {
 
223
 
 
224
                params = subscriber._extra;
 
225
                preventDefault = params[PREVENT_DEFAULT];
 
226
 
 
227
                if (preventDefault) {
 
228
                    // preventDefault is a boolean or function
 
229
                    if (!preventDefault.call || preventDefault(e)) {
 
230
                        e.preventDefault();
 
231
                    }
 
232
                }
 
233
 
 
234
                startTime = start.flick.time;
 
235
                endTime = new Date().getTime();
 
236
                time = endTime - startTime;
 
237
 
 
238
                xyDistance = [
 
239
                    endEvent.pageX - start.pageX,
 
240
                    endEvent.pageY - start.pageY
 
241
                ];
 
242
 
 
243
                if (params.axis) {
 
244
                    axis = params.axis;
 
245
                } else {
 
246
                    axis = (Math.abs(xyDistance[0]) >= Math.abs(xyDistance[1])) ? 'x' : 'y';
 
247
                }
 
248
 
 
249
                distance = xyDistance[(axis === 'x') ? 0 : 1];
 
250
                velocity = (time !== 0) ? distance/time : 0;
 
251
 
 
252
                if (isFinite(velocity) && (Math.abs(distance) >= params[MIN_DISTANCE]) && (Math.abs(velocity)  >= params[MIN_VELOCITY])) {
 
253
 
 
254
                    e.type = "flick";
 
255
                    e.flick = {
 
256
                        time:time,
 
257
                        distance: distance,
 
258
                        velocity:velocity,
 
259
                        axis: axis,
 
260
                        start : start
 
261
                    };
 
262
 
 
263
                    ce.fire(e);
 
264
 
 
265
                }
 
266
 
 
267
                subscriber[_FLICK_START] = null;
 
268
            }
 
269
        }
 
270
    },
 
271
 
 
272
    MIN_VELOCITY : 0,
 
273
    MIN_DISTANCE : 0,
 
274
    PREVENT_DEFAULT : false
 
275
});
 
276
 
 
277
 
 
278
}, '3.13.0', {"requires": ["node-base", "event-touch", "event-synthetic"]});