Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
base repository: angular/angular.js
Choose a Base Repository
angular/angular.js
Anuj16/angular.js
ArslanRafique/angular.js
DeborahK/angular.js
EpokK/angular.js
HaoWu/angular.js
IgorMinar/angular.js
JKLFA/angular.js
KAUG/angular.js
Kaic-zz/angular.js
Metric7/angular.js
MikhailTatsky/angular.js
NAzT/angular.js
Narretz/angular.js
Partoo/angular.js
PeterBoesenberg/angular.js
PoshHsu/angular.js
ScxFiction/angular.js
SeanMBe/angular.js
Sharique-Hasan/angular.js
Shipow/angular.js
SjB/angular.js
Sophrinix/angular.js
SumitMunot/angular.js
TEHEK/angular.js
abhisec/angular.js
abnerlinan/angular.js
abrons/angular.js
acosme/angular.js
adam-singer/angular.js
addyosmani/angular.js
agborkowski/angular.js
ajperrins/angular.js
alexeagle/angular.js
alxross/angular.js
aminerahmouni/angular.js
amirhhz/angular.js
angeliaz/angular.js
angularjs-jp/angular.js
anjo/angular.js
arantius/angular.js
ardnet2/angular.js
arsh-co/angular.js
bartes/angular.js
bghanchi/angular.js
blinkbox/angular.js
blueslue/angular.js
boltz/angular.js
bolu/angular.js
briceburg/angular.js
brikou/angular.js
btford/angular.js
byplayer/angular.js
ca136/angular.js
calvinhuang/angular.js
cburgdorf/angular.js
chenermeng/angular.js
chris4403/angular.js
cleyshan/angular.js
codeinpeace/angular.js
colinfrei/angular.js
congmo/angular.js
crossbreeze/angular.js
csii/angular.js
cssgist/angular.js
danielfacanha/angular.js
danilopesouza/angular.js
dankrz/angular.js
dashersw/angular.js
dbinit/angular.js
dcu/angular.js
dhl/angular.js
dineshkummarc/angular.js
dolfly/angular.js
dydycloud/angular.js
eburley/angular.js
elfgoh/angular.js
esprehn/angular.js
fergaldoyle/angular.js
fingerskier/angular.js
flamilton/angular.js
fran6co/angular.js
freewind/angular.js
gaboom/angular.js
gijs/angular.js
girikudlur/angular.js
groner/angular.js
gruber76/angular.js
gwoo/angular.js
hackreactor/angular.js
hardikdangar/angular.js
hjoest/angular.js
hkdobrev/angular.js
hoatle/angular.js
huangciyin/angular.js
huangweili/angular.js
huncent/angular.js
hwclass/angular.js
iammerrick/angular.js
ifedotov/angular.js
imaizumi8925/angular.js
imiborbas/angular.js
intelline/angular.js
jajberni/angular.js
jc1arke/angular.js
jeanielight/angular.js
jecons/angular.js
jimrenwick/angular.js
jjp/angular.js
johnlindquist/angular.js
joshkurz/angular.js
jromero75/angular.js
jsonxu/angular.js
kevan/angular.js
kevinelong/angular.js
kinglerzou/angular.js
kkurni/angular.js
kliu/angular.js
kotiya/angular.js
kyuff/angular.js
lamperwang/angular.js
leeight/angular.js
lobsang/angular.js
lrlopez/angular.js
lt1946/angular.js
ludicast/angular.js
lzlf007/angular.js
m13z/angular.js
maciejblinkbox/angular.js
mailtruck/angular.js
manuel-woelker/angular.js
mdolk/angular.js
mernen/angular.js
mgechev/angular.js
mhevery/angular.js
msgilligan/angular.js
nateabele/angular.js
nateflink/angular.js
neolf/angular.js
patcito/angular.js
pdswan/angular.js
petebacondarwin/angular.js
petrovalex/angular.js
phillipkregg/angular.js
phoo/angular.js
pmurias/angular.js
premblinkbox/angular.js
quangv/angular.js
rafa2000/angular.js
rafaalves/angular.js
rahu28/angular.js
recht/angular.js
redg1974/angular.js
ricardohbin/angular.js
rtnpro/angular.js
ruimonteiro84/angular.js
rulers/angular.js
rwaldron/angular.js
sahilmalik5/angular.js
sangam12345/angular.js
santosomar/angular.js
scuxiayiqian/angular.js
shuvozula/angular.js
shyblower/angular-ie7.js
sjhernes/angular.js
snicolai/angular.js
steinjak/angular.js
stephanebisson/angular.js
stevenp-git/angular.js
sum4me/angular.js
suneil/angular.js
supercool27/angular.js
superman-wrdh/angular.js
thegerr09/angular.js
thenyel/angular.js
thughes/angular.js
timothyx/angular.js
timthesinner/angular.js
tleruitte/angular.js
tobyreynold/angular.js
tonitt/angular.js
trochette/angular.js
unirgy/angular.js
vibster/angular.js
vincentferniot/angular.js
vingo/angular.js
virtualSharif/angular.js
vkoroslev/angular.js
vojtajina/angular.js
witkai/angular.js
woodie/angular.js
wuxq/angular.js
xiehekun/angular.js
xrchen/angular.js
yanneves/angular.js
ysiadf/angular.js
yyx990803/angular.js
zfleet/angular.js
zhangruimin/angular.js
ziakina/angular.js
Nothing to show
base: 620a20d1b337
head repository: angular/angular.js
Choose a Head Repository
angular/angular.js
Anuj16/angular.js
ArslanRafique/angular.js
DeborahK/angular.js
EpokK/angular.js
HaoWu/angular.js
IgorMinar/angular.js
JKLFA/angular.js
KAUG/angular.js
Kaic-zz/angular.js
Metric7/angular.js
MikhailTatsky/angular.js
NAzT/angular.js
Narretz/angular.js
Partoo/angular.js
PeterBoesenberg/angular.js
PoshHsu/angular.js
ScxFiction/angular.js
SeanMBe/angular.js
Sharique-Hasan/angular.js
Shipow/angular.js
SjB/angular.js
Sophrinix/angular.js
SumitMunot/angular.js
TEHEK/angular.js
abhisec/angular.js
abnerlinan/angular.js
abrons/angular.js
acosme/angular.js
adam-singer/angular.js
addyosmani/angular.js
agborkowski/angular.js
ajperrins/angular.js
alexeagle/angular.js
alxross/angular.js
aminerahmouni/angular.js
amirhhz/angular.js
angeliaz/angular.js
angularjs-jp/angular.js
anjo/angular.js
arantius/angular.js
ardnet2/angular.js
arsh-co/angular.js
bartes/angular.js
bghanchi/angular.js
blinkbox/angular.js
blueslue/angular.js
boltz/angular.js
bolu/angular.js
briceburg/angular.js
brikou/angular.js
btford/angular.js
byplayer/angular.js
ca136/angular.js
calvinhuang/angular.js
cburgdorf/angular.js
chenermeng/angular.js
chris4403/angular.js
cleyshan/angular.js
codeinpeace/angular.js
colinfrei/angular.js
congmo/angular.js
crossbreeze/angular.js
csii/angular.js
cssgist/angular.js
danielfacanha/angular.js
danilopesouza/angular.js
dankrz/angular.js
dashersw/angular.js
dbinit/angular.js
dcu/angular.js
dhl/angular.js
dineshkummarc/angular.js
dolfly/angular.js
dydycloud/angular.js
eburley/angular.js
elfgoh/angular.js
esprehn/angular.js
fergaldoyle/angular.js
fingerskier/angular.js
flamilton/angular.js
fran6co/angular.js
freewind/angular.js
gaboom/angular.js
gijs/angular.js
girikudlur/angular.js
groner/angular.js
gruber76/angular.js
gwoo/angular.js
hackreactor/angular.js
hardikdangar/angular.js
hjoest/angular.js
hkdobrev/angular.js
hoatle/angular.js
huangciyin/angular.js
huangweili/angular.js
huncent/angular.js
hwclass/angular.js
iammerrick/angular.js
ifedotov/angular.js
imaizumi8925/angular.js
imiborbas/angular.js
intelline/angular.js
jajberni/angular.js
jc1arke/angular.js
jeanielight/angular.js
jecons/angular.js
jimrenwick/angular.js
jjp/angular.js
johnlindquist/angular.js
joshkurz/angular.js
jromero75/angular.js
jsonxu/angular.js
kevan/angular.js
kevinelong/angular.js
kinglerzou/angular.js
kkurni/angular.js
kliu/angular.js
kotiya/angular.js
kyuff/angular.js
lamperwang/angular.js
leeight/angular.js
lobsang/angular.js
lrlopez/angular.js
lt1946/angular.js
ludicast/angular.js
lzlf007/angular.js
m13z/angular.js
maciejblinkbox/angular.js
mailtruck/angular.js
manuel-woelker/angular.js
mdolk/angular.js
mernen/angular.js
mgechev/angular.js
mhevery/angular.js
msgilligan/angular.js
nateabele/angular.js
nateflink/angular.js
neolf/angular.js
patcito/angular.js
pdswan/angular.js
petebacondarwin/angular.js
petrovalex/angular.js
phillipkregg/angular.js
phoo/angular.js
pmurias/angular.js
premblinkbox/angular.js
quangv/angular.js
rafa2000/angular.js
rafaalves/angular.js
rahu28/angular.js
recht/angular.js
redg1974/angular.js
ricardohbin/angular.js
rtnpro/angular.js
ruimonteiro84/angular.js
rulers/angular.js
rwaldron/angular.js
sahilmalik5/angular.js
sangam12345/angular.js
santosomar/angular.js
scuxiayiqian/angular.js
shuvozula/angular.js
shyblower/angular-ie7.js
sjhernes/angular.js
snicolai/angular.js
steinjak/angular.js
stephanebisson/angular.js
stevenp-git/angular.js
sum4me/angular.js
suneil/angular.js
supercool27/angular.js
superman-wrdh/angular.js
thegerr09/angular.js
thenyel/angular.js
thughes/angular.js
timothyx/angular.js
timthesinner/angular.js
tleruitte/angular.js
tobyreynold/angular.js
tonitt/angular.js
trochette/angular.js
unirgy/angular.js
vibster/angular.js
vincentferniot/angular.js
vingo/angular.js
virtualSharif/angular.js
vkoroslev/angular.js
vojtajina/angular.js
witkai/angular.js
woodie/angular.js
wuxq/angular.js
xiehekun/angular.js
xrchen/angular.js
yanneves/angular.js
ysiadf/angular.js
yyx990803/angular.js
zfleet/angular.js
zhangruimin/angular.js
ziakina/angular.js
Nothing to show
compare: bf35d53855d0
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 2 contributors
Commits on Jan 06, 2016
…imation

