| 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 |