(function (root){ 'use strict'; var index = 0; var suite = root.generalParallelTest = { setup: function (data, options){ suite._setupDom(data, options); suite._setupEvents(data, options); } , _setupDom: function (data, options){ data.fixture = document.getElementById('fixture').cloneNode(true ); data.fixture.id = 'test-' + (index++ ); _AN_Call_appendchild('appendChild', (document.getElementById('offscreen') || document.body), data.fixture); data.transition = { node: data.fixture.querySelector('.transition'), values: [] , events: [] , computedStyle: function (property){ return computedStyle(data.transition.node, property); } } ; data.container = { node: data.transition.node.parentNode, values: [] , events: [] , computedStyle: function (property){ return computedStyle(data.container.node, property); } } ; if (data.pseudo) { data.pseudo = { name: data.pseudo, values: [] , computedStyle: function (property){ return computedStyle(data.transition.node, property, ':' + data.pseudo.name); } } ; } } , _setupEvents: function (data, options){ ['transition', 'container'] .forEach(function (elem){ var handler = function (event){ event.stopPropagation(); var name = event.propertyName; var time = Math.round(event.elapsedTime * 1000) / 1000; var pseudo = event.pseudoElement? (':' + event.pseudoElement): ''; data[elem].events.push(name + pseudo + ":" + time + "s"); } ; data[elem].node.addEventListener('transitionend', handler, false ); data[elem]._events = { 'transitionend': handler} ; } ); } , teardown: function (data, options){ if (data.fixture.parentNode) { data.fixture.parentNode.removeChild(data.fixture); } } , sliceStart: function (options, tests){ setStyle(options.styles); generalParallelTest.startValueCollection(options); } , sliceDone: function (options, tests){ generalParallelTest.stopValueCollection(options); options.styles = { } ; } , done: function (options){ setStyle(); reflow(); } , addStyles: function (data, options, styles){ if (!options.styles) { options.styles = { } ; } Object.keys(styles).forEach(function (key){ var selector = '#' + data.fixture.id + (key.substring(0, 8) === '.fixture'? '': ' ') + key; options.styles[selector] = styles[key]; } ); } , getStyle: function (data){ reflow(); suite._getStyleFor(data, 'from'); suite._addClass(data, 'to', true ); suite._getStyleFor(data, 'to'); suite._removeClass(data, 'to', true ); data.container._values = [] ; data.transition._values = [] ; if (data.pseudo) { data.pseudo._values = [] ; } } , _getStyleFor: function (data, key){ data.container[key] = data.container.computedStyle(data.property); data.transition[key] = data.transition.computedStyle(data.property); if (data.pseudo) { data.pseudo[key] = data.pseudo.computedStyle(data.property); } } , _addClass: function (data, className, forceReflow){ data.container.node.classList.add(className); data.transition.node.classList.add(className); if (forceReflow) { reflow(); } } , _removeClass: function (data, className, forceReflow){ data.container.node.classList.remove(className); data.transition.node.classList.remove(className); if (forceReflow) { reflow(); } } , startTransition: function (data){ suite._addClass(data, 'how', true ); suite._addClass(data, 'to', false ); } , startValueCollection: function (options){ var raf = window.requestAnimationFrame || function (callback){ _AN_Call_settimeout('setTimeout', window, callback, 20); } ; options._collectValues = true ; function runLoop(){ if (!options._collectValues) { return ; } options.tests.forEach(function (data){ if (!data.property) { return ; } ['transition', 'container', 'pseudo'] .forEach(function (elem){ var pseudo = null ; if (!data[elem] || (elem === 'pseudo' && !data.pseudo)) { return ; } var current = data[elem].computedStyle(data.property); var values = data[elem].values; var length = _AN_Read_length('length', values); if (!length || values[length - 1] !== current) { values.push(current); } } ); } ); raf(runLoop); } runLoop(); } , stopValueCollection: function (options){ options._collectValues = false ; } , assertExpectedEventsFunc: function (data, elem, expected){ return function (){ var _result = data[elem].events.sort().join(" "); var _expected = typeof expected === 'string'? expected: expected.sort().join(" "); assert_equals(_result, _expected, "Expected TransitionEnd events triggered on ." + elem); } ; } , assertIntermediateValuesFunc: function (data, elem){ return function (){ var values = data[elem].values; if (data.flags.discrete) { assert_equals(values[0], data[elem].from, "must be initial value while transitioning on ." + elem); assert_equals(values[1], data[elem].to, "must be target value after transitioning on ." + elem); assert_equals(_AN_Read_length("length", values), 2, "discrete property only has 2 values ." + elem); } else { assert_not_equals(values[1], data[elem].from, "may not be initial value while transitioning on ." + elem); assert_not_equals(values[1], data[elem].to, "may not be target value while transitioning on ." + elem); } } ; } } ; } )(window);