// Copyright (c) 2012, 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.

part of $LIBRARYNAME;

@DocsEditable()
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME extends Node
{

$!MEMBERS
  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<Element> querySelectorAll(String selectors) {
    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
  }

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelector')
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelectorAll')
  ElementList<Element> queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
$if DART2JS
    return JS('bool', '("registerElement" in #)', this);
$else
    return true;
$endif
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
$if DART2JS
    if (typeExtension == null) {
      return _createElement_2(tagName);
    } else {
      return _createElement(tagName, typeExtension);
    }
$else
    var newElement = (typeExtension == null) ?
      _blink.BlinkDocument.instance.createElement_Callback_1_(unwrap_jso(this), tagName) :
      _blink.BlinkDocument.instance.createElement_Callback_2_(unwrap_jso(this), tagName, typeExtension);

    var wrapped;

    if (newElement['dart_class'] != null) {
      wrapped = newElement['dart_class'];         // Here's our Dart class.
      wrapped.blink_jsObject = newElement;
    } else {
      wrapped = wrap_jso(newElement);
      if (wrapped == null) {
        wrapped = wrap_jso_custom_element(newElement);
      }
    }

    return wrapped;
$endif
  }

$if DART2JS
  // The two-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  @DomName('Document.createElement')
  _createElement_2(String tagName) => JS('', '#.createElement(#)', this, tagName);

  // The three-argument version of this is automatically generated, but we need to
  // omit the typeExtension if it's null on Firefox or we get an is="null" attribute.
  @DomName('Document.createElementNS')
  _createElementNS_2(String namespaceURI, String qualifiedName) =>
      JS('', '#.createElementNS(#, #)', this, namespaceURI, qualifiedName);

$endif
  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
$if DART2JS
    if (typeExtension == null) {
      return _createElementNS_2(namespaceURI, qualifiedName);
    } else {
      return _createElementNS(namespaceURI, qualifiedName, typeExtension);
    }
$else
    var newElement = (typeExtension == null) ?
      _blink.BlinkDocument.instance.createElementNS_Callback_2_(unwrap_jso(this), namespaceURI, qualifiedName) :
      _blink.BlinkDocument.instance.createElementNS_Callback_3_(unwrap_jso(this), namespaceURI, qualifiedName, typeExtension);

    var wrapped;

    if (newElement['dart_class'] != null) {
      wrapped = newElement['dart_class'];         // Here's our Dart class.
      wrapped.blink_jsObject = newElement;
    } else {
      wrapped = wrap_jso(newElement);
      if (wrapped == null) {
        wrapped = wrap_jso_custom_element(newElement);
      }
    }

    return wrapped;
$endif
  }

$if DART2JS
  @DomName('Document.createNodeIterator')
  NodeIterator _createNodeIterator(Node root,
      [int whatToShow, NodeFilter filter])
      => JS('NodeIterator', '#.createNodeIterator(#, #, #, false)',
          this, root, whatToShow, filter);

  @DomName('Document.createTreeWalker')
  TreeWalker _createTreeWalker(Node root,
      [int whatToShow, NodeFilter filter])
      => JS('TreeWalker', '#.createTreeWalker(#, #, #, false)',
          this, root, whatToShow, filter);
$endif
}
