Skip to content

Commit

Permalink
fix(ngEventDirs): blur and focus use $evalAysnc to prevent inprog errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Narretz committed Mar 29, 2014
1 parent 876df04 commit a8a6126
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
30 changes: 28 additions & 2 deletions src/ng/directive/ngEventDirs.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@
</example>
*/
/*
* A directive that allows creation of custom onclick handlers that are defined as angular
* A directive that allows creation of custom event handlers that are defined as angular
* expressions and are compiled and executed within the current scope.
*
* Events that are handled via these handler are always configured not to propagate further.
*/
var ngEventDirectives = {};
forEach(
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit copy cut paste'.split(' '),
function(name) {
var directiveName = directiveNormalize('ng-' + name);
ngEventDirectives[directiveName] = ['$parse', function($parse) {
Expand All @@ -58,6 +58,32 @@ forEach(
}
);

/*
* Focus and blur need to use $evalAsync to prevent $rootScope.inprog errors caused by other event directives triggering
* focus() and blur() respectively
*
*/
forEach(
'focus blur'.split(' '),
function(name) {
var directiveName = directiveNormalize('ng-' + name);
ngEventDirectives[directiveName] = ['$parse', function($parse) {
return {
compile: function($element, attr) {
var fn = $parse(attr[directiveName]);
return function(scope, element, attr) {
element.on(lowercase(name), function(event) {
scope.$evalAsync(function() {
fn(scope, {$event:event});
});
});
};
}
};
}];
}
);

/**
* @ngdoc directive
* @name ngDblclick
Expand Down
34 changes: 34 additions & 0 deletions test/ng/directive/ngEventDirsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,38 @@ describe('event directives', function() {
expect($rootScope.formSubmitted).toEqual('foo');
}));
});

describe('ngBlur', function() {
iit('should get called when ngKeydown triggers blur', inject(function($rootScope, $compile) {
$rootScope.blur = function() {
browserTrigger(element, 'blur');
}

element = $compile('<input type="text" ng-blur="blurred = true" ng-keydown="blur()" />')($rootScope);

$rootScope.$digest();
expect($rootScope.blurred).not.toBeDefined();

browserTrigger(element, 'keydown');
expect($rootScope.blurred).toEqual(true);
}));
});

describe('ngFocus', function() {
iit('should get called when ngClick triggers focus', inject(function($rootScope, $compile) {
$rootScope.focus = function() {
browserTrigger(element.children()[0], 'focus');
}

element = $compile('<div><input type="text" ng-focus="focused = true" />' +
'<button type="button" ng-click="focus()"></button></div>')($rootScope);

$rootScope.$digest();
expect($rootScope.focused).not.toBeDefined();

browserTrigger(element.children()[1], 'click');
expect($rootScope.focused).toEqual(true);
}));
});

});

0 comments on commit a8a6126

Please sign in to comment.