// 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.

// WARNING: Do not edit - generated code.

part of $LIBRARYNAME;

$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
$!MEMBERS

$if DART2JS
  @DomName('Document.body')
  BodyElement body;
$else
  @DomName('Document.body')
  BodyElement get body => _body;

  @DomName('Document.body')
  set body(BodyElement value) {
    _body = value;
  }
$endif

  @DomName('Document.caretRangeFromPoint')
  Range caretRangeFromPoint(int x, int y) {
    return _caretRangeFromPoint(x, y);
  }

  @DomName('Document.elementFromPoint')
  Element elementFromPoint(int x, int y) {
    return _elementFromPoint(x, y);
  }

  /**
   * Checks if the getCssCanvasContext API is supported on the current platform.
   *
   * See also:
   *
   * * [getCssCanvasContext]
   */
$if DART2JS
  static bool get supportsCssCanvasContext =>
      JS('bool', '!!(document.getCSSCanvasContext)');
$else
  static bool get supportsCssCanvasContext => true;
$endif


  /**
   * Gets a CanvasRenderingContext which can be used as the CSS background of an
   * element.
   *
   * CSS:
   *
   *     background: -webkit-canvas(backgroundCanvas)
   *
   * Generate the canvas:
   *
   *     var context = document.getCssCanvasContext('2d', 'backgroundCanvas',
   *         100, 100);
   *     context.fillStyle = 'red';
   *     context.fillRect(0, 0, 100, 100);
   *
   * See also:
   *
   * * [supportsCssCanvasContext]
   * * [CanvasElement.getContext]
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @DomName('Document.getCSSCanvasContext')
  CanvasRenderingContext getCssCanvasContext(String contextId, String name,
      int width, int height) {
    return _getCssCanvasContext(contextId, name, width, height);
  }

  @DomName('Document.head')
  HeadElement get head => _head;

  @DomName('Document.lastModified')
  String get lastModified => _lastModified;

  @DomName('Document.preferredStylesheetSet')
  String get preferredStylesheetSet => _preferredStylesheetSet;

  @DomName('Document.referrer')
  String get referrer => _referrer;

  @DomName('Document.selectedStylesheetSet')
  String get selectedStylesheetSet => _selectedStylesheetSet;
  set selectedStylesheetSet(String value) {
    _selectedStylesheetSet = value;
  }

  @DomName('Document.styleSheets')
  List<StyleSheet> get styleSheets => _styleSheets;

  @DomName('Document.title')
  String get title => _title;

  @DomName('Document.title')
  set title(String value) {
    _title = value;
  }

  /**
   * Returns page to standard layout.
   *
   * Has no effect if the page is not in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
   * WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitExitFullscreen')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  void exitFullscreen() {
    _webkitExitFullscreen();
  }

  /**
   * Returns the element, if any, that is currently displayed in fullscreen.
   *
   * Returns null if there is currently no fullscreen element. You can use
   * this to determine if the page is in fullscreen mode.
   *
   *     myVideo = new VideoElement();
   *     if (document.fullscreenElement == null) {
   *       myVideo.requestFullscreen();
   *       print(document.fullscreenElement == myVideo); // true
   *     }
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
   * WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitFullscreenElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Element get fullscreenElement => _webkitFullscreenElement;

  /**
   * Returns true if this document can display elements in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen API]
   * (http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api) from
   * WebPlatform.org.
   * * [Fullscreen specification]
   * (http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitFullscreenEnabled')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  bool get fullscreenEnabled => _webkitFullscreenEnabled;

  @DomName('Document.webkitHidden')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  bool get hidden => _webkitHidden;

  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
$if DART2JS
  String get visibilityState => JS('String',
    '(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
      '#.webkitVisibilityState)', this, this, this, this);
$else
  String get visibilityState => _webkitVisibilityState;
$endif
$if DARTIUM

  /**
   * Internal routine to find the DOM JS class name being extended for custom
   * elements.
   */
  String _getJSClassName(ClassMirror classMirror) {
    var jsClassName = null;
    var isElement = false;

    while (classMirror.superclass != null) {
      var fullName = classMirror.superclass.qualifiedName;
      isElement = isElement ||
          (fullName == #dart.dom.html.Element || fullName == #dart.dom.svg.Element);

      var domLibrary = MirrorSystem.getName(fullName).startsWith('dart.dom.');
      if (jsClassName == null && domLibrary) {
        // Lookup JS class name (if not found).
        var metadatas = classMirror.metadata;
        for (var metadata in metadatas) {
          var metaDataMirror = metadata.reflectee;
          var metaType = reflectClass(metaDataMirror.runtimeType);
          if (MirrorSystem.getName(metaType.simpleName) == 'DomName' &&
              (metaDataMirror.name.startsWith('HTML') || metaDataMirror.name.startsWith('SVG'))) {
            jsClassName = metadata.reflectee.name;
          }
        }
      }

      classMirror = classMirror.superclass;
    }

    // If we're an element then everything is okay.
    return isElement ? jsClassName : null;
  }

  // Get the first class that's a super of a dart.dom library.
  ClassMirror _getDartHtmlClassName(ClassMirror classMirror) {
    while (classMirror.superclass != null) {
      var fullName = classMirror.superclass.qualifiedName;
      var domLibrary = MirrorSystem.getName(fullName).startsWith('dart.dom.');
      if (domLibrary) {
        return classMirror.superclass;
      }

      classMirror = classMirror.superclass;
    }

    return null;
  }

  /**
   * Get the class that immediately derived from a class in dart:html or
   * dart:svg (has an attribute DomName of either HTML* or SVG*).
   */
  ClassMirror _getDomSuperClass(ClassMirror classMirror) {
    var isElement = false;
    var foundSuperElement = null;

    while (classMirror.superclass != null) {
      var fullName = classMirror.superclass.qualifiedName;
      isElement = isElement || (fullName == #dart.dom.html.Element || fullName == #dart.dom.svg.Element);

      var domLibrary = MirrorSystem.getName(fullName).startsWith('dart.dom.');
      if (domLibrary) {
        if (foundSuperElement == null) {
          foundSuperElement = classMirror.superclass;
        }
        // Lookup JS class (if not found).
        var metadatas = classMirror.metadata;
        for (var metadata in metadatas) {
          var metaDataMirror = metadata.reflectee;
          var metaType = reflectClass(metaDataMirror.runtimeType);
          if (MirrorSystem.getName(metaType.simpleName) == 'DomName' &&
              (metaDataMirror.name.startsWith('HTML') || metaDataMirror.name.startsWith('SVG'))) {
            if (isElement) return foundSuperElement;
          }
        }
      }

      classMirror = classMirror.superclass;
    }

    return null;
  }

  /**
   * Does this CustomElement class have:
   *
   *   - a created constructor with no arguments?
   *   - a created constructor with a super.created() initializer?
   *
   * e.g.,    MyCustomClass.created() : super.created();
   */
  bool _hasCreatedConstructor(ClassMirror classToRegister) {
    var htmlClassMirror = _getDomSuperClass(classToRegister);

    var classMirror = classToRegister;
    while (classMirror != null && classMirror != htmlClassMirror) {
      var createdParametersValid = false;
      var superCreatedCalled = false;
      var className = MirrorSystem.getName(classMirror.simpleName);
      var methodMirror = classMirror.declarations[new Symbol("$className.created")];
      if (methodMirror != null && methodMirror.isConstructor) {
        createdParametersValid = true;                // Assume no parameters.
        if (methodMirror.parameters.length != 0) {
          // If any parameters each one must be optional.
          methodMirror.parameters.forEach((parameter) {
            createdParametersValid = createdParametersValid && parameter.isOptional;
          });
        }

        // Get the created constructor source and look at the initializer;
        // Must call super.created() if not its as an error.
        var createdSource = methodMirror.source;
        superCreatedCalled = createdSource.contains("super.created(");
      }

      if (!superCreatedCalled) {
        throw new DomException.jsInterop('created constructor initializer must call super.created()');
      } else if (!createdParametersValid) {
        throw new DomException.jsInterop('created constructor must have no parameters');
      }

      classMirror = classMirror.superclass;
      while (classMirror != classMirror.mixin) {
        // Skip the mixins.
        classMirror = classMirror.superclass;
      }
    }

    return true;
  }
$endif

  @Experimental()
  /**
   * Register a custom subclass of Element to be instantiatable by the DOM.
   *
   * This is necessary to allow the construction of any custom elements.
   *
   * The class being registered must either subclass HtmlElement or SvgElement.
   * If they subclass these directly then they can be used as:
   *
   *     class FooElement extends HtmlElement{
   *        void created() {
   *          print('FooElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-foo', FooElement);
   *       var myFoo = new Element.tag('x-foo');
   *       // prints 'FooElement created!' to the console.
   *     }
   *
   * The custom element can also be instantiated via HTML using the syntax
   * `<x-foo></x-foo>`
   *
   * Other elements can be subclassed as well:
   *
   *     class BarElement extends InputElement{
   *        void created() {
   *          print('BarElement created!');
   *        }
   *     }
   *
   *     main() {
   *       document.registerElement('x-bar', BarElement);
   *       var myBar = new Element.tag('input', 'x-bar');
   *       // prints 'BarElement created!' to the console.
   *     }
   *
   * This custom element can also be instantiated via HTML using the syntax
   * `<input is="x-bar"></input>`
   *
   */
  void registerElement(String tag, Type customElementClass,
      {String extendsTag}) {
$if DART2JS
    _registerCustomElement(JS('', 'window'), this, tag, customElementClass,
        extendsTag);
$else
    // Figure out which DOM class is being extended from the user's Dart class.
    var classMirror = reflectClass(customElementClass);

    var locationUri = classMirror.location.sourceUri.toString();
    if (locationUri == 'dart:html' || locationUri == 'dart:svg') {
      throw new DomException.jsInterop("HierarchyRequestError: Cannot register an existing dart:html or dart:svg type.");
    }

    if (classMirror.isAbstract) {
      throw new DomException.jsInterop("HierarchyRequestError: Cannot register an abstract class.");
    }

    var jsClassName = _getJSClassName(classMirror);
    if (jsClassName == null) {
      // Only components derived from HTML* can be extended.
      throw new DomException.jsInterop("HierarchyRequestError: Only HTML elements can be customized.");
    }

    var customClassType = _getDartHtmlClassName(classMirror);

    if (extendsTag != null) {
      var nativeElement = document.createElement(extendsTag);

      // Trying to extend a native element is it the Dart class consistent with the
      // extendsTag?
      if (nativeElement.runtimeType != customClassType.reflectedType) {
        var nativeElementClassMirror = reflectClass(nativeElement.runtimeType);
        var customClassNativeElement = MirrorSystem.getName(customClassType.simpleName);
        var extendsNativeElement = MirrorSystem.getName(nativeElementClassMirror.simpleName);
        throw new DomException.jsInterop("HierarchyRequestError: Custom class type ($customClassNativeElement) and extendsTag class ($extendsNativeElement) don't match .");
      }
    } else if (customClassType.reflectedType != HtmlElement && customClassType.reflectedType != svg.SvgElement) {
      var customClassName = MirrorSystem.getName(classMirror.simpleName);
      var customClassElement = MirrorSystem.getName(customClassType.simpleName);
      throw new DomException.jsInterop("HierarchyRequestError: Custom element $customClassName is a native $customClassElement should be derived from HtmlElement or SvgElement.");
    }

    if (_hasCreatedConstructor(classMirror)) {
      // Start the hookup the JS way create an <x-foo> element that extends the
      // <x-base> custom element. Inherit its prototype and signal what tag is
      // inherited:
      //
      //     var myProto = Object.create(HTMLElement.prototype);
      //     var myElement = document.registerElement('x-foo', {prototype: myProto});
      var baseElement = js.JsNative.getProperty(js.context, jsClassName);
      if (baseElement == null) {
        // Couldn't find the HTML element so use a generic one.
        baseElement = js.JsNative.getProperty(js.context, 'HTMLElement');
      }
      var elemProto = js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'Object'), "create", [js.JsNative.getProperty(baseElement, 'prototype')]);

      // Remember for any upgrading done in wrap_jso.
      addCustomElementType(tag, customElementClass, extendsTag);

      // TODO(terry): Hack to stop recursion re-creating custom element when the
      //              created() constructor of the custom element does e.g.,
      //
      //                  MyElement.created() : super.created() {
      //                    this.innerHtml = "<b>I'm an x-foo-with-markup!</b>";
      //                  }
      //
      //              sanitizing causes custom element to created recursively
      //              until stack overflow.
      //
      //              See https://github.com/dart-lang/sdk/issues/23666
      int creating = 0;

      // If any JS code is hooked we want to call it too.
      var oldCreatedCallback = elemProto['createdCallback'];
      var oldAttributeChangedCallback = elemProto['attributeChangedCallback'];
      var oldAttachedCallback = elemProto['attachedCallback'];
      var oldDetachedCallback = elemProto['detachedCallback'];

      // TODO(jacobr): warning:
      elemProto['createdCallback'] = js.JsNative.withThis(($this) {
        if (_getJSClassName(reflectClass(customElementClass).superclass) != null && creating < 2) {
          creating++;

          var dartClass;
          try {
            if (extendsTag != null) {
              // If we're extending a native element then create that element.
              // Then upgrade that element to the customElementClass through
              // normal flow.
              dartClass = document.createElement(extendsTag);
              js.setDartHtmlWrapperFor($this, dartClass);
              dartClass.blink_jsObject = $this;
            }

            // Upgrade to the CustomElement Dart class.
            dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
          } catch (e) {
            // Got a problem make it an HtmlElement and rethrow the error.
            dartClass = HtmlElement.internalCreateHtmlElement();
            // We need to remember the JS object (because constructElement failed
            // it normally sets up the blink_jsObject.
            dartClass.blink_jsObject = $this;

            // Mark to only try this once don't try upgrading from HtmlElement
            // to the user's Dart class - we had a problem.
            dartClass._badUpgrade();
            throw e;
          } finally {
            // Need to remember the Dart class that was created for this custom so
            // return it and setup the blink_jsObject to the $this that we'll be working
            // with as we talk to blink.
            js.setDartHtmlWrapperFor($this, dartClass);

            creating--;
          }
        }

        if (oldCreatedCallback != null)
          oldCreatedCallback.apply([], thisArg: unwrap_jso($this));
      });
      elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, attrName, oldVal, newVal) {
        $this.attributeChanged(attrName, oldVal, newVal);

        if (oldAttributeChangedCallback != null)
          oldAttributeChangedCallback.apply([], thisArg: unwrap_jso($this));
      });
      elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) {
        $this.attached();

        if (oldAttachedCallback != null)
          oldAttachedCallback.apply([], thisArg: unwrap_jso($this));
      });
      elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) {
        $this.detached();

        if (oldDetachedCallback != null)
          oldDetachedCallback.apply([], thisArg: unwrap_jso($this));
      });
      // document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
      var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
      js.JsNative.callMethod(js.JsNative.getProperty(js.context, 'document'), 'registerElement', [tag, jsMap]);
    }
