// Copyright (c) 2011, 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 DocumentFragmentTest;
import '../../pkg/unittest/lib/unittest.dart';
import '../../pkg/unittest/lib/html_config.dart';
import 'dart:html';
part 'util.dart';

main() {
  useHtmlConfiguration();

  var isAnchorElement =
      predicate((x) => x is AnchorElement, 'is an AnchorElement');

  Collection<String> _nodeStrings(Collection<Node> input) {
    var out = new List<String>();
    for (Node n in input) {
      if (n is Element) {
        Element e = n;
        out.add(e.tagName);
      } else {
        out.add(n.text);
      }
    }
    return out;
  };

  assertConstError(void fn()) {
    try {
      fn();
    } catch (e) {
      if (e is UnsupportedError) {
        return;
      }
    }
    expect(true, isFalse, reason: 'Expected immutability error');
  };

  void expectEmptyStyleDeclaration(CSSStyleDeclaration style) {
    expect(style.cssText, equals(''));
    expect(style.getPropertyPriority('color'), equals(''));
    expect(style.item(0), equals(''));
    expect(style.length, isZero);
    // TODO(jacobr): these checks throw UnimplementedErrors in dartium.
    // expect(style.parentRule, isNull);
    // expect(style.getPropertyCSSValue('color'), isNull);
    // expect(style.getPropertyShorthand('color'), isNull);
    // expect(style.isPropertyImplicit('color'), isFalse);

    // Ideally these would throw errors, but it's not possible to create a class
    // that'll intercept these calls without implementing the entire
    // CSSStyleDeclaration interface, so we'll settle for them being no-ops.
    style.cssText = '* {color: blue}';
    style.removeProperty('color');
    style.setProperty('color', 'blue');
  }

  group('constructors', () {
    test('0-argument makes an empty fragment', () {
      final fragment = new DocumentFragment();
      expect(fragment.children, equals([]));
    });

    test('.html parses input as HTML', () {
      final fragment = new DocumentFragment.html('<a>foo</a>');
      expect(fragment.children[0], isAnchorElement);
    });

    // test('.svg parses input as SVG', () {
    //   final fragment = new DocumentFragment.svg('<a>foo</a>');
    //   expect(fragment.children[0] is SVGAElement, isTrue);
    // });

    // TODO(nweiz): enable this once XML is ported.
    // test('.xml parses input as XML', () {
    //   final fragment = new DocumentFragment.xml('<a>foo</a>');
    //   expect(fragment.children[0] is XMLElement, isTrue);
    // });
  });

  test('Unsupported operations throw errors', () {
    var emptyFragment = new DocumentFragment();
    expectUnsupported(() => emptyFragment.attributes = {});
    expectUnsupported(() => emptyFragment.classes = []);
    expectUnsupported(() => emptyFragment.classes.add('foo'));
    expectUnsupported(() => emptyFragment.dataAttributes = {});
    expectUnsupported(() => emptyFragment.contentEditable = "true");
    expectUnsupported(() => emptyFragment.dir);
    expectUnsupported(() => emptyFragment.dir = "ltr");
    expectUnsupported(() => emptyFragment.draggable = true);
    expectUnsupported(() => emptyFragment.hidden = true);
    expectUnsupported(() => emptyFragment.id = "foo");
    expectUnsupported(() => emptyFragment.lang);
    expectUnsupported(() => emptyFragment.lang = "en");
    expectUnsupported(() => emptyFragment.scrollLeft = 10);
    expectUnsupported(() => emptyFragment.scrollTop = 10);
    expectUnsupported(() => emptyFragment.spellcheck = true);
    expectUnsupported(() => emptyFragment.translate = true);
    expectUnsupported(() => emptyFragment.tabIndex = 5);
    expectUnsupported(() => emptyFragment.title = "foo");
    expectUnsupported(() => emptyFragment.webkitdropzone = "foo");
    expectUnsupported(() => emptyFragment.webkitRegionOverflow = "foo");
  });

  group('children', () {
    var fragment;
    var children;

    init() {
      fragment = new DocumentFragment();
      children = fragment.children;
      fragment.nodes.addAll(
        [new Text("1"), new Element.tag("A"), new Element.tag("B"),
         new Text("2"), new Element.tag("I"), new Text("3"),
         new Element.tag("U")]);
    };

    test('is initially empty', () {
      children = new DocumentFragment().children;
      expect(children, equals([]));
      expect(children.isEmpty, isTrue);
    });

    test('filters out non-element nodes', () {
      init();
      expect(_nodeStrings(fragment.nodes),
          orderedEquals(["1", "A", "B", "2", "I", "3", "U"]));
      expect(_nodeStrings(children),
          orderedEquals(["A", "B", "I", "U"]));
    });

    test('only indexes children, not other nodes', () {
      init();
      children[1] = new Element.tag("BR");
      expect(_nodeStrings(fragment.nodes),
          orderedEquals(["1", "A", "BR", "2", "I", "3", "U"]));
      expect(_nodeStrings(children),
          orderedEquals(["A", "BR", "I", "U"]));
    });

    test('adds to both children and nodes', () {
      init();
      children.add(new Element.tag("UL"));
      expect(_nodeStrings(fragment.nodes),
          orderedEquals(["1", "A", "B", "2", "I", "3", "U", "UL"]));
      expect(_nodeStrings(children),
          orderedEquals(["A", "B", "I", "U", "UL"]));
    });

    test('removes only children, from both children and nodes', () {
      init();
      expect(children.removeLast().tagName, equals('U'));
      expect(_nodeStrings(fragment.nodes),
          orderedEquals(["1", "A", "B", "2", "I", "3"]));
      expect(_nodeStrings(children),
          orderedEquals(["A", "B", "I"]));

      expect(children.removeLast().tagName, "I");
      expect(_nodeStrings(fragment.nodes),
          equals(["1", "A", "B", "2", "3"]));
      expect(_nodeStrings(children), equals(["A", "B"]));
    });

    test('accessors are wrapped', () {
      init();
      expect(children[0].tagName, "A");
      expect(_nodeStrings(children.filter((e) => e.tagName == "I")), ["I"]);
      expect(children.every((e) => e is Element), isTrue);
      expect(children.some((e) => e.tagName == "U"), isTrue);
      expect(children.isEmpty, isFalse);
      expect(children.length, 4);
      expect(children[2].tagName, "I");
      expect(children.last.tagName, "U");
    });

    test('setting children overwrites nodes as well', () {
      init();
      fragment.children = [new Element.tag("DIV"), new Element.tag("HEAD")];
      expect(_nodeStrings(fragment.nodes), equals(["DIV", "HEAD"]));
    });
  });

  test('setting innerHTML works', () {
    var fragment = new DocumentFragment();
    fragment.nodes.add(new Text("foo"));
    fragment.innerHTML = "<a>bar</a>baz";
    expect(_nodeStrings(fragment.nodes), equals(["A", "baz"]));
  });

  test('getting innerHTML works', () {
    var fragment = new DocumentFragment();
    fragment.nodes.addAll([new Text("foo"), new Element.html("<A>bar</A>")]);
    expect(fragment.innerHTML, "foo<a>bar</a>");
    expect(fragment.outerHTML, "foo<a>bar</a>");
  });

  group('insertAdjacentElement', () {
    getFragment() => new DocumentFragment.html("<a>foo</a>");

    test('beforeBegin does nothing', () {
      var fragment = getFragment();
      expect(fragment.insertAdjacentElement("beforeBegin",
          new Element.tag("b")), isNull);
      expect(fragment.innerHTML, "<a>foo</a>");
    });

    test('afterEnd does nothing', () {
      var fragment = getFragment();
      expect(fragment.insertAdjacentElement("afterEnd",
          new Element.tag("b")), isNull);
      expect(fragment.innerHTML, "<a>foo</a>");
    });

    test('afterBegin inserts the element', () {
      var fragment = getFragment();
      var el = new Element.tag("b");
      expect(fragment.insertAdjacentElement("afterBegin", el), equals(el));
      expect(fragment.innerHTML, "<b></b><a>foo</a>");
    });

    test('beforeEnd inserts the element', () {
      var fragment = getFragment();
      var el = new Element.tag("b");
      expect(fragment.insertAdjacentElement("beforeEnd", el), equals(el));
      expect(fragment.innerHTML, "<a>foo</a><b></b>");
    });
  });

  group('insertAdjacentText', () {
    getFragment() => new DocumentFragment.html("<a>foo</a>");

    test('beforeBegin does nothing', () {
      var fragment = getFragment();
      fragment.insertAdjacentText("beforeBegin", "foo");
      expect(fragment.innerHTML, "<a>foo</a>");
    });

    test('afterEnd does nothing', () {
      var fragment = getFragment();
      fragment.insertAdjacentText("afterEnd", "foo");
      expect(fragment.innerHTML, "<a>foo</a>");
    });

    test('afterBegin inserts the text', () {
      var fragment = getFragment();
      fragment.insertAdjacentText("afterBegin", "foo");
      expect(fragment.innerHTML, "foo<a>foo</a>");
    });

    test('beforeEnd inserts the text', () {
      var fragment = getFragment();
      fragment.insertAdjacentText("beforeEnd", "foo");
      expect(fragment.innerHTML, "<a>foo</a>foo");
    });
  });

  group('insertAdjacentHTML', () {
    getFragment() => new DocumentFragment.html("<a>foo</a>");

    test('beforeBegin does nothing', () {
      var fragment = getFragment();
      fragment.insertAdjacentHTML("beforeBegin", "foo<br>");
      expect(fragment.innerHTML, "<a>foo</a>");
    });

    test('afterEnd does nothing', () {
      var fragment = getFragment();
      fragment.insertAdjacentHTML("afterEnd", "<br>foo");
      expect(fragment.innerHTML, "<a>foo</a>");
    });

    test('afterBegin inserts the HTML', () {
      var fragment = getFragment();
      fragment.insertAdjacentHTML("afterBegin", "foo<br>");
      expect(fragment.innerHTML, "foo<br><a>foo</a>");
    });

    test('beforeEnd inserts the HTML', () {
      var fragment = getFragment();
      fragment.insertAdjacentHTML("beforeEnd", "<br>foo");
      expect(fragment.innerHTML, "<a>foo</a><br>foo");
    });
  });

  // Just test that these methods don't throw errors
  test("no-op methods don't throw errors", () {
    var fragment = new DocumentFragment();
    fragment.on.click.add((e) => null);
    fragment.blur();
    fragment.focus();
    fragment.click();
    fragment.scrollByLines(2);
    fragment.scrollByPages(2);
    fragment.scrollIntoView();
    fragment.webkitRequestFullScreen(2);
  });

  test('default values', () {
    var fragment = new DocumentFragment();
    expect(fragment.contentEditable, "false");
    expect(fragment.tabIndex, -1);
    expect(fragment.id, "");
    expect(fragment.title, "");
    expect(fragment.tagName, "");
    expect(fragment.webkitdropzone, "");
    expect(fragment.webkitRegionOverflow, "");
    expect(fragment.isContentEditable, isFalse);
    expect(fragment.draggable, isFalse);
    expect(fragment.hidden, isFalse);
    expect(fragment.spellcheck, isFalse);
    expect(fragment.translate, isFalse);
    expect(fragment.nextElementSibling, isNull);
    expect(fragment.previousElementSibling, isNull);
    expect(fragment.offsetParent, isNull);
    expect(fragment.parent, isNull);
    expect(fragment.attributes.isEmpty, isTrue);
    expect(fragment.classes.isEmpty, isTrue);
    expect(fragment.dataAttributes.isEmpty, isTrue);
    expect(fragment.matchesSelector("foo"), isFalse);
    expect(fragment.matchesSelector("*"), isFalse);
  });

  test('style', () {
    var fragment = new DocumentFragment();
    var style = fragment.style;
    expectEmptyStyleDeclaration(style);
    fragment.computedStyle.then(expectAsync1((computedStyle) {
      expectEmptyStyleDeclaration(computedStyle);
    }));
  });

  // TODO(nweiz): re-enable when const is better supported in dartc and/or frog
  // test('const fields are immutable', () {
  //   var fragment = new DocumentFragment();
  //   assertConstError(() => fragment.attributes['title'] = 'foo');
  //   assertConstError(() => fragment.dataAttributes['title'] = 'foo');
  //   fragment.rect.then((ElementRect rect) {
  //     assertConstError(() => rect.clientRects.add(null));
  //     callbackDone();
  //   });
  //   // Issue 174: #classes is currently not const
  //   // assertConstError(() => fragment.classes.add('foo'));
  // });

  test('query searches the fragment', () {
    var fragment = new DocumentFragment.html(
      "<div class='foo'><a>foo</a><b>bar</b></div>");
    expect(fragment.query(".foo a").tagName, "A");
    expect(_nodeStrings(fragment.queryAll(".foo *")), equals(["A", "B"]));
  });
}
