Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.

Commit 59d63a6

Browse files
committed
Make $apply calls safe
1 parent d84a811 commit 59d63a6

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/mask.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ angular.module('ui.mask', [])
4949
return tempOptions;
5050
}];
5151
})
52-
.directive('uiMask', ['uiMask.Config', function(maskConfig) {
52+
.directive('uiMask', ['uiMask.Config', '$timeout', function(maskConfig, $timeout) {
5353
function isFocused (elem) {
5454
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
5555
}
@@ -444,12 +444,14 @@ angular.module('ui.mask', [])
444444
if (!isValid || value.length === 0) {
445445
valueMasked = '';
446446
iElement.val('');
447-
scope.$apply(function() {
448-
//only $setViewValue when not $pristine to avoid changing $pristine state.
449-
if (!controller.$pristine) {
450-
controller.$setViewValue('');
451-
}
452-
});
447+
$timeout(function() {
448+
scope.$apply(function() {
449+
//only $setViewValue when not $pristine to avoid changing $pristine state.
450+
if (!controller.$pristine) {
451+
controller.$setViewValue('');
452+
}
453+
});
454+
}, 0, false);
453455
}
454456
}
455457
//Check for different value and trigger change.
@@ -597,9 +599,11 @@ angular.module('ui.mask', [])
597599
iElement.val(maskPlaceholder);
598600
// This shouldn't be needed but for some reason after aggressive backspacing the controller $viewValue is incorrect.
599601
// This keeps the $viewValue updated and correct.
600-
scope.$apply(function () {
601-
controller.$setViewValue(''); // $setViewValue should be run in angular context, otherwise the changes will be invisible to angular and user code.
602-
});
602+
$timeout(function() {
603+
scope.$apply(function () {
604+
controller.$setViewValue(''); // $setViewValue should be run in angular context, otherwise the changes will be invisible to angular and user code.
605+
});
606+
}, 0, false);
603607
setCaretPosition(this, caretPosOld);
604608
return;
605609
}
@@ -640,9 +644,11 @@ angular.module('ui.mask', [])
640644
//we need this check. What could happen if you don't have it is that you'll set the model value without the user
641645
//actually doing anything. Meaning, things like pristine and touched will be set.
642646
if (valAltered) {
643-
scope.$apply(function () {
644-
controller.$setViewValue(valMasked); // $setViewValue should be run in angular context, otherwise the changes will be invisible to angular and user code.
645-
});
647+
$timeout(function() {
648+
scope.$apply(function () {
649+
controller.$setViewValue(valMasked); // $setViewValue should be run in angular context, otherwise the changes will be invisible to angular and user code.
650+
});
651+
}, 0, false);
646652
}
647653

648654
// Caret Repositioning

test/maskSpec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ describe("uiMask", function () {
233233
input.triggerHandler("input");
234234
expect(input.data("$ngModelController").$error.required).toBe(true);
235235
input.val("(abc123_) _ _").triggerHandler("input");
236+
timeout.flush();
236237
expect(scope.x).toBe("ab1");
237238
expect(input.data("$ngModelController").$error.required).toBeUndefined();
238239
});
@@ -373,14 +374,17 @@ describe("uiMask", function () {
373374

374375
input.val("aa___").triggerHandler("input");
375376
input.triggerHandler("blur");
377+
timeout.flush();
376378
expect(input.val()).toBe("aa_");
377379

378380
input.val("99a___").triggerHandler("input");
379381
input.triggerHandler("blur");
382+
timeout.flush();
380383
expect(input.val()).toBe("99_");
381384

382385
input.val("992___").triggerHandler("input");
383386
input.triggerHandler("blur");
387+
timeout.flush();
384388
expect(input.val()).toBe("992");
385389
});
386390

@@ -642,6 +646,7 @@ describe("uiMask", function () {
642646
scope.$apply("mask = '@193'");
643647
input.val("f123____").triggerHandler("input");
644648
input.triggerHandler("blur");
649+
timeout.flush();
645650
expect(input.val()).toBe("f123");
646651
});
647652

@@ -659,6 +664,7 @@ describe("uiMask", function () {
659664
scope.$apply("mask = '@193Ab'");
660665
input.val("f123cCCc").triggerHandler("input");
661666
input.triggerHandler("blur");
667+
timeout.flush();
662668
expect(input.val()).toBe("f123Cc");
663669
});
664670

0 commit comments

Comments
 (0)