This allows follow-up animations to remove a class that is currently
being added.

Fixes #13339
Fixes #13380
Closes #13414
Closes #13472
Closes #13678
Showing with 153 additions and 59 deletions.
  1. +78 −55 src/ng/directive/validators.js
  2. +36 −4 src/ngAnimate/animateQueue.js
  3. +39 −0 test/ngAnimate/integrationSpec.js
@@ -6,7 +6,7 @@
* @description
*
* ngRequired adds the required {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
* It is most often used for [@link input `input`} and {@link select `select`} controls, but can also be
* It is most often used for {@link input `input`} and {@link select `select`} controls, but can also be
* applied to custom controls.
*
* The directive sets the `required` attribute on the element if the Angular expression inside
@@ -43,16 +43,17 @@
* </div>
* </file>
* <file name="protractor.js" type="protractor">
* var required = element(by.binding('form.input.$error.required'));
* var model = element(by.binding('model'));
*
* it('should set the required error', function() {
* expect(required.getText()).toContain('true');
*
* element(by.id('input')).sendKeys('123');
* expect(required.getText()).not.toContain('true');
* expect(model.getText()).toContain('123');
* });
var required = element(by.binding('form.input.$error.required'));
var model = element(by.binding('model'));
var input = element(by.id('input'));
it('should set the required error', function() {
expect(required.getText()).toContain('true');
input.sendKeys('123');
expect(required.getText()).not.toContain('true');
expect(model.getText()).toContain('123');
});
* </file>
* </example>
*/
@@ -82,14 +83,14 @@ var requiredDirective = function() {
* @description
*
* ngPattern adds the pattern {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
* It is most often used for text-based [@link input `input`} controls, but can also be applied to custom text-based controls.
* It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
*
* The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
* does not match a RegExp which is obtained by evaluating the Angular expression given in the
* `ngPattern` attribute value:
* * If the expression evaluates to a RegExp object, then this is used directly.
* * If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it
* in `^` and `$` characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
* The validator sets the `pattern` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
* does not match a RegExp which is obtained by evaluating the Angular expression given in the
* `ngPattern` attribute value:
* * If the expression evaluates to a RegExp object, then this is used directly.
* * If the expression evaluates to a string, then it will be converted to a RegExp after wrapping it
* in `^` and `$` characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
*
* <div class="alert alert-info">
* **Note:** Avoid using the `g` flag on the RegExp, as it will cause each successive search to
@@ -100,9 +101,16 @@ var requiredDirective = function() {
* <div class="alert alert-info">
* **Note:** This directive is also added when the plain `pattern` attribute is used, with two
* differences:
* 1. `ngPattern` does not set the `pattern` attribute and therefore not HTML5 constraint validation
* is available.
* 2. The `ngPattern` attribute must be an expression, while the `pattern` value must be interpolated
* <ol>
* <li>
* `ngPattern` does not set the `pattern` attribute and therefore HTML5 constraint validation is
* not available.
* </li>
* <li>
* The `ngPattern` attribute must be an expression, while the `pattern` value must be
* interpolated.
* </li>
* </ol>
* </div>
*
* @example
@@ -128,18 +136,18 @@ var requiredDirective = function() {
* </div>
* </file>
* <file name="protractor.js" type="protractor">
var model = element(by.binding('model'));
var input = element(by.id('input'));
var model = element(by.binding('model'));
var input = element(by.id('input'));
it('should validate the input with the default pattern', function() {
input.sendKeys('aaa');
expect(model.getText()).not.toContain('aaa');
it('should validate the input with the default pattern', function() {
input.sendKeys('aaa');
expect(model.getText()).not.toContain('aaa');
input.clear().then(function() {
input.sendKeys('123');
expect(model.getText()).toContain('123');
});
});
input.clear().then(function() {
input.sendKeys('123');
expect(model.getText()).toContain('123');
});
});
* </file>
* </example>
*/
@@ -181,18 +189,25 @@ var patternDirective = function() {
* @description
*
* ngMaxlength adds the maxlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
* It is most often used for text-based [@link input `input`} controls, but can also be applied to custom text-based controls.
* It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
*
* The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
* is longer than the integer obtained by evaluating the Angular expression given in the
* `ngMaxlength` attribute value.
* The validator sets the `maxlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
* is longer than the integer obtained by evaluating the Angular expression given in the
* `ngMaxlength` attribute value.
*
* <div class="alert alert-info">
* **Note:** This directive is also added when the plain `maxlength` attribute is used, with two
* differences:
* 1. `ngMaxlength` does not set the `maxlength` attribute and therefore not HTML5 constraint validation
* is available.
* 2. The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be interpolated
* <ol>
* <li>
* `ngMaxlength` does not set the `maxlength` attribute and therefore HTML5 constraint
* validation is not available.
* </li>
* <li>
* The `ngMaxlength` attribute must be an expression, while the `maxlength` value must be
* interpolated.
* </li>
* </ol>
* </div>
*
* @example
@@ -218,7 +233,7 @@ var patternDirective = function() {
* </div>
* </file>
* <file name="protractor.js" type="protractor">
* var model = element(by.binding('model'));
var model = element(by.binding('model'));
var input = element(by.id('input'));
it('should validate the input with the default maxlength', function() {
@@ -260,18 +275,25 @@ var maxlengthDirective = function() {
* @description
*
* ngMinlength adds the minlength {@link ngModel.NgModelController#$validators `validator`} to {@link ngModel `ngModel`}.
* It is most often used for text-based [@link input `input`} controls, but can also be applied to custom text-based controls.
* It is most often used for text-based {@link input `input`} controls, but can also be applied to custom text-based controls.
*
* The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
* is shorter than the integer obtained by evaluating the Angular expression given in the
* `ngMinlength` attribute value.
* The validator sets the `minlength` error key if the {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`}
* is shorter than the integer obtained by evaluating the Angular expression given in the
* `ngMinlength` attribute value.
*
* <div class="alert alert-info">
* **Note:** This directive is also added when the plain `minlength` attribute is used, with two
* differences:
* 1. `ngMinlength` does not set the `minlength` attribute and therefore not HTML5 constraint validation
* is available.
* 2. The `ngMinlength` value must be an expression, while the `minlength` value must be interpolated
* <ol>
* <li>
* `ngMinlength` does not set the `minlength` attribute and therefore HTML5 constraint
* validation is not available.
* </li>
* <li>
* The `ngMinlength` value must be an expression, while the `minlength` value must be
* interpolated.
* </li>
* </ol>
* </div>
*
* @example
@@ -297,15 +319,16 @@ var maxlengthDirective = function() {
* </div>
* </file>
* <file name="protractor.js" type="protractor">
* var model = element(by.binding('model'));
*
* it('should validate the input with the default minlength', function() {
* element(by.id('input')).sendKeys('ab');
* expect(model.getText()).not.toContain('ab');
*
* element(by.id('input')).sendKeys('abc');
* expect(model.getText()).toContain('abc');
* });
var model = element(by.binding('model'));
var input = element(by.id('input'));
it('should validate the input with the default minlength', function() {
input.sendKeys('ab');
expect(model.getText()).not.toContain('ab');
input.sendKeys('abc');
expect(model.getText()).toContain('abc');
});
* </file>
* </example>
*/
@@ -5,13 +5,37 @@ var NG_ANIMATE_PIN_DATA = '$ngAnimatePin';
var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
var PRE_DIGEST_STATE = 1;
var RUNNING_STATE = 2;
var ONE_SPACE = ' ';

var rules = this.rules = {
skip: [],
cancel: [],
join: []
};

function makeTruthyCssClassMap(classString) {
if (!classString) {
return null;
}

var keys = classString.split(ONE_SPACE);
var map = Object.create(null);

forEach(keys, function(key) {
map[key] = true;
});
return map;
}

function hasMatchingClasses(newClassString, currentClassString) {
if (newClassString && currentClassString) {
var currentClassMap = makeTruthyCssClassMap(currentClassString);
return newClassString.split(ONE_SPACE).some(function(className) {
return currentClassMap[className];
});
}
}

function isAllowed(ruleType, element, currentAnimation, previousAnimation) {
return rules[ruleType].some(function(fn) {
return fn(element, currentAnimation, previousAnimation);
@@ -59,11 +83,19 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
});

rules.cancel.push(function(element, newAnimation, currentAnimation) {
var nO = newAnimation.options;
var cO = currentAnimation.options;

// if the exact same CSS class is added/removed then it's safe to cancel it
return (nO.addClass && nO.addClass === cO.removeClass) || (nO.removeClass && nO.removeClass === cO.addClass);

var nA = newAnimation.options.addClass;
var nR = newAnimation.options.removeClass;
var cA = currentAnimation.options.addClass;
var cR = currentAnimation.options.removeClass;

// early detection to save the global CPU shortage :)
if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) {
return false;
}

return (hasMatchingClasses(nA, cR)) || (hasMatchingClasses(nR, cA));
});

this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
@@ -351,6 +351,45 @@ describe('ngAnimate integration tests', function() {

dealoc(element);
}));


it("should remove a class when the same class is currently being added by a joined class-based animation",
inject(function($animate, $animateCss, $rootScope, $document, $rootElement, $$rAF) {

ss.addRule('.hide', 'opacity: 0');
ss.addRule('.hide-add, .hide-remove', 'transition: 1s linear all');

jqLite($document[0].body).append($rootElement);
element = jqLite('<div></div>');
$rootElement.append(element);

// These animations will be joined together
$animate.addClass(element, 'red');
$animate.addClass(element, 'hide');
$rootScope.$digest();

expect(element).toHaveClass('red-add');
expect(element).toHaveClass('hide-add');

// When a digest has passed, but no $rAF has been issued yet, .hide hasn't been added to
// the element yet
$animate.removeClass(element, 'hide');
$rootScope.$digest();
$$rAF.flush();

expect(element).not.toHaveClass('hide-add hide-add-active');
expect(element).toHaveClass('hide-remove hide-remove-active');

//End the animation process
browserTrigger(element, 'transitionend',
{ timeStamp: Date.now() + 1000, elapsedTime: 2 });
$animate.flush();

expect(element).not.toHaveClass('hide-add-active red-add-active');
expect(element).toHaveClass('red');
expect(element).not.toHaveClass('hide');
}));

});

describe('JS animations', function() {

No commit comments for this range

You can’t perform that action at this time.