This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathprepare.coffee
70 lines (60 loc) · 2.8 KB
/
prepare.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# click:prepare event
#
# This event is psuedo click capture event that event works in
# browsers without DOM Level 3 events. The prepare event is always
# fired before any other click handlers are ran. Calling
# stopPropagation or returning false will prevent the other handlers.
#
# Eventually, if jQuery 2 moves to the standard event and dispatch
# model, all this can go away and we'll just use capture as intended.
if Zepto?
# All browsers that support Zepto have addEventListener, we can just
# use native capture here.
dispatchPrepare = (originalEvent) ->
event = document.createEvent 'Events'
event[k] = v for k, v of originalEvent
event.initEvent "#{originalEvent.type}:prepare", true, true
# Forward event calls back to originalEvent
combine = (f, g) -> -> f.apply originalEvent; g.apply event
event.preventDefault = combine originalEvent.preventDefault, event.preventDefault
event.stopPropagation = combine originalEvent.stopPropagation, event.stopPropagation
event.stopImmediatePropagation = combine originalEvent.stopImmediatePropagation, event.stopImmediatePropagation
originalEvent.target.dispatchEvent event
event.result
window.addEventListener 'click', dispatchPrepare, true
window.addEventListener 'submit', dispatchPrepare, true
else
# Keep track of last prepared event timestamp. It serves as a unique
# to check against in each events dispatch handler.
lastPreparedTimestamp = null
# preDispatch is a new hook added in 1.7.2. Its not documented as
# a real public API, but we'll abuse it anyway.
preDispatch = (event) ->
timestamp = "#{event.type}:" + event.timeStamp
# Check if this event has dispatched a prepare event already
if timestamp isnt lastPreparedTimestamp
# Reuse the existing event instead of creating a new copy. Any
# calls to preventDefault or stopPropagation will take
# immediate effect.
origType = event.type
event.type = "#{origType}:prepare"
$.event.trigger event, [], event.target, false
# Restore the old event type
event.type = origType
# Mark event's timestamp id as prepared
lastPreparedTimestamp = timestamp
return
# Install stub prepare handler to ensure preDispatch is invoked
setup = (event) -> ->
$(this).on "#{event}.prepare", ->
return
# Uninstall stub prepare handler to keep things tidy
teardown = (event) -> ->
$(this).off "#{event}.prepare", ->
return
# Install preDispatch handlers into click and submit
$.event.special.click = {preDispatch}
$.event.special.submit = {preDispatch}
# Install stub handlers when someone is listening to prepare events
$.event.special['click:prepare'] = setup: setup('click'), teardown: teardown('click')
$.event.special['submit:prepare'] = setup: setup('submit'), teardown: teardown('submit')