-
Notifications
You must be signed in to change notification settings - Fork 374
/
pause.js
169 lines (147 loc) · 4.23 KB
/
pause.js
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
steal('jquery/event/default').then(function($){
var current,
rnamespaces = /\.(.*)$/,
returnFalse = function(){return false},
returnTrue = function(){return true};
/**
* @function
* @parent jquery.event.pause
* Pauses an event (to be resumed later);
*/
//
/**
* @function
* @parent jquery.event.pause
*
* Resumes an event
*/
//
/**
* @page jquery.event.pause Pause-Resume
* @plugin jquery/event/pause
* @parent specialevents
* The jquery/event/pause plugin adds the ability to pause and
* resume events.
*
* $('#todos').bind('show', function(ev){
* ev.pause();
*
* $(this).load('todos.html', function(){
* ev.resume();
* });
* })
*
* When an event is paused, stops calling other event handlers for the
* event (similar to event.stopImmediatePropagation() ). But when
* resume is called on the event, it will begin calling events on event handlers
* after the 'paused' event handler.
*
*
* Pause-able events complement the [jQuery.event.special.default default]
* events plugin, providing the ability to easy create widgets with
* an asynchronous API.
*
* ## Example
*
* Consider a basic tabs widget that:
*
* - trigger's a __show__ event on panels when they are to be displayed
* - shows the panel after the show event.
*
* The sudo code for this controller might look like:
*
* $.Controller('Tabs',{
* ".button click" : function( el ){
* var panel = this.getPanelFromButton( el );
* panel.triggerAsync('show', function(){
* panel.show();
* })
* }
* })
*
* Someone using this plugin would be able to delay the panel showing until ready:
*
* $('#todos').bind('show', function(ev){
* ev.pause();
*
* $(this).load('todos.html', function(){
* ev.resume();
* });
* })
*
* Or prevent the panel from showing at all:
*
* $('#todos').bind('show', function(ev){
* if(! isReady()){
* ev.preventDefault();
* }
* })
*
* ## Limitations
*
* The element and event handler that the <code>pause</code> is within can not be removed before
* resume is called.
*
* ## Big Example
*
* The following example shows a tabs widget where the user is prompted to save, ignore, or keep editing
* a tab when a new tab is clicked.
*
* @demo jquery/event/pause/pause.html
*
* It's a long, but great example of how to do some pretty complex state management with JavaScriptMVC.
*
*/
$.Event.prototype.isPaused = returnFalse
$.Event.prototype.pause = function(){
// stop the event from continuing temporarily
// keep the current state of the event ...
this.pausedState = {
isDefaultPrevented : this.isDefaultPrevented() ?
returnTrue : returnFalse,
isPropagationStopped : this.isPropagationStopped() ?
returnTrue : returnFalse
};
this.stopImmediatePropagation();
this.preventDefault();
this.isPaused = returnTrue;
};
$.Event.prototype.resume = function(){
// temporarily remove all event handlers of this type
var handleObj = this.handleObj,
currentTarget = this.currentTarget;
// temporarily overwrite special handle
var origType = jQuery.event.special[ handleObj.origType ],
origHandle = origType && origType.handle;
if(!origType){
jQuery.event.special[ handleObj.origType ] = {};
}
jQuery.event.special[ handleObj.origType ].handle = function(ev){
// remove this once we have passed the handleObj
if(ev.handleObj === handleObj && ev.currentTarget === currentTarget){
if(!origType){
delete jQuery.event.special[ handleObj.origType ];
} else {
jQuery.event.special[ handleObj.origType ].handle = origHandle;
}
}
}
delete this.pausedState;
// reset stuff
this.isPaused = this.isImmediatePropagationStopped = returnFalse;
// re-run dispatch
//$.event.dispatch.call(currentTarget, this)
// with the events removed, dispatch
if(!this.isPropagationStopped()){
// fire the event again, no events will get fired until
// same currentTarget / handler
$.event.trigger(this, [], this.target);
}
};
/*var oldDispatch = $.event.dispatch;
$.event.dispatch = function(){
}*/
// we need to finish handling
// and then trigger on next element ...
// can we fake the target ?
});