OLD | NEW |
1 /* Copyright 2015 The Chromium Authors. All rights reserved. | 1 /* Copyright 2015 The Chromium Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
4 * | 4 * |
5 * Exported function: | 5 * Exported function: |
6 * - assertAttributeInterpolation({property, from, to}, [{at: fraction, is: val
ue}]) | 6 * - assertAttributeInterpolation({property, from, to, [fromComposite], [toComp
osite], [underlying]}, [{at: fraction, is: value}]) |
7 * Constructs a test case for each fraction that asserts the expected val
ue | 7 * Constructs a test case for each fraction that asserts the expected val
ue |
8 * equals the value produced by interpolation between from and to using | 8 * equals the value produced by interpolation between from and to composi
ted |
| 9 * onto underlying by fromComposite and toComposite respectively using |
9 * SMIL and Web Animations. | 10 * SMIL and Web Animations. |
| 11 * SMIL will only be tested with equal fromComposite and toComposite valu
es. |
10 */ | 12 */ |
11 'use strict'; | 13 'use strict'; |
12 (() => { | 14 (() => { |
13 var interpolationTests = []; | 15 var interpolationTests = []; |
14 | 16 |
15 function createElement(tagName, container) { | 17 function createElement(tagName, container) { |
16 var element = document.createElement(tagName); | 18 var element = document.createElement(tagName); |
17 if (container) { | 19 if (container) { |
18 container.appendChild(element); | 20 container.appendChild(element); |
19 } | 21 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 if (attributeName === 'in') | 178 if (attributeName === 'in') |
177 attributeName = 'in1'; | 179 attributeName = 'in1'; |
178 | 180 |
179 // The attribute 'orient' is exposed in IDL as 'orientType' and 'orientAngle
' | 181 // The attribute 'orient' is exposed in IDL as 'orientType' and 'orientAngle
' |
180 if (attributeName === 'orient') { | 182 if (attributeName === 'orient') { |
181 if (element['orientType'] && element['orientType'].animVal === SVGMarkerEl
ement.SVG_MARKER_ORIENT_AUTO) | 183 if (element['orientType'] && element['orientType'].animVal === SVGMarkerEl
ement.SVG_MARKER_ORIENT_AUTO) |
182 return 'auto'; | 184 return 'auto'; |
183 attributeName = 'orientAngle'; | 185 attributeName = 'orientAngle'; |
184 } | 186 } |
185 | 187 |
186 var result; | 188 var result = null; |
187 if (attributeName === 'd') | 189 if (attributeName === 'd') |
188 result = element.getAttribute('d'); | 190 result = element.getAttribute('d'); |
189 else if (attributeName === 'points') | 191 else if (attributeName === 'points') |
190 result = element['animatedPoints']; | 192 result = element['animatedPoints']; |
191 else | 193 else |
192 result = element[attributeName].animVal; | 194 result = element[attributeName].animVal; |
193 | 195 |
194 if (!result) { | 196 if (result === null) { |
195 if (attributeName === 'pathLength') | 197 if (attributeName === 'pathLength') |
196 return '0'; | 198 return '0'; |
197 if (attributeName === 'preserveAlpha') | 199 if (attributeName === 'preserveAlpha') |
198 return 'false'; | 200 return 'false'; |
199 | 201 |
200 console.error('Unknown attribute, cannot get ' + attributeName); | 202 console.error('Unknown attribute, cannot get ' + attributeName); |
201 return null; | 203 return null; |
202 } | 204 } |
203 | 205 |
204 if (result instanceof SVGAngle || result instanceof SVGLength) | 206 if (result instanceof SVGAngle || result instanceof SVGLength) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 var setElement = document.createElementNS(svgNamespace, 'set'); | 240 var setElement = document.createElementNS(svgNamespace, 'set'); |
239 setElement.setAttribute('attributeName', namespacedAttributeName(attribute
Name)); | 241 setElement.setAttribute('attributeName', namespacedAttributeName(attribute
Name)); |
240 setElement.setAttribute('attributeType', 'XML'); | 242 setElement.setAttribute('attributeType', 'XML'); |
241 setElement.setAttribute('to', expectation); | 243 setElement.setAttribute('to', expectation); |
242 element.appendChild(setElement); | 244 element.appendChild(setElement); |
243 } else { | 245 } else { |
244 element.setAttribute(attributeName, expectation); | 246 element.setAttribute(attributeName, expectation); |
245 } | 247 } |
246 } | 248 } |
247 | 249 |
248 function createAnimateElement(attributeName, from, to) | 250 function createAnimateElement(attributeName, from, to, composite) |
249 { | 251 { |
250 var animateElement; | 252 var animateElement; |
251 if (attributeName.toLowerCase().includes('transform')) { | 253 if (attributeName.toLowerCase().includes('transform')) { |
252 from = from.split(')'); | 254 from = from.split(')'); |
253 to = to.split(')'); | 255 to = to.split(')'); |
254 // Discard empty string at end. | 256 // Discard empty string at end. |
255 from.pop(); | 257 from.pop(); |
256 to.pop(); | 258 to.pop(); |
257 | 259 |
258 // SMIL requires separate animateTransform elements for each transform in
the list. | 260 // SMIL requires separate animateTransform elements for each transform in
the list. |
(...skipping 15 matching lines...) Expand all Loading... |
274 animateElement = document.createElementNS(svgNamespace, 'animate'); | 276 animateElement = document.createElementNS(svgNamespace, 'animate'); |
275 animateElement.setAttribute('from', from); | 277 animateElement.setAttribute('from', from); |
276 animateElement.setAttribute('to', to); | 278 animateElement.setAttribute('to', to); |
277 } | 279 } |
278 | 280 |
279 animateElement.setAttribute('attributeName', namespacedAttributeName(attribu
teName)); | 281 animateElement.setAttribute('attributeName', namespacedAttributeName(attribu
teName)); |
280 animateElement.setAttribute('attributeType', 'XML'); | 282 animateElement.setAttribute('attributeType', 'XML'); |
281 animateElement.setAttribute('begin', '0'); | 283 animateElement.setAttribute('begin', '0'); |
282 animateElement.setAttribute('dur', '1'); | 284 animateElement.setAttribute('dur', '1'); |
283 animateElement.setAttribute('fill', 'freeze'); | 285 animateElement.setAttribute('fill', 'freeze'); |
| 286 animateElement.setAttribute('additive', composite === 'add' ? 'sum' : compos
ite); |
284 return animateElement; | 287 return animateElement; |
285 } | 288 } |
286 | 289 |
287 function createTestTarget(method, description, container, params, expectation)
{ | 290 function createTestTarget(method, description, container, params, expectation)
{ |
288 var target = createTarget(container); | 291 var target = createTarget(container); |
| 292 if (params.underlying) { |
| 293 target.setAttribute(params.property, params.underlying); |
| 294 } |
| 295 |
289 var expected = createTarget(container); | 296 var expected = createTarget(container); |
290 setAttributeValue(expected, params.property, expectation.is); | 297 setAttributeValue(expected, params.property, expectation.is); |
291 | 298 |
292 target.interpolate = function() { | 299 target.interpolate = function() { |
293 switch (method) { | 300 switch (method) { |
294 case 'SMIL': | 301 case 'SMIL': |
295 var animateElement = createAnimateElement(params.property, params.from,
params.to); | 302 console.assert(params.fromComposite === params.toComposite); |
| 303 var animateElement = createAnimateElement(params.property, params.from,
params.to, params.fromComposite); |
296 if (animateElement) { | 304 if (animateElement) { |
297 target.appendChild(animateElement); | 305 target.appendChild(animateElement); |
298 target.container.pauseAnimations(); | 306 target.container.pauseAnimations(); |
299 target.container.setCurrentTime(expectation.at); | 307 target.container.setCurrentTime(expectation.at); |
300 } else { | 308 } else { |
301 console.warn(`Unable to test SMIL from ${params.from} to ${params.to}`
); | 309 console.warn(`Unable to test SMIL from ${params.from} to ${params.to}`
); |
302 target.container.remove(); | 310 target.container.remove(); |
303 target.measure = function() {}; | 311 target.measure = function() {}; |
304 } | 312 } |
305 break; | 313 break; |
306 case 'Web Animations': | 314 case 'Web Animations': |
307 // Replace 'transform' with 'svgTransform', etc. This avoids collisions
with CSS properties or the Web Animations API (offset). | 315 // Replace 'transform' with 'svgTransform', etc. This avoids collisions
with CSS properties or the Web Animations API (offset). |
308 var prefixedProperty = 'svg' + params.property[0].toUpperCase() + params
.property.slice(1); | 316 var prefixedProperty = 'svg' + params.property[0].toUpperCase() + params
.property.slice(1); |
309 target.animate([ | 317 target.animate([ |
310 {[prefixedProperty]: params.from}, | 318 { |
311 {[prefixedProperty]: params.to}, | 319 [prefixedProperty]: params.from, |
| 320 composite: params.fromComposite, |
| 321 }, |
| 322 { |
| 323 [prefixedProperty]: params.to, |
| 324 composite: params.toComposite, |
| 325 }, |
312 ], { | 326 ], { |
313 fill: 'forwards', | 327 fill: 'forwards', |
314 duration: 1, | 328 duration: 1, |
315 easing: createEasing(expectation.at), | 329 easing: createEasing(expectation.at), |
316 delay: -0.5, | 330 delay: -0.5, |
317 iterations: 0.5, | 331 iterations: 0.5, |
318 }); | 332 }); |
319 break; | 333 break; |
320 default: | 334 default: |
321 console.error('Unknown test method: ' + method); | 335 console.error('Unknown test method: ' + method); |
322 } | 336 } |
323 }; | 337 }; |
324 | 338 |
325 target.measure = function() { | 339 target.measure = function() { |
326 test(function() { | 340 test(function() { |
327 assert_equals( | 341 assert_equals( |
328 normalizeValue(getAttributeValue(target, params.property)), | 342 normalizeValue(getAttributeValue(target, params.property)), |
329 normalizeValue(getAttributeValue(expected, params.property))); | 343 normalizeValue(getAttributeValue(expected, params.property))); |
330 }, `${method}: ${description} at (${expectation.at}) is [${expectation.is}
]`); | 344 }, `${method}: ${description} at (${expectation.at}) is [${expectation.is}
]`); |
331 }; | 345 }; |
332 | 346 |
333 return target; | 347 return target; |
334 } | 348 } |
335 | 349 |
336 function createTestTargets(interpolationTests, container) { | 350 function createTestTargets(interpolationTests, container) { |
337 var targets = []; | 351 var targets = []; |
338 for (var interpolationTest of interpolationTests) { | 352 for (var interpolationTest of interpolationTests) { |
339 var params = interpolationTest.params; | 353 var params = interpolationTest.params; |
340 var description = `Interpolate attribute <${params.property}> from [${para
ms.from}] to [${params.to}]`; | 354 params.fromComposite = params.fromComposite || 'replace'; |
341 var expectations = interpolationTest.expectations; | 355 params.toComposite = params.toComposite || 'replace'; |
| 356 var description = `Interpolate attribute <${params.property}> from ${param
s.fromComposite} [${params.from}] to ${params.toComposite} [${params.to}]`; |
342 | 357 |
343 for (var method of ['SMIL', 'Web Animations']) { | 358 for (var method of ['SMIL', 'Web Animations']) { |
| 359 if (method === 'SMIL' && params.fromComposite !== params.toComposite) { |
| 360 continue; |
| 361 } |
344 createElement('pre', container).textContent = `${method}: ${description}
`; | 362 createElement('pre', container).textContent = `${method}: ${description}
`; |
345 var smilContainer = createElement('div', container); | 363 var smilContainer = createElement('div', container); |
346 for (var expectation of expectations) { | 364 for (var expectation of interpolationTest.expectations) { |
347 if (method === 'SMIL' && (expectation.at < 0 || expectation.at > 1)) { | 365 if (method === 'SMIL' && (expectation.at < 0 || expectation.at > 1)) { |
348 continue; | 366 continue; |
349 } | 367 } |
350 targets.push(createTestTarget(method, description, smilContainer, para
ms, expectation)); | 368 targets.push(createTestTarget(method, description, smilContainer, para
ms, expectation)); |
351 } | 369 } |
352 } | 370 } |
353 } | 371 } |
354 return targets; | 372 return targets; |
355 } | 373 } |
356 | 374 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 return loadScript('../../resources/testharnessreport.js'); | 409 return loadScript('../../resources/testharnessreport.js'); |
392 }).then(() => { | 410 }).then(() => { |
393 var asyncHandle = async_test('This test uses interpolation-test.js.') | 411 var asyncHandle = async_test('This test uses interpolation-test.js.') |
394 requestAnimationFrame(() => { | 412 requestAnimationFrame(() => { |
395 runTests().then(() => asyncHandle.done()); | 413 runTests().then(() => asyncHandle.done()); |
396 }); | 414 }); |
397 }); | 415 }); |
398 | 416 |
399 window.assertAttributeInterpolation = assertAttributeInterpolation; | 417 window.assertAttributeInterpolation = assertAttributeInterpolation; |
400 })(); | 418 })(); |
OLD | NEW |