<!DOCTYPE html>
<meta charset=utf-8>
<title>The details element</title>
<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
<link rel=help href="https://html.spec.whatwg.org/multipage/#the-details-element">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<details id=details1>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details2 open>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details3 style="display:none;">
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details4>
</details>
<details id=details6>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details7>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details8 open>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details9 open>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<details id=details10>
  <summary>Lorem ipsum</summary>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</details>
<script>
  var t1 = async_test("Adding open to 'details' should fire a toggle event at the 'details' element"),
  t2 = async_test("Removing open from 'details' should fire a toggle event at the 'details' element"),
  t3 = async_test("Adding open to 'details' (display:none) should fire a toggle event at the 'details' element"),
  t4 = async_test("Adding open from 'details' (no children) should fire a toggle event at the 'details' element"),
  t6 = async_test("Calling open twice on 'details' fires only one toggle event"),
  t7 = async_test("Calling setAttribute('open', '') to 'details' should fire a toggle event at the 'details' element"),
  t8 = async_test("Calling removeAttribute('open') to 'details' should fire a toggle event at the 'details' element"),
  t9 = async_test("Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element"),
  t10 = async_test("Setting open=false to closed 'details' element should not fire a toggle event at the 'details' element"),

  details1 = document.getElementById('details1'),
  details2 = document.getElementById('details2'),
  details3 = document.getElementById('details3'),
  details4 = document.getElementById('details4'),
  details6 = document.getElementById('details6'),
  details7 = document.getElementById('details7'),
  details8 = document.getElementById('details8'),
  details9 = document.getElementById('details9'),
  details10 = document.getElementById('details10'),
  loop=false;

  function testEvent(evt) {
    assert_true(evt.isTrusted, "event is trusted");
    assert_false(evt.bubbles, "event doesn't bubble");
    assert_false(evt.cancelable, "event is not cancelable");
    assert_equals(Object.getPrototypeOf(evt), Event.prototype, "Prototype of toggle event is Event.prototype");
  }

  details1.ontoggle = t1.step_func_done(function(evt) {
    assert_true(details1.open);
    testEvent(evt)
  });
  details1.open = true; // opens details1

  details2.ontoggle = t2.step_func_done(function(evt) {
    assert_false(details2.open);
    testEvent(evt);
  });
  details2.open = false; // closes details2

  details3.ontoggle = t3.step_func_done(function(evt) {
    assert_true(details3.open);
    testEvent(evt);
  });
  details3.open = true; // opens details3

  details4.ontoggle = t4.step_func_done(function(evt) {
    assert_true(details4.open);
    testEvent(evt);
  });
  details4.open = true; // opens details4

  async_test(function(t) {
    var details5 = document.createElement("details");
    details5.ontoggle = t.step_func_done(function(evt) {
      assert_true(details5.open);
      testEvent(evt);
    })
    details5.open = true;
  }, "Adding open to 'details' (not in the document) should fire a toggle event at the 'details' element");

  details6.open = true;
  details6.open = false;
  details6.ontoggle = t6.step_func(function() {
    if (loop) {
      assert_unreached("toggle event fired twice");
    } else {
      loop = true;
    }
  });
  t6.step_timeout(function() {
    assert_true(loop);
    t6.done();
  }, 0);

  details7.ontoggle = t7.step_func_done(function(evt) {
    assert_true(details7.open);
    testEvent(evt)
  });
  details7.setAttribute('open', ''); // opens details7

  details8.ontoggle = t8.step_func_done(function(evt) {
    assert_false(details8.open);
    testEvent(evt)
  });
  details8.removeAttribute('open'); // closes details8

  var toggleFiredOnDetails9 = false;
  details9.ontoggle = t9.step_func_done(function(evt) {
    if (toggleFiredOnDetails9) {
      assert_unreached("toggle event fired twice on opened details element");
    } else {
      toggleFiredOnDetails9 = true;
    }
  });
  // The toggle event should be fired once when declaring details9 with open
  // attribute.
  details9.open = true; // opens details9
  t9.step_timeout(function() {
    assert_true(details9.open);
    assert_true(toggleFiredOnDetails9);
    t9.done();
  }, 0);

  details10.ontoggle = t10.step_func_done(function(evt) {
    assert_unreached("toggle event fired on closed details element");
  });
  details10.open = false; // closes details10
  t10.step_timeout(function() {
    assert_false(details10.open);
    t10.done();
  }, 0);

</script>