$endif
  }

  /** *Deprecated*: use [registerElement] instead. */
  @deprecated
  @Experimental()
  void register(String tag, Type customElementClass, {String extendsTag}) {
    return registerElement(tag, customElementClass, extendsTag: extendsTag);
  }

  /**
   * Static factory designed to expose `visibilitychange` events to event
   * handlers that are not necessarily instances of [Document].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Document.visibilityChange')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  static const EventStreamProvider<Event> visibilityChangeEvent =
      const _CustomEventStreamProvider<Event>(
        _determineVisibilityChangeEventType);

  static String _determineVisibilityChangeEventType(EventTarget e) {
$if DART2JS
    if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
      // Opera 12.10 and Firefox 18 and later support
      return 'visibilitychange';
    } else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
      return 'mozvisibilitychange';
    } else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
      return 'msvisibilitychange';
    } else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
      return 'webkitvisibilitychange';
    }
    return 'visibilitychange';
$else
    return 'webkitvisibilitychange';
$endif
  }

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  Stream<Event> get onVisibilityChange =>
      visibilityChangeEvent.forTarget(this);

  /// Creates an element upgrader which can be used to change the Dart wrapper
  /// type for elements.
  ///
  /// The type specified must be a subclass of HtmlElement, when an element is
  /// upgraded then the created constructor will be invoked on that element.
  ///
  /// If the type is not a direct subclass of HtmlElement then the extendsTag
  /// parameter must be provided.
  @Experimental()
  ElementUpgrader createElementUpgrader(Type type, {String extendsTag}) {
$if DART2JS
    return new _JSElementUpgrader(this, type, extendsTag);
$else
    return new _VMElementUpgrader(this, type, extendsTag);
$endif
  }
}
