Skip to content

Commit cbdcc69

Browse files
committed
Merge remote-tracking branch 'next/master'
2 parents b5d9141 + b06478e commit cbdcc69

10 files changed

+156
-69
lines changed

.gitignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
node_modules
2+
!node_modules/mocha/mocha.css
3+
!node_modules/mocha/mocha.js
4+
!node_modules/mocha/LICENCE
5+
!node_modules/chai/chai.js
6+
!node_modules/chai-LICENCE
7+
web-animations-*.min.js
8+
web-animations-*.min.js.map
9+
web-animations.min.js
10+
web-animations.min.js.map
11+
inter-*
12+
*~
13+
sauce_connect.log
14+
test.html

History.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
### 2.2.1 - *April 28 2016*
2+
* [Deprecated invalid timing inputs](https://github.com/web-animations/web-animations-next/pull/437) as they will soon throw [TypeErrors](https://github.com/web-animations/web-animations-next/pull/426) in native browsers.
3+
4+
For example, this is deprecated and will eventually throw a TypeError:
5+
6+
element.animate([], {
7+
duration: -1,
8+
iterationStart: -1,
9+
iterations: -1,
10+
easing: 'garbage string',
11+
});
12+
13+
* [Fixed polyfill crash in browsers based on Chromium 36 to 46.](https://github.com/web-animations/web-animations-next/pull/434)
14+
15+
* [Increased cubic-bezier accuracy.](https://github.com/web-animations/web-animations-next/pull/428)
16+
17+
* [Added support for grad and turn units for angles.](https://github.com/web-animations/web-animations-next/pull/427)
18+
119
### 2.2.0 - *April 6 2016*
220
* Deprecated the use of hyphens in property names.
321

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"type": "git",
66
"url": "https://github.com/web-animations/web-animations-js.git"
77
},
8-
"version": "2.2.0",
8+
"version": "2.2.1",
99
"keywords": [
1010
"animations",
1111
"polyfill"

src/deprecation.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
var silenced = {};
1818

1919
shared.isDeprecated = function(feature, date, advice, plural) {
20+
if (WEB_ANIMATIONS_TESTING) {
21+
return true;
22+
}
23+
2024
var auxVerb = plural ? 'are' : 'is';
2125
var today = new Date();
2226
var expiry = new Date(date);

src/matrix-decomposition.js

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -253,29 +253,32 @@
253253
];
254254
}
255255

256+
function toRadians(arg) {
257+
var rads = arg.rad || 0;
258+
var degs = arg.deg || 0;
259+
var grads = arg.grad || 0;
260+
var turns = arg.turn || 0;
261+
var angle = (degs / 360 + grads / 400 + turns) * (2 * Math.PI) + rads;
262+
return angle;
263+
}
264+
256265
function convertItemToMatrix(item) {
257266
switch (item.t) {
258267
case 'rotatex':
259-
var rads = item.d[0].rad || 0;
260-
var degs = item.d[0].deg || 0;
261-
var angle = (degs * Math.PI / 180) + rads;
268+
var angle = toRadians(item.d[0]);
262269
return [1, 0, 0, 0,
263270
0, Math.cos(angle), Math.sin(angle), 0,
264271
0, -Math.sin(angle), Math.cos(angle), 0,
265272
0, 0, 0, 1];
266273
case 'rotatey':
267-
var rads = item.d[0].rad || 0;
268-
var degs = item.d[0].deg || 0;
269-
var angle = (degs * Math.PI / 180) + rads;
274+
var angle = toRadians(item.d[0]);
270275
return [Math.cos(angle), 0, -Math.sin(angle), 0,
271276
0, 1, 0, 0,
272277
Math.sin(angle), 0, Math.cos(angle), 0,
273278
0, 0, 0, 1];
274279
case 'rotate':
275280
case 'rotatez':
276-
var rads = item.d[0].rad || 0;
277-
var degs = item.d[0].deg || 0;
278-
var angle = (degs * Math.PI / 180) + rads;
281+
var angle = toRadians(item.d[0]);
279282
return [Math.cos(angle), Math.sin(angle), 0, 0,
280283
-Math.sin(angle), Math.cos(angle), 0, 0,
281284
0, 0, 1, 0,
@@ -284,9 +287,7 @@
284287
var x = item.d[0];
285288
var y = item.d[1];
286289
var z = item.d[2];
287-
var rads = item.d[3].rad || 0;
288-
var degs = item.d[3].deg || 0;
289-
var angle = (degs * Math.PI / 180) + rads;
290+
var angle = toRadians(item.d[3]);
290291

291292
var sqrLength = x * x + y * y + z * z;
292293
if (sqrLength === 0) {
@@ -347,28 +348,20 @@
347348
0, 0, item.d[2], 0,
348349
0, 0, 0, 1];
349350
case 'skew':
350-
var xDegs = item.d[0].deg || 0;
351-
var xRads = item.d[0].rad || 0;
352-
var yDegs = item.d[1].deg || 0;
353-
var yRads = item.d[1].rad || 0;
354-
var xAngle = (xDegs * Math.PI / 180) + xRads;
355-
var yAngle = (yDegs * Math.PI / 180) + yRads;
351+
var xAngle = toRadians(item.d[0]);
352+
var yAngle = toRadians(item.d[1]);
356353
return [1, Math.tan(yAngle), 0, 0,
357354
Math.tan(xAngle), 1, 0, 0,
358355
0, 0, 1, 0,
359356
0, 0, 0, 1];
360357
case 'skewx':
361-
var rads = item.d[0].rad || 0;
362-
var degs = item.d[0].deg || 0;
363-
var angle = (degs * Math.PI / 180) + rads;
358+
var angle = toRadians(item.d[0]);
364359
return [1, 0, 0, 0,
365360
Math.tan(angle), 1, 0, 0,
366361
0, 0, 1, 0,
367362
0, 0, 0, 1];
368363
case 'skewy':
369-
var rads = item.d[0].rad || 0;
370-
var degs = item.d[0].deg || 0;
371-
var angle = (degs * Math.PI / 180) + rads;
364+
var angle = toRadians(item.d[0]);
372365
return [1, Math.tan(angle), 0, 0,
373366
0, 1, 0, 0,
374367
0, 0, 1, 0,

src/timing-utilities.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
var fills = 'backwards|forwards|both|none'.split('|');
1818
var directions = 'reverse|alternate|alternate-reverse'.split('|');
19+
var linear = function(x) { return x; };
1920

2021
function cloneTimingInput(timingInput) {
2122
if (typeof timingInput == 'number') {
@@ -38,14 +39,19 @@
3839
this._playbackRate = 1;
3940
this._direction = 'normal';
4041
this._easing = 'linear';
42+
this._easingFunction = linear;
43+
}
44+
45+
function isInvalidTimingDeprecated() {
46+
return shared.isDeprecated('Invalid timing inputs', '2016-03-02', 'TypeError exceptions will be thrown instead.', true);
4147
}
4248

4349
AnimationEffectTiming.prototype = {
4450
_setMember: function(member, value) {
4551
this['_' + member] = value;
4652
if (this._effect) {
4753
this._effect._timingInput[member] = value;
48-
this._effect._timing = shared.normalizeTimingInput(shared.normalizeTimingInput(this._effect._timingInput));
54+
this._effect._timing = shared.normalizeTimingInput(this._effect._timingInput);
4955
this._effect.activeDuration = shared.calculateActiveDuration(this._effect._timing);
5056
if (this._effect._animation) {
5157
this._effect._animation._rebuildUnderlyingAnimation();
@@ -74,12 +80,18 @@
7480
return this._fill;
7581
},
7682
set iterationStart(value) {
83+
if ((isNaN(value) || value < 0) && isInvalidTimingDeprecated()) {
84+
throw new TypeError('iterationStart must be a non-negative number, received: ' + timing.iterationStart);
85+
}
7786
this._setMember('iterationStart', value);
7887
},
7988
get iterationStart() {
8089
return this._iterationStart;
8190
},
8291
set duration(value) {
92+
if (value != 'auto' && (isNaN(value) || value < 0) && isInvalidTimingDeprecated()) {
93+
throw new TypeError('duration must be non-negative or auto, received: ' + value);
94+
}
8395
this._setMember('duration', value);
8496
},
8597
get duration() {
@@ -92,12 +104,16 @@
92104
return this._direction;
93105
},
94106
set easing(value) {
107+
this._easingFunction = toTimingFunction(value);
95108
this._setMember('easing', value);
96109
},
97110
get easing() {
98111
return this._easing;
99112
},
100113
set iterations(value) {
114+
if ((isNaN(value) || value < 0) && isInvalidTimingDeprecated()) {
115+
throw new TypeError('iterations must be non-negative, received: ' + value);
116+
}
101117
this._setMember('iterations', value);
102118
},
103119
get iterations() {
@@ -150,9 +166,7 @@
150166

151167
function normalizeTimingInput(timingInput, forGroup) {
152168
timingInput = shared.numericTimingToObject(timingInput);
153-
var timing = makeTiming(timingInput, forGroup);
154-
timing._easingFunction = toTimingFunction(timing.easing);
155-
return timing;
169+
return makeTiming(timingInput, forGroup);
156170
}
157171

158172
function cubic(a, b, c, d) {
@@ -168,7 +182,7 @@
168182
var mid = (start + end) / 2;
169183
function f(a, b, m) { return 3 * a * (1 - m) * (1 - m) * m + 3 * b * (1 - m) * m * m + m * m * m};
170184
var xEst = f(a, c, mid);
171-
if (Math.abs(x - xEst) < 0.001) {
185+
if (Math.abs(x - xEst) < 0.0001) {
172186
return f(b, d, mid);
173187
}
174188
if (xEst < x) {
@@ -209,25 +223,28 @@
209223
var numberString = '\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*';
210224
var cubicBezierRe = new RegExp('cubic-bezier\\(' + numberString + ',' + numberString + ',' + numberString + ',' + numberString + '\\)');
211225
var stepRe = /steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;
212-
var linear = function(x) { return x; };
213226

214227
function toTimingFunction(easing) {
215228
if (!styleForCleaning) {
216229
styleForCleaning = document.createElement('div').style;
217230
}
218231
styleForCleaning.animationTimingFunction = '';
219232
styleForCleaning.animationTimingFunction = easing;
220-
easing = styleForCleaning.animationTimingFunction;
233+
var validatedEasing = styleForCleaning.animationTimingFunction;
234+
235+
if (validatedEasing == '' && isInvalidTimingDeprecated()) {
236+
throw new TypeError(easing + ' is not a valid value for easing');
237+
}
221238

222-
var cubicData = cubicBezierRe.exec(easing);
239+
var cubicData = cubicBezierRe.exec(validatedEasing);
223240
if (cubicData) {
224241
return cubic.apply(this, cubicData.slice(1).map(Number));
225242
}
226-
var stepData = stepRe.exec(easing);
243+
var stepData = stepRe.exec(validatedEasing);
227244
if (stepData) {
228245
return step(Number(stepData[1]), {'start': Start, 'middle': Middle, 'end': End}[stepData[2]]);
229246
}
230-
var preset = presets[easing];
247+
var preset = presets[validatedEasing];
231248
if (preset) {
232249
return preset;
233250
}

src/web-animations-bonus-object-form-keyframes.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,36 @@
1313
// limitations under the License.
1414

1515
(function(shared) {
16-
// If an animation with the new syntax applies an effect, there's no need
17-
// to load this part of the polyfill.
16+
// If the polyfill is being loaded in a context where Element.animate is
17+
// supported but object-form syntax is not, then creating an animation
18+
// using the new syntax will either have no effect or will throw an exception.
19+
// In either case, we want to proceed to load this part of the polyfill.
20+
//
21+
// The test animation uses an opacity other than the one the element already
22+
// has, and doesn't need to change during the animation for the test to work.
23+
// After the test, the element's opacity will be left how we found it:
24+
// - If the animation is not created, the test will leave the element's
25+
// opacity untouched at originalOpacity.
26+
// - If the animation is created, it will be cancelled, and leave the
27+
// element's opacity at originalOpacity.
28+
// - If the animation is somehow created and runs without being cancelled,
29+
// when it finishes after 1ms, it will cease to have any effect (because
30+
// fill is not specified), and opacity will again be left at originalOpacity.
1831
var element = document.documentElement;
19-
var animation = element.animate({'opacity': ['1', '0']},
20-
{duration: 1, fill: 'forwards'});
21-
animation.finish();
22-
var animated = getComputedStyle(element).getPropertyValue('opacity') == '0';
23-
animation.cancel();
32+
var animation = null;
33+
var animated = false;
34+
try {
35+
var originalOpacity = getComputedStyle(element).getPropertyValue('opacity');
36+
var testOpacity = originalOpacity == '0' ? '1' : '0';
37+
animation = element.animate({'opacity': [testOpacity, testOpacity]},
38+
{duration: 1});
39+
animation.currentTime = 0;
40+
animated = getComputedStyle(element).getPropertyValue('opacity') == testOpacity;
41+
} catch (error) {
42+
} finally {
43+
if (animation)
44+
animation.cancel();
45+
}
2446
if (animated) {
2547
return;
2648
}

test/js/keyframes.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,16 +442,13 @@ suite('keyframes', function() {
442442
assert.equal(typeof interpolations[1].interpolation, 'function');
443443
});
444444

445-
test('Make interpolations with invalid easing.', function() {
446-
var interpolations;
447-
assert.doesNotThrow(function() {
448-
interpolations = makeInterpolations(makePropertySpecificKeyframeGroups(normalizeKeyframes([
445+
test('Make interpolations with invalid easing should throw.', function() {
446+
assert.throws(function() {
447+
makeInterpolations(makePropertySpecificKeyframeGroups(normalizeKeyframes([
449448
{left: '0px', easing: 'pants and ducks'},
450449
{left: '200px'},
451450
])));
452451
});
453-
assert.equal(interpolations.length, 1);
454-
assert.equal(interpolations[0].easing.toString(), 'function (x) { return x; }');
455452
});
456453
});
457454

test/js/matrix-interpolation.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,42 +407,42 @@ suite('matrix interpolation', function() {
407407
test('decompose various CSS properties with unsupported units', function() {
408408
compareInterpolatedTransforms(
409409
['rotateX(110grad)', 'rotateX(10deg) matrix(1, 0, 0, 1, 0, 0)'],
410-
['rotateX(0deg)', 'rotateX(10deg) matrix(1, 0, 0, 1, 0, 0)'],
410+
['rotateX(99deg)', 'rotateX(10deg) matrix(1, 0, 0, 1, 0, 0)'],
411411
0.5);
412412

413413
compareInterpolatedTransforms(
414414
['rotateY(2turn)', 'rotateY(2rad) matrix(1, 0, 0, 1, 0, 0)'],
415-
['rotateY(0rad)', 'rotateY(2rad) matrix(1, 0, 0, 1, 0, 0)'],
415+
['rotateY(12.56637rad)', 'rotateY(2rad) matrix(1, 0, 0, 1, 0, 0)'],
416416
0.5);
417417

418418
compareInterpolatedTransforms(
419419
['rotate(320deg)', 'rotateY(10grad) matrix(1, 0, 0, 1, 0, 0)'],
420-
['rotate(320deg)', 'rotateY(0deg) matrix(1, 0, 0, 1, 0, 0)'],
420+
['rotate(320deg)', 'rotateY(9deg) matrix(1, 0, 0, 1, 0, 0)'],
421421
0.5);
422422

423423
compareInterpolatedTransforms(
424424
['rotateZ(10grad)', 'rotateZ(2rad) matrix(1, 0, 0, 1, 0, 0)'],
425-
['rotateZ(0rad)', 'rotateZ(2rad) matrix(1, 0, 0, 1, 0, 0)'],
425+
['rotateZ(0.157rad)', 'rotateZ(2rad) matrix(1, 0, 0, 1, 0, 0)'],
426426
0.5);
427427

428428
compareInterpolatedTransforms(
429429
['rotate3d(1, 1, 1, 100deg)', 'rotate3d(1, 1, 1, 2turn) matrix(1, 0, 0, 1, 0, 0)'],
430-
['rotate3d(1, 1, 1, 100deg)', 'rotate3d(1, 1, 1, 0deg) matrix(1, 0, 0, 1, 0, 0)'],
430+
['rotate3d(1, 1, 1, 100deg)', 'rotate3d(1, 1, 1, 720deg) matrix(1, 0, 0, 1, 0, 0)'],
431431
0.5);
432432

433433
compareInterpolatedTransforms(
434434
['skew(30grad)', 'skew(10deg) matrix(1, 0, 0, 1, 0, 0)'],
435-
['skew(0deg)', 'skew(10deg) matrix(1, 0, 0, 1, 0, 0)'],
435+
['skew(27deg)', 'skew(10deg) matrix(1, 0, 0, 1, 0, 0)'],
436436
0.5);
437437

438438
compareInterpolatedTransforms(
439439
['skewx(3grad)', 'skewx(1rad) matrix(1, 0, 0, 1, 0, 0)'],
440-
['skewx(0rad)', 'skewx(1rad) matrix(1, 0, 0, 1, 0, 0)'],
440+
['skewx(0.04712rad)', 'skewx(1rad) matrix(1, 0, 0, 1, 0, 0)'],
441441
0.5);
442442

443443
compareInterpolatedTransforms(
444444
['skewy(3rad)', 'skewy(1grad) matrix(1, 0, 0, 1, 0, 0)'],
445-
['skewy(3rad)', 'skewy(0rad) matrix(1, 0, 0, 1, 0, 0)'],
445+
['skewy(3rad)', 'skewy(0.0157rad) matrix(1, 0, 0, 1, 0, 0)'],
446446
0.5);
447447

448448
compareInterpolatedTransforms(

0 commit comments

Comments
 (0)