<!DOCTYPE html>
<meta charset=utf-8>
<title>Writable effect.target tests</title>
<link rel="help"
  href="https://w3c.github.io/web-animations/#dom-keyframeeffect-target">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<body>
<div id="log"></div>
<script>
"use strict";

var gKeyFrames = { 'marginLeft': ['0px', '100px'] };

test(function(t) {
  var div = createDiv(t);
  var effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
  effect.target = div;

  var anim = new Animation(effect, document.timeline);
  anim.play();

  anim.currentTime = 50 * MS_PER_SEC;
  assert_equals(getComputedStyle(div).marginLeft, '50px',
                'Value at 50% progress');
}, 'Test setting target before constructing the associated animation');

test(function(t) {
  var div = createDiv(t);
  div.style.marginLeft = '10px';
  var effect = new KeyframeEffect(null, gKeyFrames, 100 * MS_PER_SEC);
  var anim = new Animation(effect, document.timeline);
  anim.play();

  anim.currentTime = 50 * MS_PER_SEC;
  assert_equals(getComputedStyle(div).marginLeft, '10px',
                'Value at 50% progress before setting new target');
  effect.target = div;
  assert_equals(getComputedStyle(div).marginLeft, '50px',
                'Value at 50% progress after setting new target');
}, 'Test setting target from null to a valid target');

test(function(t) {
  var div = createDiv(t);
  div.style.marginLeft = '10px';
  var anim = div.animate(gKeyFrames, 100 * MS_PER_SEC);

  anim.currentTime = 50 * MS_PER_SEC;
  assert_equals(getComputedStyle(div).marginLeft, '50px',
                'Value at 50% progress before clearing the target')

  anim.effect.target = null;
  assert_equals(getComputedStyle(div).marginLeft, '10px',
                'Value after clearing the target')
}, 'Test setting target from a valid target to null');

test(function(t) {
  var a = createDiv(t);
  var b = createDiv(t);
  a.style.marginLeft = '10px';
  b.style.marginLeft = '20px';
  var anim = a.animate(gKeyFrames, 100 * MS_PER_SEC);

  anim.currentTime = 50 * MS_PER_SEC;
  assert_equals(getComputedStyle(a).marginLeft, '50px',
                'Value of 1st element (currently targeted) before ' +
                'changing the effect target');
  assert_equals(getComputedStyle(b).marginLeft, '20px',
                'Value of 2nd element (currently not targeted) before ' +
                'changing the effect target');
  anim.effect.target = b;
  assert_equals(getComputedStyle(a).marginLeft, '10px',
                'Value of 1st element (currently not targeted) after ' +
                'changing the effect target');
  assert_equals(getComputedStyle(b).marginLeft, '50px',
                'Value of 2nd element (currently targeted) after ' +
                'changing the effect target');

  // This makes sure the animation property is changed correctly on new
  // targeted element.
  anim.currentTime = 75 * MS_PER_SEC;
  assert_equals(getComputedStyle(b).marginLeft, '75px',
                'Value of 2nd target (currently targeted) after ' +
                'changing the animation current time.');
}, 'Test setting target from a valid target to another target');

test(function(t) {
  var anim = createDiv(t).animate([ { marginLeft: '0px' },
                                    { marginLeft: '-20px' },
                                    { marginLeft: '100px' },
                                    { marginLeft: '50px' } ],
                                  { duration: 100 * MS_PER_SEC,
                                    spacing: 'paced(margin-left)' });

  anim.effect.target = null;

  var frames = anim.effect.getKeyframes();
  var slots = frames.length - 1;
  assert_equals(frames[0].computedOffset, 0.0, '1st frame offset');
  assert_equals(frames[1].computedOffset, 1.0 / slots, '2nd frame offset');
  assert_equals(frames[2].computedOffset, 2.0 / slots, '3rd frame offset');
  assert_equals(frames[3].computedOffset, 1.0, 'last frame offset');
}, 'Test falling back to distribute spacing mode after setting null target');

test(function(t) {
  var effect = new KeyframeEffect(null,
                                  [ { marginLeft: '0px' },
                                    { marginLeft: '-20px' },
                                    { marginLeft: '100px' },
                                    { marginLeft: '50px' } ],
                                  { duration: 100 * MS_PER_SEC,
                                    spacing: 'paced(margin-left)' });
  var frames = effect.getKeyframes();
  var slots = frames.length - 1;
  assert_equals(frames[1].computedOffset, 1.0 / slots, '2nd frame offset');
  assert_equals(frames[2].computedOffset, 2.0 / slots, '3rd frame offset');
}, 'Test falling back to distribute spacing mode if there is no context ' +
   'element');

test(function(t) {
  var div1 = createDiv(t);
  var div2 = createDiv(t);
  div1.style.marginLeft = '-20px';
  div2.style.marginLeft = '-50px';
  var child1 = document.createElement('div');
  var child2 = document.createElement('div');
  div1.appendChild(child1);
  div2.appendChild(child2);
  //      body
  //    /      \
  //  div1     div2
  // (-20px)  (-50px)
  //   |        |
  // child1   child2
  var anim = child1.animate([ { marginLeft: '0px' },
                              { marginLeft: 'inherit' },
                              { marginLeft: '100px' },
                              { marginLeft: '50px' } ],
                            { duration: 100 * MS_PER_SEC,
                              spacing: 'paced(margin-left)' });

  var frames = anim.effect.getKeyframes();
  var cumDist = [0, 20, 140, 190];
  assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
                '2nd frame offset');
  assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
                '3rd frame offset');

  anim.effect.target = child2;
  frames = anim.effect.getKeyframes();
  cumDist = [0, 50, 200, 250];
  assert_equals(frames[1].computedOffset, cumDist[1] / cumDist[3],
                '2nd frame offset after setting a new target');
  assert_equals(frames[2].computedOffset, cumDist[2] / cumDist[3],
                '3rd frame offset after setting a new target');
}, 'Test paced spacing mode after setting a new target');

</script>
</body>