8
8
var Dispatcher = function ( editable ) {
9
9
var win = editable . win ;
10
10
eventable ( this , editable ) ;
11
+ this . supportsInputEvent = false ;
11
12
this . $document = $ ( win . document ) ;
12
13
this . config = editable . config ;
13
14
this . editable = editable ;
@@ -17,6 +18,10 @@ var Dispatcher = function(editable) {
17
18
this . setup ( ) ;
18
19
} ;
19
20
21
+ // This will be set to true once we detect the input event is working.
22
+ // Input event description on MDN:
23
+ // https://developer.mozilla.org/en-US/docs/Web/Reference/Events/input
24
+ var isInputEventSupported = false ;
20
25
21
26
/**
22
27
* Sets up all events that Editable.JS is catching.
@@ -61,12 +66,44 @@ Dispatcher.prototype.setupElementEvents = function() {
61
66
} ) . on ( 'cut.editable' , _this . editableSelector , function ( event ) {
62
67
log ( 'Cut' ) ;
63
68
_this . notify ( 'clipboard' , this , 'cut' , _this . selectionWatcher . getFreshSelection ( ) ) ;
69
+ _this . triggerChangeEvent ( this ) ;
64
70
} ) . on ( 'paste.editable' , _this . editableSelector , function ( event ) {
65
71
log ( 'Paste' ) ;
66
72
_this . notify ( 'clipboard' , this , 'paste' , _this . selectionWatcher . getFreshSelection ( ) ) ;
73
+ _this . triggerChangeEvent ( this ) ;
74
+ } ) . on ( 'input.editable' , _this . editableSelector , function ( event ) {
75
+ log ( 'Input' ) ;
76
+ if ( isInputEventSupported ) {
77
+ _this . notify ( 'change' , this ) ;
78
+ } else {
79
+ // Most likely the event was already handled manually by
80
+ // triggerChangeEvent so the first time we just switch the
81
+ // isInputEventSupported flag without notifiying the change event.
82
+ isInputEventSupported = true ;
83
+ }
67
84
} ) ;
68
85
} ;
69
86
87
+ /**
88
+ * Trigger a change event
89
+ *
90
+ * This should be done in these cases:
91
+ * - typing a letter
92
+ * - delete (backspace and delete keys)
93
+ * - cut
94
+ * - paste
95
+ * - copy and paste (not easily possible manually as far as I know)
96
+ *
97
+ * Preferrably this is done using the input event. But the input event is not
98
+ * supported on all browsers for contenteditable elements.
99
+ * To make things worse it is not detectable either. So instead of detecting
100
+ * we set 'isInputEventSupported' when the input event fires the first time.
101
+ */
102
+ Dispatcher . prototype . triggerChangeEvent = function ( target ) {
103
+ if ( isInputEventSupported ) return ;
104
+ this . notify ( 'change' , target ) ;
105
+ } ;
106
+
70
107
Dispatcher . prototype . dispatchSwitchEvent = function ( event , element , direction ) {
71
108
var cursor ;
72
109
if ( event . altKey || event . ctrlKey || event . metaKey || event . shiftKey )
@@ -99,7 +136,8 @@ Dispatcher.prototype.setupKeyboardEvents = function() {
99
136
var _this = this ;
100
137
101
138
this . $document . on ( 'keydown.editable' , this . editableSelector , function ( event ) {
102
- _this . keyboard . dispatchKeyEvent ( event , this ) ;
139
+ var notifyCharacterEvent = ! isInputEventSupported ;
140
+ _this . keyboard . dispatchKeyEvent ( event , this , notifyCharacterEvent ) ;
103
141
} ) ;
104
142
105
143
this . keyboard . on ( 'left' , function ( event ) {
@@ -130,7 +168,11 @@ Dispatcher.prototype.setupKeyboardEvents = function() {
130
168
event . preventDefault ( ) ;
131
169
event . stopPropagation ( ) ;
132
170
_this . notify ( 'merge' , this , 'before' , cursor ) ;
171
+ } else {
172
+ _this . triggerChangeEvent ( this ) ;
133
173
}
174
+ } else {
175
+ _this . triggerChangeEvent ( this ) ;
134
176
}
135
177
} ) . on ( 'delete' , function ( event ) {
136
178
log ( 'Delete key pressed' ) ;
@@ -142,7 +184,11 @@ Dispatcher.prototype.setupKeyboardEvents = function() {
142
184
event . preventDefault ( ) ;
143
185
event . stopPropagation ( ) ;
144
186
_this . notify ( 'merge' , this , 'after' , cursor ) ;
187
+ } else {
188
+ _this . triggerChangeEvent ( this ) ;
145
189
}
190
+ } else {
191
+ _this . triggerChangeEvent ( this ) ;
146
192
}
147
193
} ) . on ( 'enter' , function ( event ) {
148
194
log ( 'Enter key pressed' ) ;
@@ -165,6 +211,8 @@ Dispatcher.prototype.setupKeyboardEvents = function() {
165
211
event . stopPropagation ( ) ;
166
212
var cursor = _this . selectionWatcher . forceCursor ( ) ;
167
213
_this . notify ( 'newline' , this , cursor ) ;
214
+ } ) . on ( 'character' , function ( event ) {
215
+ _this . notify ( 'change' , this ) ;
168
216
} ) ;
169
217
} ;
170
218
0 commit comments