@@ -89,18 +89,63 @@ angular.module('ui.ace', [])
8989 */
9090 var onChangeListener ;
9191
92+ /**
93+ * Reference to a blur listener created by the listener factory.
94+ * @function
95+ * @see listenerFactory.onBlur
96+ */
97+ var onBlurListener ;
98+
99+ /**
100+ * Calls a callback by checking its existing. The argument list
101+ * is variable and thus this function is relying on the arguments
102+ * object.
103+ * @throws {Error } If the callback isn't a function
104+ */
105+ var executeUserCallback = function ( ) {
106+
107+ /**
108+ * The callback function grabbed from the array-like arguments
109+ * object. The first argument should always be the callback.
110+ *
111+ * @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
112+ * @type {* }
113+ */
114+ var callback = arguments [ 0 ] ;
115+
116+ /**
117+ * Arguments to be passed to the callback. These are taken
118+ * from the array-like arguments object. The first argument
119+ * is stripped because that should be the callback function.
120+ *
121+ * @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
122+ * @type {Array }
123+ */
124+ var args = Array . prototype . slice . call ( arguments , 1 ) ;
125+
126+ if ( angular . isDefined ( callback ) ) {
127+ scope . $apply ( function ( ) {
128+ if ( angular . isFunction ( callback ) ) {
129+ callback ( args ) ;
130+ } else {
131+ throw new Error ( 'ui-ace use a function as callback.' ) ;
132+ }
133+ } ) ;
134+ }
135+ }
136+
92137 /**
93138 * Listener factory. Until now only change listeners can be created.
94139 * @type object
95140 */
96141 var listenerFactory = {
97142 /**
98143 * Creates a change listener which propagates the change event
99- * to the callback from the user option onChange. It might be
100- * exchanged during runtime, if this happens the old listener
101- * will be unbound.
144+ * and the editor session to the callback from the user option
145+ * onChange. It might be exchanged during runtime, if this
146+ * happens the old listener will be unbound.
102147 *
103- * @param callback callback function taken from the
148+ * @param callback callback function defined in the user options
104149 * @see onChangeListener
105150 */
106151 onChange : function ( callback ) {
@@ -112,21 +157,23 @@ angular.module('ui.ace', [])
112157 ngModel . $setViewValue ( newValue ) ;
113158 } ) ;
114159 }
115-
116- /**
117- * Call the user onChange function.
118- */
119- if ( angular . isDefined ( callback ) ) {
120- scope . $apply ( function ( ) {
121- if ( angular . isFunction ( callback ) ) {
122- callback ( e , acee ) ;
123- } else {
124- throw new Error ( 'ui-ace use a function as callback.' ) ;
125- }
126- } ) ;
127- }
160+ executeUserCallback ( callback , e , acee ) ;
128161 }
129162 } ;
163+ } ,
164+ /**
165+ * Creates a blur listener which propagates the editor session
166+ * to the callback from the user option onBlur. It might be
167+ * exchanged during runtime, if this happens the old listener
168+ * will be unbound.
169+ *
170+ * @param callback callback function defined in the user options
171+ * @see onBlurListener
172+ */
173+ onBlur : function ( callback ) {
174+ return function ( ) {
175+ executeUserCallback ( callback , acee ) ;
176+ }
130177 }
131178 } ;
132179
@@ -159,20 +206,31 @@ angular.module('ui.ace', [])
159206 scope . $watch ( attrs . uiAce , function ( ) {
160207 opts = angular . extend ( { } , options , scope . $eval ( attrs . uiAce ) ) ;
161208
162- // unbind old listener
209+ // unbind old change listener
163210 session . removeListener ( 'change' , onChangeListener ) ;
164211
165- // bind new listener
212+ // bind new change listener
166213 onChangeListener = listenerFactory . onChange ( opts . onChange ) ;
167214 session . on ( 'change' , onChangeListener ) ;
168215
216+ // unbind old blur listener
217+ //session.removeListener('blur', onBlurListener);
218+ acee . removeListener ( 'blur' , onBlurListener ) ;
219+
220+ // bind new blur listener
221+ onBlurListener = listenerFactory . onBlur ( opts . onBlur ) ;
222+ acee . on ( 'blur' , onBlurListener ) ;
223+
169224 setOptions ( acee , session , opts ) ;
170225 } , /* deep watch */ true ) ;
171226
172227 // EVENTS
173228 onChangeListener = listenerFactory . onChange ( opts . onChange ) ;
174229 session . on ( 'change' , onChangeListener ) ;
175230
231+ onBlurListener = listenerFactory . onBlur ( opts . onBlur ) ;
232+ acee . on ( 'blur' , onBlurListener ) ;
233+
176234 elm . on ( '$destroy' , function ( ) {
177235 acee . session . $stopWorker ( ) ;
178236 acee . destroy ( ) ;
0 commit comments