Skip to content

Commit 232186b

Browse files
authoredJul 20, 2017
Merge pull request #156 from ewilligers/master
Publish version 2.3.0
2 parents b0ca1f7 + c037b10 commit 232186b

20 files changed

+2623
-953
lines changed
 

‎CONTRIBUTING.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ is the default target for pull requests.
2020
1. Commit changes to your fork.
2121
1. Create a pull request from your fork of web-animations-js to
2222
[web-animations/web-animations-js/dev](https://github.com/web-animations/web-animations-js/tree/dev).
23+
1. Ensure that you've signed the [Google Contributor License Agreement](https://cla.developers.google.com/clas).
2324

2425

2526
## Debugging tests
@@ -83,7 +84,7 @@ Example: `http://localhost:9876/base/test/web-platform-tests/web-animations/anim
8384
npm install
8485
grunt
8586
# Optional "grunt test" to make sure everything still passes.
86-
git add -f *.min.js*
87+
git add -f *.min.js{,.map}
8788
git rm .gitignore
8889
git commit -m 'Add build artifacts from '`cat .git/refs/heads/dev`
8990
git push HEAD:refs/heads/master

‎Gruntfile.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ module.exports = function(grunt) {
206206
}
207207

208208
function filterTests(testFiles) {
209+
console.assert(testFiles.length > 0);
209210
if (!testFilter) {
210211
return testFiles;
211212
}
@@ -226,18 +227,20 @@ module.exports = function(grunt) {
226227
karmaConfig.files = ['test/karma-mocha-setup.js'].concat(config.src, testFiles);
227228
});
228229
}
229-
function runWebPlatformTests() {
230+
function runWebPlatformTests(withNativeFallback) {
230231
var testFiles = filterTests(grunt.file.expand(config.webPlatformTests));
231232
if (testFiles.length == 0) {
232233
return Promise.resolve(true);
233234
}
234235

235-
console.info('Running web-platform-tests/web-animations tests...');
236+
var withOrWithout = withNativeFallback ? 'with' : 'without';
237+
console.info('Running web-platform-tests/web-animations tests for target ' + task.target + ' ' + withOrWithout + ' native fallback...');
236238
return runKarma(function(karmaConfig) {
237239
configCallback(karmaConfig);
238240
karmaConfig.client.testharnessTests = require('./test/web-platform-tests-expectations.js');
239241
karmaConfig.client.testharnessTests.testURLList = testFiles;
240-
karmaConfig.proxies['/base/polyfill.js'] = '/base/' + task.target + '.min.js';
242+
karmaConfig.client.testharnessTests.target = task.target;
243+
karmaConfig.client.testharnessTests.withNativeFallback = withNativeFallback;
241244
karmaConfig.files.push('test/karma-testharness-adapter.js');
242245
var servedFiles = [
243246
'test/web-platform-tests/resources/**',
@@ -256,10 +259,15 @@ module.exports = function(grunt) {
256259
}
257260

258261
var polyfillTestsPassed = false;
262+
var webPlatformTestsWithFallbackPassed = false;
263+
var webPlatformTestsWithoutFallbackPassed = false;
259264
runPolyfillTests().then(success => {
260265
polyfillTestsPassed = success;
261-
}).then(runWebPlatformTests).then(webPlatformTestsPassed => {
262-
done(polyfillTestsPassed && webPlatformTestsPassed);
266+
}).then(() => runWebPlatformTests(true)).then(success => {
267+
webPlatformTestsWithFallbackPassed = success;
268+
}).then(() => runWebPlatformTests(false)).then(success => {
269+
webPlatformTestsWithoutFallbackPassed = success;
270+
done(polyfillTestsPassed && webPlatformTestsWithFallbackPassed && webPlatformTestsWithoutFallbackPassed);
263271
}).catch(function(error) {
264272
console.error(error);
265273
done(false);

‎History.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
### 2.3.0 - *July 20 2017*
2+
3+
* [Support IE/Edge SVG transforms.](https://github.com/web-animations/web-animations-js/pull/148)
4+
5+
* [Parse and evaluate calc expressions without eval.](https://github.com/web-animations/web-animations-js/pull/151)
6+
17
### 2.2.5 - *April 17 2017*
28

39
* Removed erroneously added *.gz files from release.

‎package.json

+1-1
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.5",
8+
"version": "2.3.0",
99
"keywords": [
1010
"animations",
1111
"polyfill"

‎src/apply-preserving-inline-style.js

+49-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@
1414

1515
(function(scope, testing) {
1616

17+
var SVG_TRANSFORM_PROP = '_webAnimationsUpdateSvgTransformAttr';
18+
19+
/**
20+
* IE/Edge do not support `transform` styles for SVG elements. Instead,
21+
* `transform` attribute can be animated with some restrictions.
22+
* See https://connect.microsoft.com/IE/feedback/details/811744/ie11-bug-with-implementation-of-css-transforms-in-svg,
23+
* https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/1173754/,
24+
* https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/101242/, etc.
25+
* The same problem is exhibited by pre-Chrome Android browsers (ICS).
26+
* Unfortunately, there's no easy way to feature-detect it.
27+
*/
28+
function updateSvgTransformAttr(window, element) {
29+
if (!element.namespaceURI || element.namespaceURI.indexOf('/svg') == -1) {
30+
return false;
31+
}
32+
if (!(SVG_TRANSFORM_PROP in window)) {
33+
window[SVG_TRANSFORM_PROP] =
34+
/Trident|MSIE|IEMobile|Edge|Android 4/i.test(window.navigator.userAgent);
35+
}
36+
return window[SVG_TRANSFORM_PROP];
37+
}
38+
1739
var styleAttributes = {
1840
cssText: 1,
1941
length: 1,
@@ -44,13 +66,16 @@
4466
WEB_ANIMATIONS_TESTING && console.assert(!(element.style instanceof AnimatedCSSStyleDeclaration),
4567
'Element must not already have an animated style attached.');
4668

69+
this._element = element;
4770
// Stores the inline style of the element on its behalf while the
4871
// polyfill uses the element's inline style to simulate web animations.
4972
// This is needed to fake regular inline style CSSOM access on the element.
5073
this._surrogateStyle = document.createElementNS('http://www.w3.org/1999/xhtml', 'div').style;
5174
this._style = element.style;
5275
this._length = 0;
5376
this._isAnimatedProperty = {};
77+
this._updateSvgTransformAttr = updateSvgTransformAttr(window, element);
78+
this._savedTransformAttr = null;
5479

5580
// Copy the inline style contents over to the surrogate.
5681
for (var i = 0; i < this._style.length; i++) {
@@ -110,9 +135,30 @@
110135
_set: function(property, value) {
111136
this._style[property] = value;
112137
this._isAnimatedProperty[property] = true;
138+
if (this._updateSvgTransformAttr &&
139+
scope.unprefixedPropertyName(property) == 'transform') {
140+
// On IE/Edge, also set SVG element's `transform` attribute to 2d
141+
// matrix of the transform. The `transform` style does not work, but
142+
// `transform` attribute can be used instead.
143+
// Notice, if the platform indeed supports SVG/CSS transforms the CSS
144+
// declaration is supposed to override the attribute.
145+
if (this._savedTransformAttr == null) {
146+
this._savedTransformAttr = this._element.getAttribute('transform');
147+
}
148+
this._element.setAttribute('transform', scope.transformToSvgMatrix(value));
149+
}
113150
},
114151
_clear: function(property) {
115152
this._style[property] = this._surrogateStyle[property];
153+
if (this._updateSvgTransformAttr &&
154+
scope.unprefixedPropertyName(property) == 'transform') {
155+
if (this._savedTransformAttr) {
156+
this._element.setAttribute('transform', this._savedTransformAttr);
157+
} else {
158+
this._element.removeAttribute('transform');
159+
}
160+
this._savedTransformAttr = null;
161+
}
116162
delete this._isAnimatedProperty[property];
117163
},
118164
};
@@ -185,7 +231,9 @@
185231
}
186232
};
187233

188-
if (WEB_ANIMATIONS_TESTING)
234+
if (WEB_ANIMATIONS_TESTING) {
189235
testing.ensureStyleIsPatched = ensureStyleIsPatched;
236+
testing.updateSvgTransformAttr = updateSvgTransformAttr;
237+
}
190238

191239
})(webAnimations1, webAnimationsTesting);

‎src/dimension-handler.js

+74-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,78 @@
1414

1515
(function(scope, testing) {
1616

17+
// Evaluates a calc expression.
18+
// https://drafts.csswg.org/css-values-3/#calc-notation
19+
function calculate(expression) {
20+
// In calc expressions, white space is required on both sides of the
21+
// + and - operators. https://drafts.csswg.org/css-values-3/#calc-notation
22+
// Thus any + or - immediately adjacent to . or 0..9 is part of the number,
23+
// e.g. -1.23e+45
24+
// This regular expression matches ( ) * / + - and numbers.
25+
var tokenRegularExpression = /([\+\-\w\.]+|[\(\)\*\/])/g;
26+
var currentToken;
27+
function consume() {
28+
var matchResult = tokenRegularExpression.exec(expression);
29+
if (matchResult)
30+
currentToken = matchResult[0];
31+
else
32+
currentToken = undefined;
33+
}
34+
consume(); // Read the initial token.
35+
36+
function calcNumber() {
37+
// https://drafts.csswg.org/css-values-3/#number-value
38+
var result = Number(currentToken);
39+
consume();
40+
return result;
41+
}
42+
43+
function calcValue() {
44+
// <calc-value> = <number> | <dimension> | <percentage> | ( <calc-sum> )
45+
if (currentToken !== '(')
46+
return calcNumber();
47+
consume();
48+
var result = calcSum();
49+
if (currentToken !== ')')
50+
return NaN;
51+
consume();
52+
return result;
53+
}
54+
55+
function calcProduct() {
56+
// <calc-product> = <calc-value> [ '*' <calc-value> | '/' <calc-number-value> ]*
57+
var left = calcValue();
58+
while (currentToken === '*' || currentToken === '/') {
59+
var operator = currentToken;
60+
consume();
61+
var right = calcValue();
62+
if (operator === '*')
63+
left *= right;
64+
else
65+
left /= right;
66+
}
67+
return left;
68+
}
69+
70+
function calcSum() {
71+
// <calc-sum> = <calc-product> [ [ '+' | '-' ] <calc-product> ]*
72+
var left = calcProduct();
73+
while (currentToken === '+' || currentToken === '-') {
74+
var operator = currentToken;
75+
consume();
76+
var right = calcProduct();
77+
if (operator === '+')
78+
left += right;
79+
else
80+
left -= right;
81+
}
82+
return left;
83+
}
84+
85+
// <calc()> = calc( <calc-sum> )
86+
return calcSum();
87+
}
88+
1789
function parseDimension(unitRegExp, string) {
1890
string = string.trim().toLowerCase();
1991

@@ -36,7 +108,7 @@
36108
var taggedUnitRegExp = 'U(' + unitRegExp.source + ')';
37109

38110
// Validating input is simply applying as many reductions as we can.
39-
var typeCheck = string.replace(/[-+]?(\d*\.)?\d+/g, 'N')
111+
var typeCheck = string.replace(/[-+]?(\d*\.)?\d+([Ee][-+]?\d+)?/g, 'N')
40112
.replace(new RegExp('N' + taggedUnitRegExp, 'g'), 'D')
41113
.replace(/\s[+-]\s/g, 'O')
42114
.replace(/\s/g, '');
@@ -54,7 +126,7 @@
54126
return;
55127

56128
for (var unit in matchedUnits) {
57-
var result = eval(string.replace(new RegExp('U' + unit, 'g'), '').replace(new RegExp(taggedUnitRegExp, 'g'), '*0'));
129+
var result = calculate(string.replace(new RegExp('U' + unit, 'g'), '').replace(new RegExp(taggedUnitRegExp, 'g'), '*0'));
58130
if (!isFinite(result))
59131
return;
60132
matchedUnits[unit] = result;

‎src/matrix-decomposition.js

+1
Original file line numberDiff line numberDiff line change
@@ -435,5 +435,6 @@
435435

436436
scope.dot = dot;
437437
scope.makeMatrixDecomposition = makeMatrixDecomposition;
438+
scope.transformListToMatrix = convertToMatrix;
438439

439440
})(webAnimations1, webAnimationsTesting);

‎src/property-names.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414

1515
(function(scope, testing) {
1616

17-
var aliased = {};
17+
var prefixed = {};
18+
var unprefixed = {};
1819

1920
function alias(name, aliases) {
2021
aliases.concat([name]).forEach(function(candidate) {
2122
if (candidate in document.documentElement.style) {
22-
aliased[name] = candidate;
23+
prefixed[name] = candidate;
2324
}
25+
unprefixed[candidate] = name;
2426
});
2527
}
2628
alias('transform', ['webkitTransform', 'msTransform']);
@@ -29,7 +31,10 @@
2931
alias('perspectiveOrigin', ['webkitPerspectiveOrigin']);
3032

3133
scope.propertyName = function(property) {
32-
return aliased[property] || property;
34+
return prefixed[property] || property;
35+
};
36+
scope.unprefixedPropertyName = function(property) {
37+
return unprefixed[property] || property;
3338
};
3439

3540
})(webAnimations1, webAnimationsTesting);

‎src/transform-handler.js

+13
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,19 @@
256256

257257
scope.addPropertiesHandler(parseTransform, mergeTransforms, ['transform']);
258258

259+
scope.transformToSvgMatrix = function(string) {
260+
// matrix(<a> <b> <c> <d> <e> <f>)
261+
var mat = scope.transformListToMatrix(parseTransform(string));
262+
return 'matrix(' +
263+
numberToLongString(mat[0]) + ' ' + // <a>
264+
numberToLongString(mat[1]) + ' ' + // <b>
265+
numberToLongString(mat[4]) + ' ' + // <c>
266+
numberToLongString(mat[5]) + ' ' + // <d>
267+
numberToLongString(mat[12]) + ' ' + // <e>
268+
numberToLongString(mat[13]) + // <f>
269+
')';
270+
};
271+
259272
if (WEB_ANIMATIONS_TESTING)
260273
testing.parseTransform = parseTransform;
261274

‎test/js/apply-preserving-inline-style.js

+121
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ suite('apply-preserving-inline-style', function() {
44
ensureStyleIsPatched(this.element);
55
this.style = this.element.style;
66
document.documentElement.appendChild(this.element);
7+
this.svgContainer = document.createElementNS(
8+
'http://www.w3.org/2000/svg', 'svg');
9+
document.documentElement.appendChild(this.svgContainer);
10+
delete window._webAnimationsUpdateSvgTransformAttr;
711
});
812
teardown(function() {
913
document.documentElement.removeChild(this.element);
14+
document.documentElement.removeChild(this.svgContainer);
15+
delete window._webAnimationsUpdateSvgTransformAttr;
1016
});
1117

1218
test('Style is patched', function() {
@@ -69,4 +75,119 @@ suite('apply-preserving-inline-style', function() {
6975
this.style.cssText = 'top: 0px';
7076
assert.equal(this.style.length, 1);
7177
});
78+
test('Detect SVG transform compatibility', function() {
79+
var element = document.createElement('div');
80+
var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
81+
function check(userAgent, shouldUpdateSvgTransformAttr) {
82+
var win = {navigator: {userAgent: userAgent}};
83+
// Non-SVG element is never updated.
84+
assert.equal(updateSvgTransformAttr(win, element), false);
85+
// SVG element may be updated as tested.
86+
assert.equal(updateSvgTransformAttr(win, svgElement),
87+
shouldUpdateSvgTransformAttr);
88+
}
89+
// Unknown data: assume that transforms supported.
90+
check('', false);
91+
// Chrome: transforms supported.
92+
check('Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E)' +
93+
' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.20' +
94+
' Mobile Safari/537.36',
95+
false);
96+
// Safari: transforms supported.
97+
check('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) ' +
98+
'AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 ' +
99+
'Safari/7046A194A',
100+
false);
101+
// Firefox: transforms supported.
102+
check('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) ' +
103+
'Gecko/20100101 Firefox/40.1',
104+
false);
105+
// IE: transforms are NOT supported.
106+
check('Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 7.0;' +
107+
' InfoPath.3; .NET CLR 3.1.40767; Trident/6.0; en-IN)',
108+
true);
109+
// Edge: transforms are NOT supported.
110+
check('Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36' +
111+
' (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36' +
112+
' Edge/12.10136',
113+
true);
114+
// ICS Android: transforms are NOT supported.
115+
check('Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; MZ604 Build/I.7.1-45)' +
116+
' AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30',
117+
true);
118+
});
119+
test('Set and clear transform', function() {
120+
// This is not an SVG element, so CSS transform support is not consulted.
121+
window._webAnimationsUpdateSvgTransformAttr = true;
122+
// Set.
123+
this.element.style._set('transform', 'translate(10px, 10px) scale(2)');
124+
assert.equal(getComputedStyle(this.element).transform,
125+
'matrix(2, 0, 0, 2, 10, 10)');
126+
assert.equal(this.element.hasAttribute('transform'), false);
127+
// Clear.
128+
this.element.style._clear('transform');
129+
assert.equal(getComputedStyle(this.element).transform, 'none');
130+
assert.equal(this.element.hasAttribute('transform'), false);
131+
});
132+
test('Set and clear supported transform on SVG element', function() {
133+
window._webAnimationsUpdateSvgTransformAttr = false;
134+
var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
135+
ensureStyleIsPatched(svgElement);
136+
this.svgContainer.appendChild(svgElement);
137+
// Set.
138+
svgElement.style._set('transform', 'translate(10px, 10px) scale(2)');
139+
assert.equal(getComputedStyle(svgElement).transform,
140+
'matrix(2, 0, 0, 2, 10, 10)');
141+
assert.equal(svgElement.hasAttribute('transform'), false);
142+
// Clear.
143+
svgElement.style._clear('transform');
144+
assert.equal(getComputedStyle(svgElement).transform, 'none');
145+
assert.equal(svgElement.hasAttribute('transform'), false);
146+
});
147+
test('Set and clear transform CSS property not supported on SVG element', function() {
148+
window._webAnimationsUpdateSvgTransformAttr = true;
149+
var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
150+
ensureStyleIsPatched(svgElement);
151+
this.svgContainer.appendChild(svgElement);
152+
// Set.
153+
svgElement.style._set('transform', 'translate(10px, 10px) scale(2)');
154+
assert.equal(getComputedStyle(svgElement).transform,
155+
'matrix(2, 0, 0, 2, 10, 10)');
156+
assert.equal(svgElement.getAttribute('transform'),
157+
'matrix(2 0 0 2 10 10)');
158+
// Clear.
159+
svgElement.style._clear('transform');
160+
assert.equal(getComputedStyle(svgElement).transform, 'none');
161+
assert.equal(svgElement.getAttribute('transform'), null);
162+
});
163+
test('Set and clear prefixed transform CSS property not supported on SVG element', function() {
164+
window._webAnimationsUpdateSvgTransformAttr = true;
165+
var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
166+
ensureStyleIsPatched(svgElement);
167+
this.svgContainer.appendChild(svgElement);
168+
// Set.
169+
svgElement.style._set('msTransform', 'translate(10px, 10px) scale(2)');
170+
assert.equal(svgElement.getAttribute('transform'),
171+
'matrix(2 0 0 2 10 10)');
172+
// Clear.
173+
svgElement.style._clear('msTransform');
174+
assert.equal(svgElement.getAttribute('transform'), null);
175+
});
176+
test('Restore transform CSS property not supported on SVG element', function() {
177+
window._webAnimationsUpdateSvgTransformAttr = true;
178+
var svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
179+
svgElement.setAttribute('transform', 'matrix(2 0 0 2 0 0)');
180+
ensureStyleIsPatched(svgElement);
181+
this.svgContainer.appendChild(svgElement);
182+
// Set.
183+
svgElement.style._set('transform', 'translate(10px, 10px) scale(2)');
184+
assert.equal(getComputedStyle(svgElement).transform,
185+
'matrix(2, 0, 0, 2, 10, 10)');
186+
assert.equal(svgElement.getAttribute('transform'),
187+
'matrix(2 0 0 2 10 10)');
188+
// Clear.
189+
svgElement.style._clear('transform');
190+
assert.equal(getComputedStyle(svgElement).transform, 'none');
191+
assert.equal(svgElement.getAttribute('transform'), 'matrix(2 0 0 2 0 0)');
192+
});
72193
});

‎test/js/dimension-handler.js

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ suite('dimension-handler', function() {
1818
{px: 50.0, em: -6.5});
1919
assert.deepEqual(webAnimations1.parseLength('calc((5px + 2px)*(1 + 2*(4 + 2*-5)) + 7px - (5em + 6vw/2)*4)'),
2020
{px: -70, em: -20, vw: -12});
21+
assert.deepEqual(webAnimations1.parseLength('calc(-13.2E+1rem/+12e-1/(+1 + +2 - -2 * 2 - -3))'),
22+
{rem: -11});
2123
assert.deepEqual(webAnimations1.parseLength('calc(calc(5px) + calc(((3))) *calc(calc(10px)))'),
2224
{px: 35});
2325
});

‎test/karma-testharness-adapter.js

+54-13
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@
1818
// Behaves like JSON.stringify() except only for strings and outputs strings with single quotes
1919
// instead of double quotes.
2020
// This so we can paste test results as expectations while keeping our linter happy.
21-
function stringify(string) {
22-
return '\'' + string.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/'/g, '\\\'') + '\'';
21+
function stringify(x) {
22+
if (typeof x == 'string') {
23+
return '\'' + x.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/'/g, '\\\'') + '\'';
24+
}
25+
console.assert(typeof x != 'object');
26+
return x.toString();
2327
}
2428

2529
function checkExpectations(testURL, passes, failures, expectedFailures) {
@@ -98,10 +102,12 @@
98102

99103
function checkConfig(config) {
100104
var requiredProperties = {
105+
target: '<String name of polyfill target being tested>',
101106
testURLList: '<Array of test URLs>',
102107
skip: '<Object mapping skipped test URLs to the reason for skipping>',
103-
expectedFailures: '<Object mapping test URLs to expected inner test failures>',
108+
failureConfigurations: '<Array of objects mapping test configuration to test URLs to expected inner test failures>',
104109
flakyTestIndicator: '<String used in expectedFailures to indicate flaky test (pass/fail)>',
110+
withNativeFallback: '<Boolean to indicate whether the native browser fallback should be included>',
105111
};
106112
var errorMessage = '';
107113
if (!config) {
@@ -125,29 +131,64 @@
125131
return true;
126132
}
127133

134+
var filteredConfigurationAttributes = ['target', 'withNativeFallback'];
135+
128136
// Serialises the failures suitable for pasting into expectedFailures: {} in web-platform-tests-expectations.js
129-
function formatFailures(failures) {
137+
function formatFailures(config, failures) {
138+
var result = ' {\n';
139+
140+
result += ' configuration: {\n';
141+
filteredConfigurationAttributes.forEach(function(attribute) {
142+
result += ' ' + attribute + ': ' + stringify(config[attribute]) + ',\n';
143+
});
144+
result += ' },\n';
145+
146+
result += ' failures: {\n';
130147
var testURLs = Object.keys(failures);
131148
testURLs.sort();
132-
return testURLs.map(function(testURL) {
149+
result += testURLs.map(function(testURL) {
133150
var tests = Object.keys(failures[testURL]);
134151
tests.sort();
135152
return (
136-
' ' + stringify(testURL) + ': {\n' +
153+
' ' + stringify(testURL) + ': {\n' +
137154
tests.map(function(test) {
138155
return (
139-
' ' + stringify(test) + ':\n' +
140-
' ' + stringify(failures[testURL][test]) + ',\n');
156+
' ' + stringify(test) + ':\n' +
157+
' ' + stringify(failures[testURL][test]) + ',\n');
141158
}).join('\n') +
142-
' },\n');
159+
' },\n');
143160
}).join('\n');
161+
result += ' },\n';
162+
163+
result += ' },\n';
164+
return result;
165+
}
166+
167+
function getExpectedFailures(config, testURL) {
168+
var result = {};
169+
config.failureConfigurations.forEach(function(failureConfiguration) {
170+
var configFilter = failureConfiguration.configuration;
171+
var filterMatches = filteredConfigurationAttributes.every(function(attribute) {
172+
console.assert(attribute in config);
173+
console.assert(attribute in configFilter);
174+
return configFilter[attribute] == null || config[attribute] == configFilter[attribute];
175+
});
176+
if (!filterMatches) {
177+
return;
178+
}
179+
var testURLFailures = failureConfiguration.failures[testURL] || [];
180+
for (var testName in testURLFailures) {
181+
result[testName] = testURLFailures[testName];
182+
}
183+
});
184+
return result;
144185
}
145186

146187
function runRemainingTests(remainingTestURLs, config, testNameDiv, iframe, outputFailures) {
147188
if (remainingTestURLs.length == 0) {
148189
karma.complete();
149190
window.failures = outputFailures;
150-
window.formattedFailures = formatFailures(outputFailures);
191+
window.formattedFailures = formatFailures(config, outputFailures);
151192
return;
152193
}
153194

@@ -167,11 +208,11 @@
167208
// parent window and call it once testharness.js has loaded.
168209
window.onTestharnessLoaded = function(innerWindow) {
169210
innerWindow.add_completion_callback(function(results) {
170-
var expectations = config.expectedFailures[testURL];
211+
var expectedFailures = getExpectedFailures(config, testURL);
171212
var failures = {};
172213
var passes = {};
173214
results.forEach(function(result) {
174-
if (expectations && expectations[result.name] == config.flakyTestIndicator) {
215+
if (expectedFailures && expectedFailures[result.name] == config.flakyTestIndicator) {
175216
failures[result.name] = config.flakyTestIndicator;
176217
return;
177218
}
@@ -188,7 +229,7 @@
188229
outputFailures[testURL] = failures;
189230
}
190231

191-
karma.result(checkExpectations(testURL, passes, failures, expectations));
232+
karma.result(checkExpectations(testURL, passes, failures, expectedFailures));
192233
runRemainingTests(remainingTestURLs.slice(1), config, testNameDiv, iframe, outputFailures);
193234
});
194235
};

‎test/resources/testharnessreport.js

+7-10
Original file line numberDiff line numberDiff line change
@@ -407,17 +407,14 @@ function dump_test_results(tests, status) {
407407

408408
/* BEGIN WEB ANIMATIONS POLYFILL EXTRAS */
409409

410-
// Disable native Web Animations fallback.
411-
// TODO(alancutter): Make this configurable in testing targets.
412-
Element.prototype.animate = null;
413-
414-
// The path /base/polyfill.js is expected to be a proxy for the appropriate polyfill script configured in Karma.
415-
document.write('<script src="/base/polyfill.js"></script>');
416-
if (window.parent && parent.window.onTestharnessLoaded) {
417-
parent.window.onTestharnessLoaded(window);
418-
} else {
419-
metadata_generator.setup();
410+
// This must be run under a Karma server via "grunt test".
411+
var config = window.parent.__karma__.config.testharnessTests;
412+
if (!config.withNativeFallback) {
413+
// Disable native Web Animations fallback.
414+
Element.prototype.animate = null;
420415
}
416+
document.write('<script src="/base/' + config.target + '.min.js"></script>');
417+
parent.window.onTestharnessLoaded(window);
421418

422419
/* END WEB ANIMATIONS POLYFILL EXTRAS */
423420

‎test/web-platform-tests-expectations.js

+2,266-911
Large diffs are not rendered by default.

‎web-animations-next-lite.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎web-animations-next-lite.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎web-animations-next.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎web-animations-next.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎web-animations.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎web-animations.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.