| 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 /* | 5 /* |
| 6 Exported function: | 6 Exported function: |
| 7 assertResponsive | 7 assertResponsive |
| 8 | 8 |
| 9 Call signature: | 9 Call signature: |
| 10 assertResponsive({ | 10 assertResponsive({ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 configuration. | 28 configuration. |
| 29 It starts the interpolation in every configuration, changes the | 29 It starts the interpolation in every configuration, changes the |
| 30 state to every other configuration (n * (n - 1) complexity) and asserts that | 30 state to every other configuration (n * (n - 1) complexity) and asserts that |
| 31 each destination configuration's expectations are met. | 31 each destination configuration's expectations are met. |
| 32 Each animation target can be assigned custom styles via the ".target" selector. | 32 Each animation target can be assigned custom styles via the ".target" selector. |
| 33 This test is designed to catch stale interpolation caches. | 33 This test is designed to catch stale interpolation caches. |
| 34 */ | 34 */ |
| 35 | 35 |
| 36 (function() { | 36 (function() { |
| 37 'use strict'; | 37 'use strict'; |
| 38 var sharedStyle = null; | |
| 39 var animationCount = 0; | |
| 40 var pendingResponsiveTests = []; | 38 var pendingResponsiveTests = []; |
| 41 | 39 |
| 42 function assertResponsive(options) { | 40 function assertResponsive(options) { |
| 43 pendingResponsiveTests.push(options); | 41 pendingResponsiveTests.push(options); |
| 44 } | 42 } |
| 45 | 43 |
| 46 function createStateTransitions(configurations) { | 44 function createStateTransitions(configurations) { |
| 47 var stateTransitions = []; | 45 var stateTransitions = []; |
| 48 for (var i = 0; i < configurations.length; i++) { | 46 for (var i = 0; i < configurations.length; i++) { |
| 49 var beforeConfiguration = configurations[i]; | 47 var beforeConfiguration = configurations[i]; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 console.assert(targets.every(function(target) { return target.parentElement
=== parent; })); | 83 console.assert(targets.every(function(target) { return target.parentElement
=== parent; })); |
| 86 parent.style[property] = state.inherited; | 84 parent.style[property] = state.inherited; |
| 87 } | 85 } |
| 88 if (state.underlying) { | 86 if (state.underlying) { |
| 89 for (var target of targets) { | 87 for (var target of targets) { |
| 90 target.style[property] = state.underlying; | 88 target.style[property] = state.underlying; |
| 91 } | 89 } |
| 92 } | 90 } |
| 93 } | 91 } |
| 94 | 92 |
| 95 function createAnimationName() { | 93 function createKeyframes(property, from, to) { |
| 96 return 'anim' + (animationCount++); | 94 return [ |
| 95 {[property]: from}, |
| 96 {[property]: to}, |
| 97 ]; |
| 97 } | 98 } |
| 98 | 99 |
| 99 function createKeyframes(animationName, property, from, to) { | 100 function startPausedAnimations(targets, keyframes, fractions) { |
| 100 return ` | |
| 101 @keyframes ${animationName} { | |
| 102 from { ${property}: ${from}; } | |
| 103 to { ${property}: ${to}; } | |
| 104 }`; | |
| 105 } | |
| 106 | |
| 107 function addGlobalStyle(styleText) { | |
| 108 if (!sharedStyle) { | |
| 109 sharedStyle = createElement('style', document.documentElement); | |
| 110 } | |
| 111 sharedStyle.textContent += styleText; | |
| 112 } | |
| 113 | |
| 114 function startPausedAnimations(targets, animationName, fractions) { | |
| 115 console.assert(targets.length == fractions.length); | 101 console.assert(targets.length == fractions.length); |
| 116 for (var i = 0; i < targets.length; i++) { | 102 for (var i = 0; i < targets.length; i++) { |
| 117 var target = targets[i]; | 103 var target = targets[i]; |
| 118 var fraction = fractions[i]; | 104 var fraction = fractions[i]; |
| 119 console.assert(fraction >= 0 && fraction <= 1); | 105 console.assert(fraction >= 0 && fraction < 1); |
| 120 target.style.animation = `${animationName} 1s linear both paused`; | 106 var animation = target.animate(keyframes, 1); |
| 121 target.style.animationDelay = `${-fraction}s`; | 107 animation.currentTime = fraction; |
| 108 animation.pause(); |
| 122 } | 109 } |
| 123 } | 110 } |
| 124 | 111 |
| 125 function runPendingResponsiveTests() { | 112 function runPendingResponsiveTests() { |
| 126 var stateTransitionTests = []; | 113 var stateTransitionTests = []; |
| 127 pendingResponsiveTests.forEach(function(options) { | 114 pendingResponsiveTests.forEach(function(options) { |
| 128 var property = options.property; | 115 var property = options.property; |
| 129 var from = options.from; | 116 var from = options.from; |
| 130 var to = options.to; | 117 var to = options.to; |
| 131 var animationName = createAnimationName(); | 118 var keyframes = createKeyframes(property, from, to); |
| 132 addGlobalStyle(createKeyframes(animationName, property, from, to)); | |
| 133 | 119 |
| 134 var stateTransitions = createStateTransitions(options.configurations); | 120 var stateTransitions = createStateTransitions(options.configurations); |
| 135 stateTransitions.forEach(function(stateTransition) { | 121 stateTransitions.forEach(function(stateTransition) { |
| 136 var before = stateTransition.before; | 122 var before = stateTransition.before; |
| 137 var after = stateTransition.after; | 123 var after = stateTransition.after; |
| 138 var container = createElement('div', document.body); | 124 var container = createElement('div', document.body); |
| 139 var targets = createTargets(after.expect.length, container); | 125 var targets = createTargets(after.expect.length, container); |
| 140 | 126 |
| 141 setState(targets, property, before.state); | 127 setState(targets, property, before.state); |
| 142 startPausedAnimations(targets, animationName, after.expect.map(function(ex
pectation) { return expectation.at; })); | 128 startPausedAnimations(targets, keyframes, after.expect.map(function(expect
ation) { return expectation.at; })); |
| 143 stateTransitionTests.push({ | 129 stateTransitionTests.push({ |
| 144 applyStateTransition() { | 130 applyStateTransition() { |
| 145 setState(targets, property, after.state); | 131 setState(targets, property, after.state); |
| 146 }, | 132 }, |
| 147 assert() { | 133 assert() { |
| 148 for (var i = 0; i < targets.length; i++) { | 134 for (var i = 0; i < targets.length; i++) { |
| 149 var target = targets[i]; | 135 var target = targets[i]; |
| 150 var expectation = after.expect[i]; | 136 var expectation = after.expect[i]; |
| 151 var actual = getComputedStyle(target)[property]; | 137 var actual = getComputedStyle(target)[property]; |
| 152 test(function() { | 138 test(function() { |
| 153 assert_equals(actual, expectation.is); | 139 assert_equals(actual, expectation.is); |
| 154 }, `Animation on property <${property}> from [${from}] to [${to}] wi
th ${JSON.stringify(before.state)} changed to ${JSON.stringify(after.state)} at
(${expectation.at}) is [${expectation.is}]`); | 140 }, `Animation on property <${property}> from [${from}] to [${to}] wi
th ${JSON.stringify(before.state)} changed to ${JSON.stringify(after.state)} at
(${expectation.at}) is [${expectation.is}]`); |
| 155 } | 141 } |
| 156 }, | 142 }, |
| 157 }); | 143 }); |
| 158 }); | 144 }); |
| 159 }); | 145 }); |
| 160 | 146 |
| 161 // Force style recalc to instantiate animations internally. | |
| 162 getComputedStyle(document.body).color; | |
| 163 | |
| 164 // Separate style modification from measurement as different phases to avoid a
style recalc storm. | 147 // Separate style modification from measurement as different phases to avoid a
style recalc storm. |
| 165 for (var stateTransitionTest of stateTransitionTests) { | 148 for (var stateTransitionTest of stateTransitionTests) { |
| 166 stateTransitionTest.applyStateTransition(); | 149 stateTransitionTest.applyStateTransition(); |
| 167 } | 150 } |
| 168 for (var stateTransitionTest of stateTransitionTests) { | 151 for (var stateTransitionTest of stateTransitionTests) { |
| 169 stateTransitionTest.assert(); | 152 stateTransitionTest.assert(); |
| 170 } | 153 } |
| 171 } | 154 } |
| 172 | 155 |
| 173 function loadScript(url) { | 156 function loadScript(url) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 186 requestAnimationFrame(function() { | 169 requestAnimationFrame(function() { |
| 187 runPendingResponsiveTests(); | 170 runPendingResponsiveTests(); |
| 188 asyncHandle.done() | 171 asyncHandle.done() |
| 189 }); | 172 }); |
| 190 }); | 173 }); |
| 191 | 174 |
| 192 | 175 |
| 193 window.assertResponsive = assertResponsive; | 176 window.assertResponsive = assertResponsive; |
| 194 | 177 |
| 195 })(); | 178 })(); |
| OLD | NEW |