aladdin 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +22 -0
- data/README.md +43 -0
- data/assets/images/foundation/orbit/bullets.jpg +0 -0
- data/assets/images/foundation/orbit/left-arrow-small.png +0 -0
- data/assets/images/foundation/orbit/left-arrow.png +0 -0
- data/assets/images/foundation/orbit/loading.gif +0 -0
- data/assets/images/foundation/orbit/mask-black.png +0 -0
- data/assets/images/foundation/orbit/pause-black.png +0 -0
- data/assets/images/foundation/orbit/right-arrow-small.png +0 -0
- data/assets/images/foundation/orbit/right-arrow.png +0 -0
- data/assets/images/foundation/orbit/rotator-black.png +0 -0
- data/assets/images/foundation/orbit/timer-black.png +0 -0
- data/assets/javascripts/foundation/app.js +38 -0
- data/assets/javascripts/foundation/jquery.cookie.js +72 -0
- data/assets/javascripts/foundation/jquery.event.move.js +580 -0
- data/assets/javascripts/foundation/jquery.event.swipe.js +130 -0
- data/assets/javascripts/foundation/jquery.foundation.accordion.js +34 -0
- data/assets/javascripts/foundation/jquery.foundation.alerts.js +20 -0
- data/assets/javascripts/foundation/jquery.foundation.buttons.js +74 -0
- data/assets/javascripts/foundation/jquery.foundation.clearing.js +468 -0
- data/assets/javascripts/foundation/jquery.foundation.forms.js +486 -0
- data/assets/javascripts/foundation/jquery.foundation.joyride.js +639 -0
- data/assets/javascripts/foundation/jquery.foundation.magellan.js +85 -0
- data/assets/javascripts/foundation/jquery.foundation.mediaQueryToggle.js +27 -0
- data/assets/javascripts/foundation/jquery.foundation.navigation.js +55 -0
- data/assets/javascripts/foundation/jquery.foundation.orbit.js +897 -0
- data/assets/javascripts/foundation/jquery.foundation.reveal.js +794 -0
- data/assets/javascripts/foundation/jquery.foundation.tabs.js +43 -0
- data/assets/javascripts/foundation/jquery.foundation.tooltips.js +193 -0
- data/assets/javascripts/foundation/jquery.foundation.topbar.js +152 -0
- data/assets/javascripts/foundation/jquery.js +9440 -0
- data/assets/javascripts/foundation/jquery.offcanvas.js +50 -0
- data/assets/javascripts/foundation/jquery.placeholder.js +157 -0
- data/assets/javascripts/foundation/modernizr.foundation.js +4 -0
- data/bin/aladdin +20 -0
- data/lib/aladdin.rb +43 -0
- data/lib/aladdin/app.rb +89 -0
- data/lib/aladdin/render/markdown.rb +40 -0
- data/lib/aladdin/render/sanitize.rb +84 -0
- data/lib/aladdin/version.rb +4 -0
- data/views/haml/index.haml +43 -0
- data/views/haml/layout.haml +51 -0
- data/views/scss/_settings.scss +242 -0
- data/views/scss/app.scss +47 -0
- data/views/scss/github.scss +65 -0
- data/views/scss/pygment.scss +12 -0
- metadata +307 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jiunn Haur Lim, Carnegie Mellon University
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Aladdin
|
2
|
+
[](https://travis-ci.org/jimjh/aladdin)
|
3
|
+
[](https://gemnasium.com/jimjh/aladdin)
|
4
|
+
[](https://codeclimate.com/github/jimjh/aladdin)
|
5
|
+
|
6
|
+
Generates tutorials using the set of markdown documents provided by the author.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'aladdin'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$> easy_install Pygments
|
16
|
+
$> bundle install
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$> easy_install Pygments
|
21
|
+
$> gem install aladdin
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
Create a new directory for your notes _e.g._ `my_tutorial`. Change into that
|
25
|
+
directory, and create your notes using GitHub-Flavored Markdown. It might look
|
26
|
+
like:
|
27
|
+
|
28
|
+
my_tutorial/
|
29
|
+
01-introduction.md
|
30
|
+
02-the-beginning.md
|
31
|
+
03-the-end.md
|
32
|
+
|
33
|
+
Finally, execute aladdin to launch the Sinatra server:
|
34
|
+
|
35
|
+
$> aladdin
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
1. Fork it
|
40
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
41
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
42
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
43
|
+
5. Create new Pull Request
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,38 @@
|
|
1
|
+
;(function ($, window, undefined) {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
var $doc = $(document),
|
5
|
+
Modernizr = window.Modernizr;
|
6
|
+
|
7
|
+
$(document).ready(function() {
|
8
|
+
$.fn.foundationAlerts ? $doc.foundationAlerts() : null;
|
9
|
+
$.fn.foundationButtons ? $doc.foundationButtons() : null;
|
10
|
+
$.fn.foundationAccordion ? $doc.foundationAccordion() : null;
|
11
|
+
$.fn.foundationNavigation ? $doc.foundationNavigation() : null;
|
12
|
+
$.fn.foundationTopBar ? $doc.foundationTopBar() : null;
|
13
|
+
$.fn.foundationCustomForms ? $doc.foundationCustomForms() : null;
|
14
|
+
$.fn.foundationMediaQueryViewer ? $doc.foundationMediaQueryViewer() : null;
|
15
|
+
$.fn.foundationTabs ? $doc.foundationTabs({callback : $.foundation.customForms.appendCustomMarkup}) : null;
|
16
|
+
$.fn.foundationTooltips ? $doc.foundationTooltips() : null;
|
17
|
+
$.fn.foundationMagellan ? $doc.foundationMagellan() : null;
|
18
|
+
$.fn.foundationClearing ? $doc.foundationClearing() : null;
|
19
|
+
|
20
|
+
$('input, textarea').placeholder();
|
21
|
+
});
|
22
|
+
|
23
|
+
// UNCOMMENT THE LINE YOU WANT BELOW IF YOU WANT IE8 SUPPORT AND ARE USING .block-grids
|
24
|
+
// $('.block-grid.two-up>li:nth-child(2n+1)').css({clear: 'both'});
|
25
|
+
// $('.block-grid.three-up>li:nth-child(3n+1)').css({clear: 'both'});
|
26
|
+
// $('.block-grid.four-up>li:nth-child(4n+1)').css({clear: 'both'});
|
27
|
+
// $('.block-grid.five-up>li:nth-child(5n+1)').css({clear: 'both'});
|
28
|
+
|
29
|
+
// Hide address bar on mobile devices (except if #hash present, so we don't mess up deep linking).
|
30
|
+
if (Modernizr.touch && !window.location.hash) {
|
31
|
+
$(window).load(function () {
|
32
|
+
setTimeout(function () {
|
33
|
+
window.scrollTo(0, 1);
|
34
|
+
}, 0);
|
35
|
+
});
|
36
|
+
}
|
37
|
+
|
38
|
+
})(jQuery, this);
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/*!
|
2
|
+
* jQuery Cookie Plugin v1.3
|
3
|
+
* https://github.com/carhartl/jquery-cookie
|
4
|
+
*
|
5
|
+
* Copyright 2011, Klaus Hartl
|
6
|
+
* Dual licensed under the MIT or GPL Version 2 licenses.
|
7
|
+
* http://www.opensource.org/licenses/mit-license.php
|
8
|
+
* http://www.opensource.org/licenses/GPL-2.0
|
9
|
+
*/
|
10
|
+
(function ($, document, undefined) {
|
11
|
+
|
12
|
+
var pluses = /\+/g;
|
13
|
+
|
14
|
+
function raw(s) {
|
15
|
+
return s;
|
16
|
+
}
|
17
|
+
|
18
|
+
function decoded(s) {
|
19
|
+
return decodeURIComponent(s.replace(pluses, ' '));
|
20
|
+
}
|
21
|
+
|
22
|
+
var config = $.cookie = function (key, value, options) {
|
23
|
+
|
24
|
+
// write
|
25
|
+
if (value !== undefined) {
|
26
|
+
options = $.extend({}, config.defaults, options);
|
27
|
+
|
28
|
+
if (value === null) {
|
29
|
+
options.expires = -1;
|
30
|
+
}
|
31
|
+
|
32
|
+
if (typeof options.expires === 'number') {
|
33
|
+
var days = options.expires, t = options.expires = new Date();
|
34
|
+
t.setDate(t.getDate() + days);
|
35
|
+
}
|
36
|
+
|
37
|
+
value = config.json ? JSON.stringify(value) : String(value);
|
38
|
+
|
39
|
+
return (document.cookie = [
|
40
|
+
encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
|
41
|
+
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
42
|
+
options.path ? '; path=' + options.path : '',
|
43
|
+
options.domain ? '; domain=' + options.domain : '',
|
44
|
+
options.secure ? '; secure' : ''
|
45
|
+
].join(''));
|
46
|
+
}
|
47
|
+
|
48
|
+
// read
|
49
|
+
var decode = config.raw ? raw : decoded;
|
50
|
+
var cookies = document.cookie.split('; ');
|
51
|
+
for (var i = 0, l = cookies.length; i < l; i++) {
|
52
|
+
var parts = cookies[i].split('=');
|
53
|
+
if (decode(parts.shift()) === key) {
|
54
|
+
var cookie = decode(parts.join('='));
|
55
|
+
return config.json ? JSON.parse(cookie) : cookie;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
return null;
|
60
|
+
};
|
61
|
+
|
62
|
+
config.defaults = {};
|
63
|
+
|
64
|
+
$.removeCookie = function (key, options) {
|
65
|
+
if ($.cookie(key) !== null) {
|
66
|
+
$.cookie(key, null, options);
|
67
|
+
return true;
|
68
|
+
}
|
69
|
+
return false;
|
70
|
+
};
|
71
|
+
|
72
|
+
})(jQuery, document);
|
@@ -0,0 +1,580 @@
|
|
1
|
+
// jquery.event.move
|
2
|
+
//
|
3
|
+
// 1.3.1
|
4
|
+
//
|
5
|
+
// Stephen Band
|
6
|
+
//
|
7
|
+
// Triggers 'movestart', 'move' and 'moveend' events after
|
8
|
+
// mousemoves following a mousedown cross a distance threshold,
|
9
|
+
// similar to the native 'dragstart', 'drag' and 'dragend' events.
|
10
|
+
// Move events are throttled to animation frames. Move event objects
|
11
|
+
// have the properties:
|
12
|
+
//
|
13
|
+
// pageX:
|
14
|
+
// pageY: Page coordinates of pointer.
|
15
|
+
// startX:
|
16
|
+
// startY: Page coordinates of pointer at movestart.
|
17
|
+
// distX:
|
18
|
+
// distY: Distance the pointer has moved since movestart.
|
19
|
+
// deltaX:
|
20
|
+
// deltaY: Distance the finger has moved since last event.
|
21
|
+
// velocityX:
|
22
|
+
// velocityY: Average velocity over last few events.
|
23
|
+
|
24
|
+
|
25
|
+
(function (module) {
|
26
|
+
if (typeof define === 'function' && define.amd) {
|
27
|
+
// AMD. Register as an anonymous module.
|
28
|
+
define(['jquery'], module);
|
29
|
+
} else {
|
30
|
+
// Browser globals
|
31
|
+
module(jQuery);
|
32
|
+
}
|
33
|
+
})(function(jQuery, undefined){
|
34
|
+
|
35
|
+
var // Number of pixels a pressed pointer travels before movestart
|
36
|
+
// event is fired.
|
37
|
+
threshold = 6,
|
38
|
+
|
39
|
+
add = jQuery.event.add,
|
40
|
+
|
41
|
+
remove = jQuery.event.remove,
|
42
|
+
|
43
|
+
// Just sugar, so we can have arguments in the same order as
|
44
|
+
// add and remove.
|
45
|
+
trigger = function(node, type, data) {
|
46
|
+
jQuery.event.trigger(type, data, node);
|
47
|
+
},
|
48
|
+
|
49
|
+
// Shim for requestAnimationFrame, falling back to timer. See:
|
50
|
+
// see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
51
|
+
requestFrame = (function(){
|
52
|
+
return (
|
53
|
+
window.requestAnimationFrame ||
|
54
|
+
window.webkitRequestAnimationFrame ||
|
55
|
+
window.mozRequestAnimationFrame ||
|
56
|
+
window.oRequestAnimationFrame ||
|
57
|
+
window.msRequestAnimationFrame ||
|
58
|
+
function(fn, element){
|
59
|
+
return window.setTimeout(function(){
|
60
|
+
fn();
|
61
|
+
}, 25);
|
62
|
+
}
|
63
|
+
);
|
64
|
+
})(),
|
65
|
+
|
66
|
+
ignoreTags = {
|
67
|
+
textarea: true,
|
68
|
+
input: true,
|
69
|
+
select: true,
|
70
|
+
button: true
|
71
|
+
},
|
72
|
+
|
73
|
+
mouseevents = {
|
74
|
+
move: 'mousemove',
|
75
|
+
cancel: 'mouseup dragstart',
|
76
|
+
end: 'mouseup'
|
77
|
+
},
|
78
|
+
|
79
|
+
touchevents = {
|
80
|
+
move: 'touchmove',
|
81
|
+
cancel: 'touchend',
|
82
|
+
end: 'touchend'
|
83
|
+
};
|
84
|
+
|
85
|
+
|
86
|
+
// Constructors
|
87
|
+
|
88
|
+
function Timer(fn){
|
89
|
+
var callback = fn,
|
90
|
+
active = false,
|
91
|
+
running = false;
|
92
|
+
|
93
|
+
function trigger(time) {
|
94
|
+
if (active){
|
95
|
+
callback();
|
96
|
+
requestFrame(trigger);
|
97
|
+
running = true;
|
98
|
+
active = false;
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
running = false;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
this.kick = function(fn) {
|
106
|
+
active = true;
|
107
|
+
if (!running) { trigger(); }
|
108
|
+
};
|
109
|
+
|
110
|
+
this.end = function(fn) {
|
111
|
+
var cb = callback;
|
112
|
+
|
113
|
+
if (!fn) { return; }
|
114
|
+
|
115
|
+
// If the timer is not running, simply call the end callback.
|
116
|
+
if (!running) {
|
117
|
+
fn();
|
118
|
+
}
|
119
|
+
// If the timer is running, and has been kicked lately, then
|
120
|
+
// queue up the current callback and the end callback, otherwise
|
121
|
+
// just the end callback.
|
122
|
+
else {
|
123
|
+
callback = active ?
|
124
|
+
function(){ cb(); fn(); } :
|
125
|
+
fn ;
|
126
|
+
|
127
|
+
active = true;
|
128
|
+
}
|
129
|
+
};
|
130
|
+
}
|
131
|
+
|
132
|
+
|
133
|
+
// Functions
|
134
|
+
|
135
|
+
function returnTrue() {
|
136
|
+
return true;
|
137
|
+
}
|
138
|
+
|
139
|
+
function returnFalse() {
|
140
|
+
return false;
|
141
|
+
}
|
142
|
+
|
143
|
+
function preventDefault(e) {
|
144
|
+
e.preventDefault();
|
145
|
+
}
|
146
|
+
|
147
|
+
function preventIgnoreTags(e) {
|
148
|
+
// Don't prevent interaction with form elements.
|
149
|
+
if (ignoreTags[ e.target.tagName.toLowerCase() ]) { return; }
|
150
|
+
|
151
|
+
e.preventDefault();
|
152
|
+
}
|
153
|
+
|
154
|
+
function isLeftButton(e) {
|
155
|
+
// Ignore mousedowns on any button other than the left (or primary)
|
156
|
+
// mouse button, or when a modifier key is pressed.
|
157
|
+
return (e.which === 1 && !e.ctrlKey && !e.altKey);
|
158
|
+
}
|
159
|
+
|
160
|
+
function identifiedTouch(touchList, id) {
|
161
|
+
var i, l;
|
162
|
+
|
163
|
+
if (touchList.identifiedTouch) {
|
164
|
+
return touchList.identifiedTouch(id);
|
165
|
+
}
|
166
|
+
|
167
|
+
// touchList.identifiedTouch() does not exist in
|
168
|
+
// webkit yet… we must do the search ourselves...
|
169
|
+
|
170
|
+
i = -1;
|
171
|
+
l = touchList.length;
|
172
|
+
|
173
|
+
while (++i < l) {
|
174
|
+
if (touchList[i].identifier === id) {
|
175
|
+
return touchList[i];
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
function changedTouch(e, event) {
|
181
|
+
var touch = identifiedTouch(e.changedTouches, event.identifier);
|
182
|
+
|
183
|
+
// This isn't the touch you're looking for.
|
184
|
+
if (!touch) { return; }
|
185
|
+
|
186
|
+
// Chrome Android (at least) includes touches that have not
|
187
|
+
// changed in e.changedTouches. That's a bit annoying. Check
|
188
|
+
// that this touch has changed.
|
189
|
+
if (touch.pageX === event.pageX && touch.pageY === event.pageY) { return; }
|
190
|
+
|
191
|
+
return touch;
|
192
|
+
}
|
193
|
+
|
194
|
+
|
195
|
+
// Handlers that decide when the first movestart is triggered
|
196
|
+
|
197
|
+
function mousedown(e){
|
198
|
+
var data;
|
199
|
+
|
200
|
+
if (!isLeftButton(e)) { return; }
|
201
|
+
|
202
|
+
data = {
|
203
|
+
target: e.target,
|
204
|
+
startX: e.pageX,
|
205
|
+
startY: e.pageY,
|
206
|
+
timeStamp: e.timeStamp
|
207
|
+
};
|
208
|
+
|
209
|
+
add(document, mouseevents.move, mousemove, data);
|
210
|
+
add(document, mouseevents.cancel, mouseend, data);
|
211
|
+
}
|
212
|
+
|
213
|
+
function mousemove(e){
|
214
|
+
var data = e.data;
|
215
|
+
|
216
|
+
checkThreshold(e, data, e, removeMouse);
|
217
|
+
}
|
218
|
+
|
219
|
+
function mouseend(e) {
|
220
|
+
removeMouse();
|
221
|
+
}
|
222
|
+
|
223
|
+
function removeMouse() {
|
224
|
+
remove(document, mouseevents.move, mousemove);
|
225
|
+
remove(document, mouseevents.cancel, removeMouse);
|
226
|
+
}
|
227
|
+
|
228
|
+
function touchstart(e) {
|
229
|
+
var touch, template;
|
230
|
+
|
231
|
+
// Don't get in the way of interaction with form elements.
|
232
|
+
if (ignoreTags[ e.target.tagName.toLowerCase() ]) { return; }
|
233
|
+
|
234
|
+
touch = e.changedTouches[0];
|
235
|
+
|
236
|
+
// iOS live updates the touch objects whereas Android gives us copies.
|
237
|
+
// That means we can't trust the touchstart object to stay the same,
|
238
|
+
// so we must copy the data. This object acts as a template for
|
239
|
+
// movestart, move and moveend event objects.
|
240
|
+
template = {
|
241
|
+
target: touch.target,
|
242
|
+
startX: touch.pageX,
|
243
|
+
startY: touch.pageY,
|
244
|
+
timeStamp: e.timeStamp,
|
245
|
+
identifier: touch.identifier
|
246
|
+
};
|
247
|
+
|
248
|
+
// Use the touch identifier as a namespace, so that we can later
|
249
|
+
// remove handlers pertaining only to this touch.
|
250
|
+
add(document, touchevents.move + '.' + touch.identifier, touchmove, template);
|
251
|
+
add(document, touchevents.cancel + '.' + touch.identifier, touchend, template);
|
252
|
+
}
|
253
|
+
|
254
|
+
function touchmove(e){
|
255
|
+
var data = e.data,
|
256
|
+
touch = changedTouch(e, data);
|
257
|
+
|
258
|
+
if (!touch) { return; }
|
259
|
+
|
260
|
+
checkThreshold(e, data, touch, removeTouch);
|
261
|
+
}
|
262
|
+
|
263
|
+
function touchend(e) {
|
264
|
+
var template = e.data,
|
265
|
+
touch = identifiedTouch(e.changedTouches, template.identifier);
|
266
|
+
|
267
|
+
if (!touch) { return; }
|
268
|
+
|
269
|
+
removeTouch(template.identifier);
|
270
|
+
}
|
271
|
+
|
272
|
+
function removeTouch(identifier) {
|
273
|
+
remove(document, '.' + identifier, touchmove);
|
274
|
+
remove(document, '.' + identifier, touchend);
|
275
|
+
}
|
276
|
+
|
277
|
+
|
278
|
+
// Logic for deciding when to trigger a movestart.
|
279
|
+
|
280
|
+
function checkThreshold(e, template, touch, fn) {
|
281
|
+
var distX = touch.pageX - template.startX,
|
282
|
+
distY = touch.pageY - template.startY;
|
283
|
+
|
284
|
+
// Do nothing if the threshold has not been crossed.
|
285
|
+
if ((distX * distX) + (distY * distY) < (threshold * threshold)) { return; }
|
286
|
+
|
287
|
+
triggerStart(e, template, touch, distX, distY, fn);
|
288
|
+
}
|
289
|
+
|
290
|
+
function handled() {
|
291
|
+
// this._handled should return false once, and after return true.
|
292
|
+
this._handled = returnTrue;
|
293
|
+
return false;
|
294
|
+
}
|
295
|
+
|
296
|
+
function flagAsHandled(e) {
|
297
|
+
e._handled();
|
298
|
+
}
|
299
|
+
|
300
|
+
function triggerStart(e, template, touch, distX, distY, fn) {
|
301
|
+
var node = template.target,
|
302
|
+
touches, time;
|
303
|
+
|
304
|
+
touches = e.targetTouches;
|
305
|
+
time = e.timeStamp - template.timeStamp;
|
306
|
+
|
307
|
+
// Create a movestart object with some special properties that
|
308
|
+
// are passed only to the movestart handlers.
|
309
|
+
template.type = 'movestart';
|
310
|
+
template.distX = distX;
|
311
|
+
template.distY = distY;
|
312
|
+
template.deltaX = distX;
|
313
|
+
template.deltaY = distY;
|
314
|
+
template.pageX = touch.pageX;
|
315
|
+
template.pageY = touch.pageY;
|
316
|
+
template.velocityX = distX / time;
|
317
|
+
template.velocityY = distY / time;
|
318
|
+
template.targetTouches = touches;
|
319
|
+
template.finger = touches ?
|
320
|
+
touches.length :
|
321
|
+
1 ;
|
322
|
+
|
323
|
+
// The _handled method is fired to tell the default movestart
|
324
|
+
// handler that one of the move events is bound.
|
325
|
+
template._handled = handled;
|
326
|
+
|
327
|
+
// Pass the touchmove event so it can be prevented if or when
|
328
|
+
// movestart is handled.
|
329
|
+
template._preventTouchmoveDefault = function() {
|
330
|
+
e.preventDefault();
|
331
|
+
};
|
332
|
+
|
333
|
+
// Trigger the movestart event.
|
334
|
+
trigger(template.target, template);
|
335
|
+
|
336
|
+
// Unbind handlers that tracked the touch or mouse up till now.
|
337
|
+
fn(template.identifier);
|
338
|
+
}
|
339
|
+
|
340
|
+
|
341
|
+
// Handlers that control what happens following a movestart
|
342
|
+
|
343
|
+
function activeMousemove(e) {
|
344
|
+
var event = e.data.event,
|
345
|
+
timer = e.data.timer;
|
346
|
+
|
347
|
+
updateEvent(event, e, e.timeStamp, timer);
|
348
|
+
}
|
349
|
+
|
350
|
+
function activeMouseend(e) {
|
351
|
+
var event = e.data.event,
|
352
|
+
timer = e.data.timer;
|
353
|
+
|
354
|
+
removeActiveMouse();
|
355
|
+
|
356
|
+
endEvent(event, timer, function() {
|
357
|
+
// Unbind the click suppressor, waiting until after mouseup
|
358
|
+
// has been handled.
|
359
|
+
setTimeout(function(){
|
360
|
+
remove(event.target, 'click', returnFalse);
|
361
|
+
}, 0);
|
362
|
+
});
|
363
|
+
}
|
364
|
+
|
365
|
+
function removeActiveMouse(event) {
|
366
|
+
remove(document, mouseevents.move, activeMousemove);
|
367
|
+
remove(document, mouseevents.end, activeMouseend);
|
368
|
+
}
|
369
|
+
|
370
|
+
function activeTouchmove(e) {
|
371
|
+
var event = e.data.event,
|
372
|
+
timer = e.data.timer,
|
373
|
+
touch = changedTouch(e, event);
|
374
|
+
|
375
|
+
if (!touch) { return; }
|
376
|
+
|
377
|
+
// Stop the interface from gesturing
|
378
|
+
e.preventDefault();
|
379
|
+
|
380
|
+
event.targetTouches = e.targetTouches;
|
381
|
+
updateEvent(event, touch, e.timeStamp, timer);
|
382
|
+
}
|
383
|
+
|
384
|
+
function activeTouchend(e) {
|
385
|
+
var event = e.data.event,
|
386
|
+
timer = e.data.timer,
|
387
|
+
touch = identifiedTouch(e.changedTouches, event.identifier);
|
388
|
+
|
389
|
+
// This isn't the touch you're looking for.
|
390
|
+
if (!touch) { return; }
|
391
|
+
|
392
|
+
removeActiveTouch(event);
|
393
|
+
endEvent(event, timer);
|
394
|
+
}
|
395
|
+
|
396
|
+
function removeActiveTouch(event) {
|
397
|
+
remove(document, '.' + event.identifier, activeTouchmove);
|
398
|
+
remove(document, '.' + event.identifier, activeTouchend);
|
399
|
+
}
|
400
|
+
|
401
|
+
|
402
|
+
// Logic for triggering move and moveend events
|
403
|
+
|
404
|
+
function updateEvent(event, touch, timeStamp, timer) {
|
405
|
+
var time = timeStamp - event.timeStamp;
|
406
|
+
|
407
|
+
event.type = 'move';
|
408
|
+
event.distX = touch.pageX - event.startX;
|
409
|
+
event.distY = touch.pageY - event.startY;
|
410
|
+
event.deltaX = touch.pageX - event.pageX;
|
411
|
+
event.deltaY = touch.pageY - event.pageY;
|
412
|
+
|
413
|
+
// Average the velocity of the last few events using a decay
|
414
|
+
// curve to even out spurious jumps in values.
|
415
|
+
event.velocityX = 0.3 * event.velocityX + 0.7 * event.deltaX / time;
|
416
|
+
event.velocityY = 0.3 * event.velocityY + 0.7 * event.deltaY / time;
|
417
|
+
event.pageX = touch.pageX;
|
418
|
+
event.pageY = touch.pageY;
|
419
|
+
|
420
|
+
timer.kick();
|
421
|
+
}
|
422
|
+
|
423
|
+
function endEvent(event, timer, fn) {
|
424
|
+
timer.end(function(){
|
425
|
+
event.type = 'moveend';
|
426
|
+
|
427
|
+
trigger(event.target, event);
|
428
|
+
|
429
|
+
return fn && fn();
|
430
|
+
});
|
431
|
+
}
|
432
|
+
|
433
|
+
|
434
|
+
// jQuery special event definition
|
435
|
+
|
436
|
+
function setup(data, namespaces, eventHandle) {
|
437
|
+
// Stop the node from being dragged
|
438
|
+
//add(this, 'dragstart.move drag.move', preventDefault);
|
439
|
+
|
440
|
+
// Prevent text selection and touch interface scrolling
|
441
|
+
//add(this, 'mousedown.move', preventIgnoreTags);
|
442
|
+
|
443
|
+
// Tell movestart default handler that we've handled this
|
444
|
+
add(this, 'movestart.move', flagAsHandled);
|
445
|
+
|
446
|
+
// Don't bind to the DOM. For speed.
|
447
|
+
return true;
|
448
|
+
}
|
449
|
+
|
450
|
+
function teardown(namespaces) {
|
451
|
+
remove(this, 'dragstart drag', preventDefault);
|
452
|
+
remove(this, 'mousedown touchstart', preventIgnoreTags);
|
453
|
+
remove(this, 'movestart', flagAsHandled);
|
454
|
+
|
455
|
+
// Don't bind to the DOM. For speed.
|
456
|
+
return true;
|
457
|
+
}
|
458
|
+
|
459
|
+
function addMethod(handleObj) {
|
460
|
+
// We're not interested in preventing defaults for handlers that
|
461
|
+
// come from internal move or moveend bindings
|
462
|
+
if (handleObj.namespace === "move" || handleObj.namespace === "moveend") {
|
463
|
+
return;
|
464
|
+
}
|
465
|
+
|
466
|
+
// Stop the node from being dragged
|
467
|
+
add(this, 'dragstart.' + handleObj.guid + ' drag.' + handleObj.guid, preventDefault, undefined, handleObj.selector);
|
468
|
+
|
469
|
+
// Prevent text selection and touch interface scrolling
|
470
|
+
add(this, 'mousedown.' + handleObj.guid, preventIgnoreTags, undefined, handleObj.selector);
|
471
|
+
}
|
472
|
+
|
473
|
+
function removeMethod(handleObj) {
|
474
|
+
if (handleObj.namespace === "move" || handleObj.namespace === "moveend") {
|
475
|
+
return;
|
476
|
+
}
|
477
|
+
|
478
|
+
remove(this, 'dragstart.' + handleObj.guid + ' drag.' + handleObj.guid);
|
479
|
+
remove(this, 'mousedown.' + handleObj.guid);
|
480
|
+
}
|
481
|
+
|
482
|
+
jQuery.event.special.movestart = {
|
483
|
+
setup: setup,
|
484
|
+
teardown: teardown,
|
485
|
+
add: addMethod,
|
486
|
+
remove: removeMethod,
|
487
|
+
|
488
|
+
_default: function(e) {
|
489
|
+
var template, data;
|
490
|
+
|
491
|
+
// If no move events were bound to any ancestors of this
|
492
|
+
// target, high tail it out of here.
|
493
|
+
if (!e._handled()) { return; }
|
494
|
+
|
495
|
+
template = {
|
496
|
+
target: e.target,
|
497
|
+
startX: e.startX,
|
498
|
+
startY: e.startY,
|
499
|
+
pageX: e.pageX,
|
500
|
+
pageY: e.pageY,
|
501
|
+
distX: e.distX,
|
502
|
+
distY: e.distY,
|
503
|
+
deltaX: e.deltaX,
|
504
|
+
deltaY: e.deltaY,
|
505
|
+
velocityX: e.velocityX,
|
506
|
+
velocityY: e.velocityY,
|
507
|
+
timeStamp: e.timeStamp,
|
508
|
+
identifier: e.identifier,
|
509
|
+
targetTouches: e.targetTouches,
|
510
|
+
finger: e.finger
|
511
|
+
};
|
512
|
+
|
513
|
+
data = {
|
514
|
+
event: template,
|
515
|
+
timer: new Timer(function(time){
|
516
|
+
trigger(e.target, template);
|
517
|
+
})
|
518
|
+
};
|
519
|
+
|
520
|
+
if (e.identifier === undefined) {
|
521
|
+
// We're dealing with a mouse
|
522
|
+
// Stop clicks from propagating during a move
|
523
|
+
add(e.target, 'click', returnFalse);
|
524
|
+
add(document, mouseevents.move, activeMousemove, data);
|
525
|
+
add(document, mouseevents.end, activeMouseend, data);
|
526
|
+
}
|
527
|
+
else {
|
528
|
+
// We're dealing with a touch. Stop touchmove doing
|
529
|
+
// anything defaulty.
|
530
|
+
e._preventTouchmoveDefault();
|
531
|
+
add(document, touchevents.move + '.' + e.identifier, activeTouchmove, data);
|
532
|
+
add(document, touchevents.end + '.' + e.identifier, activeTouchend, data);
|
533
|
+
}
|
534
|
+
}
|
535
|
+
};
|
536
|
+
|
537
|
+
jQuery.event.special.move = {
|
538
|
+
setup: function() {
|
539
|
+
// Bind a noop to movestart. Why? It's the movestart
|
540
|
+
// setup that decides whether other move events are fired.
|
541
|
+
add(this, 'movestart.move', jQuery.noop);
|
542
|
+
},
|
543
|
+
|
544
|
+
teardown: function() {
|
545
|
+
remove(this, 'movestart.move', jQuery.noop);
|
546
|
+
}
|
547
|
+
};
|
548
|
+
|
549
|
+
jQuery.event.special.moveend = {
|
550
|
+
setup: function() {
|
551
|
+
// Bind a noop to movestart. Why? It's the movestart
|
552
|
+
// setup that decides whether other move events are fired.
|
553
|
+
add(this, 'movestart.moveend', jQuery.noop);
|
554
|
+
},
|
555
|
+
|
556
|
+
teardown: function() {
|
557
|
+
remove(this, 'movestart.moveend', jQuery.noop);
|
558
|
+
}
|
559
|
+
};
|
560
|
+
|
561
|
+
add(document, 'mousedown.move', mousedown);
|
562
|
+
add(document, 'touchstart.move', touchstart);
|
563
|
+
|
564
|
+
// Make jQuery copy touch event properties over to the jQuery event
|
565
|
+
// object, if they are not already listed. But only do the ones we
|
566
|
+
// really need. IE7/8 do not have Array#indexOf(), but nor do they
|
567
|
+
// have touch events, so let's assume we can ignore them.
|
568
|
+
if (typeof Array.prototype.indexOf === 'function') {
|
569
|
+
(function(jQuery, undefined){
|
570
|
+
var props = ["changedTouches", "targetTouches"],
|
571
|
+
l = props.length;
|
572
|
+
|
573
|
+
while (l--) {
|
574
|
+
if (jQuery.event.props.indexOf(props[l]) === -1) {
|
575
|
+
jQuery.event.props.push(props[l]);
|
576
|
+
}
|
577
|
+
}
|
578
|
+
})(jQuery);
|
579
|
+
};
|
580
|
+
});
|