// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library entered_left_view_test;

import 'dart:async';
import 'dart:html';
import 'dart:js' as js;
import 'package:unittest/html_individual_config.dart';
import 'package:unittest/unittest.dart';
import '../utils.dart';

var invocations = [];
class Foo extends HtmlElement {
  factory Foo() => null;
  Foo.created() : super.created();

  void createdCallback() {
    invocations.add('created');
  }

  void enteredView() {
    invocations.add('entered');
  }

  void leftView() {
    invocations.add('left');
  }

  void attributeChanged(String name, String oldValue, String newValue) {
    invocations.add('attribute changed');
  }
}

// Pump custom events polyfill events.
void customElementsTakeRecords() {
  if (js.context.hasProperty('CustomElements')) {
    js.context['CustomElements'].callMethod('takeRecords');
  }
}

main() {
  useHtmlIndividualConfiguration();

  // Adapted from Blink's
  // fast/dom/custom/entered-left-document.html test.

  var docA = document;
  var docB = document.implementation.createHtmlDocument('');

  var nullSanitizer = new NullTreeSanitizer();

  var registeredTypes = false;
  setUp(() {
    return loadPolyfills().then((_) {
      if (registeredTypes) {
        return;
      }
      registeredTypes = true;
      document.register('x-a', Foo);
    });
  });

  group('standard_events', () {
    var a;
    setUp(() {
      invocations = [];
    });

    test('Created', () {
      a = new Element.tag('x-a');
      expect(invocations, ['created']);
    });

    test('entered', () {
      document.body.append(a);
      customElementsTakeRecords();
      expect(invocations, ['entered']);
    });

    test('left', () {
      a.remove();
      customElementsTakeRecords();
      expect(invocations, ['left']);
    });

    var div = new DivElement();
    test('nesting does not trigger entered', () {
      div.append(a);
      customElementsTakeRecords();
      expect(invocations, []);
    });

    test('nested entering triggers entered', () {
      document.body.append(div);
      customElementsTakeRecords();
      expect(invocations, ['entered']);
    });

    test('nested leaving triggers left', () {
      div.remove();
      customElementsTakeRecords();
      expect(invocations, ['left']);
    });
  });

  group('viewless_document', () {
    var a;
    setUp(() {
      invocations = [];
    });

    test('Created, owned by a document without a view', () {
      a = docB.createElement('x-a');
      expect(a.document, docB,
          reason:'new instance should be owned by the document the definition '
          'was registered with');
      expect(invocations, ['created'],
          reason: 'calling the constructor should invoke the created callback');
    });

    test('Entered document without a view', () {
      docB.body.append(a);
      expect(invocations, [],
          reason: 'entered callback should not be invoked when entering a '
          'document without a view');
    });

    test('Attribute changed in document without a view', () {
      a.setAttribute('data-foo', 'bar');
      expect(invocations, ['attribute changed'],
          reason: 'changing an attribute should invoke the callback, even in a '
          'document without a view');
    });

    test('Entered document with a view', () {
      document.body.append(a);
      customElementsTakeRecords();
      expect(invocations, ['entered'],
          reason: 'entered callback should be invoked when entering a document '
          'with a view');
    });

    test('Left document with a view', () {
      a.remove();
      customElementsTakeRecords();
      expect(invocations, ['left'],
          reason: 'left callback should be invoked when leaving a document '
          'with a view');
    });

    test('Created in a document without a view', () {
      docB.body.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
      Platform.upgradeCustomElements(docB.body);

      expect(invocations, ['created'],
          reason: 'only created callback should be invoked when parsing a '
          'custom element in a document without a view');
    });
  });

  group('shadow_dom', () {
    var div;
    var s;
    setUp(() {
      invocations = [];
      div = new DivElement();
      s = div.createShadowRoot();
    });

    tearDown(() {
      customElementsTakeRecords();
    });

    test('Created in Shadow DOM that is not in a document', () {
      s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
      Platform.upgradeCustomElements(s);

      expect(invocations, ['created'],
          reason: 'the entered callback should not be invoked when entering a '
          'Shadow DOM subtree not in the document');
    });

    test('Leaves Shadow DOM that is not in a document', () {
      s.innerHtml = '';
      expect(invocations, [],
          reason: 'the left callback should not be invoked when leaving a '
          'Shadow DOM subtree not in the document');
    });

    test('Enters a document with a view as a constituent of Shadow DOM', () {
      s.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
      Platform.upgradeCustomElements(s);

      document.body.append(div);
      customElementsTakeRecords();
      expect(invocations, ['created', 'entered'],
            reason: 'the entered callback should be invoked when inserted into '
            'a document with a view as part of Shadow DOM');

      div.remove();
      customElementsTakeRecords();

      expect(invocations, ['created', 'entered', 'left'],
          reason: 'the left callback should be invoked when removed from a '
          'document with a view as part of Shadow DOM');
    });
  });


  group('disconnected_subtree', () {
    var div = new DivElement();

    setUp(() {
      invocations = [];
    });

    test('Enters a disconnected subtree of DOM', () {
      div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
      Platform.upgradeCustomElements(div);

      expect(invocations, ['created'],
          reason: 'the entered callback should not be invoked when inserted '
          'into a disconnected subtree');
    });

    test('Leaves a disconnected subtree of DOM', () {
      div.innerHtml = '';
      expect(invocations, [],
          reason: 'the left callback should not be invoked when removed from a '
          'disconnected subtree');
    });

    test('Enters a document with a view as a constituent of a subtree', () {
      div.setInnerHtml('<x-a></x-a>', treeSanitizer: nullSanitizer);
      Platform.upgradeCustomElements(div);
      invocations = [];
      document.body.append(div);
      customElementsTakeRecords();
      expect(invocations, ['entered'],
          reason: 'the entered callback should be invoked when inserted into a '
          'document with a view as part of a subtree');
    });
  });
}
