monocle-rails 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/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/monocle/rails.rb +8 -0
- data/lib/monocle/rails/version.rb +5 -0
- data/monocle-rails.gemspec +23 -0
- data/vendor/.DS_Store +0 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/compat/browser.js +120 -0
- data/vendor/assets/javascripts/compat/css.js +145 -0
- data/vendor/assets/javascripts/compat/env.js +463 -0
- data/vendor/assets/javascripts/compat/gala.js +469 -0
- data/vendor/assets/javascripts/compat/stubs.js +50 -0
- data/vendor/assets/javascripts/controls/contents.js +59 -0
- data/vendor/assets/javascripts/controls/magnifier.js +51 -0
- data/vendor/assets/javascripts/controls/panel.js +136 -0
- data/vendor/assets/javascripts/controls/placesaver.js +100 -0
- data/vendor/assets/javascripts/controls/scrubber.js +140 -0
- data/vendor/assets/javascripts/controls/spinner.js +99 -0
- data/vendor/assets/javascripts/controls/stencil.js +410 -0
- data/vendor/assets/javascripts/core/billboard.js +120 -0
- data/vendor/assets/javascripts/core/book.js +467 -0
- data/vendor/assets/javascripts/core/bookdata.js +59 -0
- data/vendor/assets/javascripts/core/component.js +413 -0
- data/vendor/assets/javascripts/core/events.js +56 -0
- data/vendor/assets/javascripts/core/factory.js +194 -0
- data/vendor/assets/javascripts/core/formatting.js +317 -0
- data/vendor/assets/javascripts/core/monocle.js +16 -0
- data/vendor/assets/javascripts/core/place.js +210 -0
- data/vendor/assets/javascripts/core/reader.js +683 -0
- data/vendor/assets/javascripts/core/selection.js +158 -0
- data/vendor/assets/javascripts/core/styles.js +155 -0
- data/vendor/assets/javascripts/dimensions/columns.js +218 -0
- data/vendor/assets/javascripts/flippers/instant.js +78 -0
- data/vendor/assets/javascripts/flippers/scroller.js +128 -0
- data/vendor/assets/javascripts/flippers/slider.js +469 -0
- data/vendor/assets/javascripts/monocore.js +27 -0
- data/vendor/assets/javascripts/monoctrl.js +1 -0
- data/vendor/assets/javascripts/panels/eink.js +61 -0
- data/vendor/assets/javascripts/panels/imode.js +180 -0
- data/vendor/assets/javascripts/panels/magic.js +297 -0
- data/vendor/assets/javascripts/panels/marginal.js +50 -0
- data/vendor/assets/javascripts/panels/twopane.js +34 -0
- data/vendor/assets/stylesheets/monocore.css +194 -0
- data/vendor/assets/stylesheets/monoctrl.css +168 -0
- metadata +129 -0
@@ -0,0 +1,469 @@
|
|
1
|
+
Gala = {}
|
2
|
+
|
3
|
+
|
4
|
+
// Register an event listener.
|
5
|
+
//
|
6
|
+
Gala.listen = function (elem, evtType, fn, useCapture) {
|
7
|
+
elem = Gala.$(elem);
|
8
|
+
if (elem.addEventListener) {
|
9
|
+
elem.addEventListener(evtType, fn, useCapture || false);
|
10
|
+
} else if (elem.attachEvent) {
|
11
|
+
if (evtType.indexOf(':') < 1) {
|
12
|
+
elem.attachEvent('on'+evtType, fn);
|
13
|
+
} else {
|
14
|
+
var h = (Gala.IE_REGISTRATIONS[elem] = Gala.IE_REGISTRATIONS[elem] || {});
|
15
|
+
var a = (h[evtType] = h[evtType] || []);
|
16
|
+
a.push(fn);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
// Remove an event listener.
|
23
|
+
//
|
24
|
+
Gala.deafen = function (elem, evtType, fn, useCapture) {
|
25
|
+
elem = Gala.$(elem);
|
26
|
+
if (elem.removeEventListener) {
|
27
|
+
elem.removeEventListener(evtType, fn, useCapture || false);
|
28
|
+
} else if (elem.detachEvent) {
|
29
|
+
if (evtType.indexOf(':') < 1) {
|
30
|
+
elem.detachEvent('on'+evtType, fn);
|
31
|
+
} else {
|
32
|
+
var h = (Gala.IE_REGISTRATIONS[elem] = Gala.IE_REGISTRATIONS[elem] || {});
|
33
|
+
var a = (h[evtType] = h[evtType] || []);
|
34
|
+
for (var i = 0, ii = a.length; i < ii; ++i) {
|
35
|
+
if (a[i] == fn) { a.splice(i, 1); }
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
// Fire an event on the element.
|
43
|
+
//
|
44
|
+
// The data supplied to this function will be available in the event object in
|
45
|
+
// the 'm' property -- eg, alert(evt.m) --> 'foo'
|
46
|
+
//
|
47
|
+
Gala.dispatch = function (elem, evtType, data, cancelable) {
|
48
|
+
elem = Gala.$(elem);
|
49
|
+
var evt;
|
50
|
+
if (elem.dispatchEvent) {
|
51
|
+
evt = document.createEvent('Events');
|
52
|
+
evt.initEvent(evtType, false, cancelable || false);
|
53
|
+
evt.m = data;
|
54
|
+
return elem.dispatchEvent(evt);
|
55
|
+
} else if (elem.attachEvent && evtType.indexOf(':') >= 0) {
|
56
|
+
if (!Gala.IE_REGISTRATIONS[elem]) { return true; }
|
57
|
+
var evtHandlers = Gala.IE_REGISTRATIONS[elem][evtType];
|
58
|
+
if (!evtHandlers || evtHandlers.length < 1) { return true; }
|
59
|
+
evt = {
|
60
|
+
type: evtType,
|
61
|
+
currentTarget: elem,
|
62
|
+
target: elem,
|
63
|
+
m: data,
|
64
|
+
defaultPrevented: false,
|
65
|
+
preventDefault: function () { evt.defaultPrevented = true; }
|
66
|
+
}
|
67
|
+
var q, processQueue = Gala.IE_INVOCATION_QUEUE.length === 0;
|
68
|
+
for (var i = 0, ii = evtHandlers.length; i < ii; ++i) {
|
69
|
+
q = { elem: elem, evtType: evtType, handler: evtHandlers[i], evt: evt }
|
70
|
+
Gala.IE_INVOCATION_QUEUE.push(q);
|
71
|
+
}
|
72
|
+
if (processQueue) {
|
73
|
+
while (q = Gala.IE_INVOCATION_QUEUE.shift()) {
|
74
|
+
//console.log("IE EVT on %s: '%s' with data: %s", q.elem, q.evtType, q.evt.m);
|
75
|
+
q.handler(q.evt);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
return !(cancelable && evt.defaultPrevented);
|
79
|
+
} else {
|
80
|
+
console.warn('[GALA] Cannot dispatch non-namespaced events: '+evtType);
|
81
|
+
return true;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
// Prevents the browser-default action on an event and stops it from
|
87
|
+
// propagating up the DOM tree.
|
88
|
+
//
|
89
|
+
Gala.stop = function (evt) {
|
90
|
+
evt = evt || window.event;
|
91
|
+
if (evt.preventDefault) { evt.preventDefault(); }
|
92
|
+
if (evt.stopPropagation) { evt.stopPropagation(); }
|
93
|
+
evt.returnValue = false;
|
94
|
+
evt.cancelBubble = true;
|
95
|
+
return false;
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
// Add a group of listeners, which is just a hash of { evtType: callback, ... }
|
100
|
+
//
|
101
|
+
Gala.listenGroup = function (elem, listeners, useCapture) {
|
102
|
+
for (var evtType in listeners) {
|
103
|
+
Gala.listen(elem, evtType, listeners[evtType], useCapture || false);
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
// Remove a group of listeners.
|
109
|
+
//
|
110
|
+
Gala.deafenGroup = function (elem, listeners, useCapture) {
|
111
|
+
for (var evtType in listeners) {
|
112
|
+
Gala.deafen(elem, evtType, listeners[evtType], useCapture || false);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
|
117
|
+
// Replace a group of listeners with another group, re-using the same
|
118
|
+
// 'listeners' object -- a common pattern.
|
119
|
+
//
|
120
|
+
Gala.replaceGroup = function (elem, listeners, newListeners, useCapture) {
|
121
|
+
Gala.deafenGroup(elem, listeners, useCapture || false);
|
122
|
+
for (var evtType in listeners) { delete listeners[evtType]; }
|
123
|
+
for (evtType in newListeners) { listeners[evtType] = newListeners[evtType]; }
|
124
|
+
Gala.listenGroup(elem, listeners, useCapture || false);
|
125
|
+
return listeners;
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
// Listen for a tap or a click event.
|
130
|
+
//
|
131
|
+
// Returns a 'listener' object that can be passed to Gala.deafenGroup().
|
132
|
+
//
|
133
|
+
// If 'tapClass' is undefined, it defaults to 'tapping'. If it is a blank
|
134
|
+
// string, no class is assigned.
|
135
|
+
//
|
136
|
+
Gala.onTap = function (elem, fn, tapClass) {
|
137
|
+
elem = Gala.$(elem);
|
138
|
+
// Throttle the invocation to prevent double firing of the event in envs
|
139
|
+
// that support touch and mouse. Particularly in Firefox and Chrome on IE 8,
|
140
|
+
// a mouse event and touch events are both fired.
|
141
|
+
// Ref https://github.com/joseph/Monocle/pull/216#issuecomment-21424427
|
142
|
+
fn = Gala.throttle(fn, 100);
|
143
|
+
|
144
|
+
if (typeof tapClass == 'undefined') { tapClass = Gala.TAPPING_CLASS; }
|
145
|
+
|
146
|
+
var tapStartingCoords = {};
|
147
|
+
|
148
|
+
// If the tap extends beyond a few pixels, it's no longer a tap.
|
149
|
+
var tapIsValid = function (evt) {
|
150
|
+
var cur = Gala.Cursor(evt);
|
151
|
+
var xDelta = Math.abs(cur.pageX - tapStartingCoords.x);
|
152
|
+
var yDelta = Math.abs(cur.pageY - tapStartingCoords.y);
|
153
|
+
var maxContact = Math.max(xDelta, yDelta);
|
154
|
+
return Gala.TAP_MAX_CONTACT_DISTANCE >= maxContact;
|
155
|
+
}
|
156
|
+
|
157
|
+
// This ensures the element is considered 'clickable' by browsers
|
158
|
+
// like on the Kindle 3.
|
159
|
+
var noopOnClick = function (listeners) {
|
160
|
+
Gala.listen(elem, 'click', listeners.click = fns.noop);
|
161
|
+
}
|
162
|
+
|
163
|
+
var fns = {
|
164
|
+
start: function (evt) {
|
165
|
+
var cur = Gala.Cursor(evt);
|
166
|
+
tapStartingCoords = { x: cur.pageX, y: cur.pageY };
|
167
|
+
if (tapClass) { elem.classList.add(tapClass); }
|
168
|
+
},
|
169
|
+
move: function (evt) {
|
170
|
+
if (!tapStartingCoords) { return; }
|
171
|
+
if (!tapIsValid(evt)) { fns.cancel(evt); }
|
172
|
+
},
|
173
|
+
end: function (evt) {
|
174
|
+
if (!tapStartingCoords) { return; }
|
175
|
+
fns.cancel(evt);
|
176
|
+
evt.currentTarget = evt.currentTarget || evt.srcElement;
|
177
|
+
fn(evt);
|
178
|
+
},
|
179
|
+
noop: function () {},
|
180
|
+
cancel: function () {
|
181
|
+
if (!tapStartingCoords) { return; }
|
182
|
+
tapStartingCoords = null;
|
183
|
+
if (tapClass) { elem.classList.remove(tapClass); }
|
184
|
+
}
|
185
|
+
};
|
186
|
+
Gala.listen(window, Gala.CONTACT_CANCEL, fns.cancel);
|
187
|
+
return Gala.onContact(elem, fns, false, noopOnClick);
|
188
|
+
}
|
189
|
+
|
190
|
+
|
191
|
+
// Register a series of functions to listen for the start, move, end
|
192
|
+
// events of a mouse or touch interaction.
|
193
|
+
//
|
194
|
+
// 'fns' argument is an object like:
|
195
|
+
//
|
196
|
+
// {
|
197
|
+
// 'start': function () { ... },
|
198
|
+
// 'move': function () { ... },
|
199
|
+
// 'end': function () { ... },
|
200
|
+
// 'cancel': function () { ... }
|
201
|
+
// }
|
202
|
+
//
|
203
|
+
// All of the functions in this object are optional.
|
204
|
+
//
|
205
|
+
// Returns an object that can later be passed to Gala.deafenGroup.
|
206
|
+
//
|
207
|
+
Gala.onContact = function (elem, fns, useCapture, initCallback) {
|
208
|
+
elem = Gala.$(elem);
|
209
|
+
|
210
|
+
var isLeftClick = function (evt) {
|
211
|
+
return evt[typeof evt.which == 'undefined' ? 'button' : 'which'] < 2;
|
212
|
+
}
|
213
|
+
|
214
|
+
var isSingleTouch = function (evt) {
|
215
|
+
return !!(evt.touches && evt.touches.length < 2);
|
216
|
+
}
|
217
|
+
|
218
|
+
var wrapContact = function (fn) {
|
219
|
+
return function (evt) {
|
220
|
+
if (Gala.Pointers.enabled()) { Gala.Pointers.trackPointers(evt); }
|
221
|
+
var doCallFunc = (Gala.Pointers.isSinglePointer() ||
|
222
|
+
isSingleTouch(evt) ||
|
223
|
+
isLeftClick(evt));
|
224
|
+
if (doCallFunc) { fn(evt); }
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
var buildListeners = function (opts) {
|
229
|
+
var types = Gala.getEventTypes();
|
230
|
+
|
231
|
+
var listeners = {};
|
232
|
+
var evtTypes = ['start', 'move', 'end', 'cancel'];
|
233
|
+
for (var i = 0, ii = evtTypes.length; i < ii; ++i) {
|
234
|
+
var type = evtTypes[i];
|
235
|
+
if (opts[type]) {
|
236
|
+
var thisEvtTypes = types[type].split(' ');
|
237
|
+
for (var j = 0, jj = thisEvtTypes.length; j < jj; ++j) {
|
238
|
+
listeners[thisEvtTypes[j]] = wrapContact(opts[type]);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}
|
242
|
+
return listeners;
|
243
|
+
}
|
244
|
+
|
245
|
+
var listeners = buildListeners(fns);
|
246
|
+
|
247
|
+
Gala.listenGroup(elem, listeners);
|
248
|
+
if (typeof initCallback == 'function') { initCallback(listeners); }
|
249
|
+
return listeners;
|
250
|
+
}
|
251
|
+
|
252
|
+
// Support for pointer events
|
253
|
+
// http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx
|
254
|
+
// http://www.w3.org/Submission/pointer-events/
|
255
|
+
// Primary target of this functionality is windows 8, surface, etc
|
256
|
+
//
|
257
|
+
Gala.Pointers = {
|
258
|
+
pointers: {},
|
259
|
+
|
260
|
+
|
261
|
+
enabled: function () { return Gala.Pointers.ENV.pointer },
|
262
|
+
|
263
|
+
// Track pointer events
|
264
|
+
//
|
265
|
+
trackPointers: function (evt) {
|
266
|
+
var types = Gala.getEventTypes(),
|
267
|
+
endEvents = types.end.slice().concat(types.cancel);
|
268
|
+
|
269
|
+
// if we have an end event, I'm not sure it makes sense to only clear the
|
270
|
+
// single pointer that sent the end event. I think it makes sense to
|
271
|
+
// clear all pointers...I think it's kind of an edge case.
|
272
|
+
if (endEvents.indexOf(evt.type)) {
|
273
|
+
this.reset();
|
274
|
+
} else {
|
275
|
+
this.pointers[evt.pointerId] = evt;
|
276
|
+
}
|
277
|
+
},
|
278
|
+
|
279
|
+
|
280
|
+
// This follows the same logic as touches. To be valid, there
|
281
|
+
// is less than two.
|
282
|
+
//
|
283
|
+
isSinglePointer: function () {
|
284
|
+
return !!(this.enabled() && this.count() < 2);
|
285
|
+
},
|
286
|
+
|
287
|
+
|
288
|
+
// Get count of currently tracked pointers
|
289
|
+
//
|
290
|
+
count: function () {
|
291
|
+
// This method only exists in IE > 8 but that's ok because this code only
|
292
|
+
// applies to versions of IE > 8;
|
293
|
+
return Object.keys ? Object.keys(this.pointers).length : 0;
|
294
|
+
},
|
295
|
+
|
296
|
+
|
297
|
+
// Reset the pointers
|
298
|
+
//
|
299
|
+
reset: function () {
|
300
|
+
this.pointers = {};
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
304
|
+
Gala.Pointers.ENV = {
|
305
|
+
// Is the Pointer Events specification implemented?
|
306
|
+
// http://www.w3.org/Submission/pointer-events/
|
307
|
+
// Not sure how I feel about this spec but it makes sense to unify
|
308
|
+
// the events into a single interface to be used as needed. - DS
|
309
|
+
//
|
310
|
+
pointer: (function () {
|
311
|
+
return !!(navigator.pointerEnabled || navigator.msPointerEnabled)
|
312
|
+
})(),
|
313
|
+
|
314
|
+
|
315
|
+
// Does the system support a mouse
|
316
|
+
// This is required to identify touch devices that do not support
|
317
|
+
// a mouse interface. This is used because mouse events are still fired
|
318
|
+
// from mobile devices.
|
319
|
+
//
|
320
|
+
// This may need updated when Android desktops come out but hopefully
|
321
|
+
// everyone will just adopt the pointer spec.
|
322
|
+
//
|
323
|
+
noMouse: (function () {
|
324
|
+
var mobileRegex = /mobile|tablet|ip(ad|hone|od)|android|silk/i;
|
325
|
+
return (
|
326
|
+
('ontouchstart' in window) &&
|
327
|
+
!!navigator.userAgent.match(mobileRegex)
|
328
|
+
);
|
329
|
+
})()
|
330
|
+
}
|
331
|
+
|
332
|
+
// Get Event Types that are used to bind the different event concepts
|
333
|
+
// start, move, end, cancel. This method helps normalize event binding and
|
334
|
+
// prevent improper event listening, etc
|
335
|
+
//
|
336
|
+
Gala.getEventTypes = function () {
|
337
|
+
var types;
|
338
|
+
|
339
|
+
if (Gala.Pointers.enabled()) {
|
340
|
+
// Microsoft screwing stuff up with pointers
|
341
|
+
// http://www.w3.org/TR/pointerevents/
|
342
|
+
types = [
|
343
|
+
'pointerdown MSPointerDown',
|
344
|
+
'pointermove MSPointerMove',
|
345
|
+
'pointerup MSPointerUp',
|
346
|
+
'pointercancel MSPointerCancel'
|
347
|
+
];
|
348
|
+
} else if (Gala.Pointers.ENV.noMouse) {
|
349
|
+
types = [
|
350
|
+
'touchstart',
|
351
|
+
'touchmove',
|
352
|
+
'touchend',
|
353
|
+
'touchcancel'
|
354
|
+
];
|
355
|
+
} else {
|
356
|
+
types = [
|
357
|
+
'touchstart mousedown',
|
358
|
+
'touchmove mousemove',
|
359
|
+
'touchend mouseup',
|
360
|
+
'touchcancel'
|
361
|
+
];
|
362
|
+
}
|
363
|
+
|
364
|
+
return {
|
365
|
+
start: types[0],
|
366
|
+
move: types[1],
|
367
|
+
end: types[2],
|
368
|
+
cancel: types[3]
|
369
|
+
};
|
370
|
+
}
|
371
|
+
|
372
|
+
|
373
|
+
// The Gala.Cursor object provides more detail coordinates for the contact
|
374
|
+
// event, and normalizes differences between touch and mouse coordinates.
|
375
|
+
//
|
376
|
+
// If you have a contact event listener, you can get the coordinates for it
|
377
|
+
// with:
|
378
|
+
//
|
379
|
+
// var cursor = new Gala.Cursor(evt);
|
380
|
+
//
|
381
|
+
Gala.Cursor = function (evt) {
|
382
|
+
var API = { constructor: Gala.Cursor }
|
383
|
+
|
384
|
+
|
385
|
+
function initialize() {
|
386
|
+
var ci =
|
387
|
+
evt.type.match(/mouse|pointer/i) ? evt :
|
388
|
+
['touchstart', 'touchmove'].indexOf(evt.type) >= 0 ? evt.targetTouches[0] :
|
389
|
+
['touchend', 'touchcancel'].indexOf(evt.type) >= 0 ? evt.changedTouches[0] :
|
390
|
+
null;
|
391
|
+
|
392
|
+
// Basic coordinates (provided by the event).
|
393
|
+
API.pageX = ci.pageX;
|
394
|
+
API.pageY = ci.pageY;
|
395
|
+
API.clientX = ci.clientX;
|
396
|
+
API.clientY = ci.clientY;
|
397
|
+
API.screenX = ci.screenX;
|
398
|
+
API.screenY = ci.screenY;
|
399
|
+
API.event = evt;
|
400
|
+
|
401
|
+
// Coordinates relative to the target element for the event.
|
402
|
+
var tgt = API.target = evt.target || evt.srcElement;
|
403
|
+
while (tgt.nodeType != 1 && tgt.parentNode) { tgt = tgt.parentNode; }
|
404
|
+
assignOffsetFor(tgt, 'offset');
|
405
|
+
|
406
|
+
// Coordinates relative to the element that the event was registered on.
|
407
|
+
var registrant = evt.currentTarget;
|
408
|
+
if (registrant && typeof registrant.offsetLeft != 'undefined') {
|
409
|
+
assignOffsetFor(registrant, 'registrant');
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
413
|
+
|
414
|
+
function assignOffsetFor(elem, attr) {
|
415
|
+
var r;
|
416
|
+
if (elem.getBoundingClientRect) {
|
417
|
+
var er = elem.getBoundingClientRect();
|
418
|
+
var dr = document.documentElement.getBoundingClientRect();
|
419
|
+
r = { left: er.left - dr.left, top: er.top - dr.top }
|
420
|
+
} else {
|
421
|
+
r = { left: elem.offsetLeft, top: elem.offsetTop }
|
422
|
+
while (elem = elem.offsetParent) {
|
423
|
+
if (elem.offsetLeft || elem.offsetTop) {
|
424
|
+
r.left += elem.offsetLeft;
|
425
|
+
r.top += elem.offsetTop;
|
426
|
+
}
|
427
|
+
}
|
428
|
+
}
|
429
|
+
API[attr+'X'] = API.pageX - r.left;
|
430
|
+
API[attr+'Y'] = API.pageY - r.top;
|
431
|
+
}
|
432
|
+
|
433
|
+
|
434
|
+
initialize();
|
435
|
+
|
436
|
+
return API;
|
437
|
+
}
|
438
|
+
|
439
|
+
|
440
|
+
// A little utility to dereference ids into elements. You've seen this before.
|
441
|
+
//
|
442
|
+
Gala.$ = function (elem) {
|
443
|
+
if (typeof elem == 'string') { elem = document.getElementById(elem); }
|
444
|
+
return elem;
|
445
|
+
}
|
446
|
+
|
447
|
+
Gala.throttle = function (func, wait) {
|
448
|
+
var previous = 0;
|
449
|
+
|
450
|
+
return function () {
|
451
|
+
var now = new Date();
|
452
|
+
var remaining = wait - (now - previous);
|
453
|
+
if (remaining <= 0) {
|
454
|
+
previous = now;
|
455
|
+
func.apply(this, arguments);
|
456
|
+
}
|
457
|
+
}
|
458
|
+
}
|
459
|
+
|
460
|
+
|
461
|
+
|
462
|
+
|
463
|
+
// CONSTANTS
|
464
|
+
//
|
465
|
+
Gala.TAPPING_CLASS = 'tapping';
|
466
|
+
Gala.IE_REGISTRATIONS = {};
|
467
|
+
Gala.IE_INVOCATION_QUEUE = [];
|
468
|
+
Gala.CONTACT_CANCEL = "gala:contact:cancel";
|
469
|
+
Gala.TAP_MAX_CONTACT_DISTANCE = 10;
|